diff -Nru django-guardian-1.3.2/AUTHORS django-guardian-1.4.1/AUTHORS --- django-guardian-1.3.2/AUTHORS 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/AUTHORS 2015-12-18 05:08:22.000000000 +0000 @@ -54,3 +54,4 @@ - Verena Jaspersen - Bertrand Svetchine - Frank Wickström +- George Karakostas diff -Nru django-guardian-1.3.2/benchmarks/models.py django-guardian-1.4.1/benchmarks/models.py --- django-guardian-1.3.2/benchmarks/models.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/benchmarks/models.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -from django.db import models -from guardian.models import UserObjectPermissionBase -from guardian.models import GroupObjectPermissionBase - - -class TestModel(models.Model): - name = models.CharField(max_length=128) - - - -class DirectUser(UserObjectPermissionBase): - content_object = models.ForeignKey('TestDirectModel') - - -class DirectGroup(GroupObjectPermissionBase): - content_object = models.ForeignKey('TestDirectModel') - - -class TestDirectModel(models.Model): - name = models.CharField(max_length=128) - diff -Nru django-guardian-1.3.2/benchmarks/run_benchmarks.py django-guardian-1.4.1/benchmarks/run_benchmarks.py --- django-guardian-1.3.2/benchmarks/run_benchmarks.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/benchmarks/run_benchmarks.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -#!/usr/bin/env python -""" -This benchmark package should be treated as work-in-progress, not a production -ready benchmarking solution for django-guardian. -""" -import datetime -import os -import random -import string -import sys - -abspath = lambda *p: os.path.abspath(os.path.join(*p)) - -THIS_DIR = abspath(os.path.dirname(__file__)) -ROOT_DIR = abspath(THIS_DIR, '..') - -# so the preferred guardian module is one within this repo and -# not system-wide -sys.path.insert(0, ROOT_DIR) - -os.environ["DJANGO_SETTINGS_MODULE"] = 'benchmarks.settings' -from benchmarks import settings -from guardian.shortcuts import assign_perm - -settings.DJALOG_LEVEL = 40 -settings.INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.sessions', - 'django.contrib.contenttypes', - 'django.contrib.admin', - 'django.contrib.sites', - 'guardian', - 'benchmarks', -) - -from utils import show_settings -import django -from django.contrib.auth.models import User, Group -from django.utils.termcolors import colorize -from benchmarks.models import TestModel -from benchmarks.models import TestDirectModel - -USERS_COUNT = 50 -OBJECTS_COUNT = 1000 -OBJECTS_WIHT_PERMS_COUNT = 1000 - -def random_string(length=25, chars=string.ascii_letters+string.digits): - return ''.join(random.choice(chars) for i in range(length)) - - -def get_model_name(model): - """ - Returns the name of the model - """ - # model._meta.module_name is deprecated in django version 1.7 and removed in django version 1.8. - # It is replaced by model._meta.model_name - if django.VERSION < (1, 7): - return model._meta.module_name - return model._meta.model_name - - -class Call(object): - def __init__(self, args, kwargs, start=None, finish=None): - self.args = args - self.kwargs = kwargs - self.start = start - self.finish = finish - - def delta(self): - return self.finish - self.start - - -class Timed(object): - - def __init__(self, action=None): - self.action = action - - def __call__(self, func): - - if not hasattr(func, 'calls'): - func.calls = [] - - def wrapper(*args, **kwargs): - if self.action: - print(" -> [%s]" % self.action) - start = datetime.datetime.now() - call = Call(list(args), dict(kwargs), start) - try: - return func(*args, **kwargs) - finally: - call.finish = datetime.datetime.now() - func.calls.append(call) - if self.action: - print(" -> [%s] Done (Total time: %s)" % (self.action, - call.delta())) - return wrapper - - -class Benchmark(object): - - def __init__(self, name, users_count, objects_count, - objects_with_perms_count, model): - self.name = name - self.users_count = users_count - self.objects_count = objects_count - self.objects_with_perms_count = objects_with_perms_count - - self.Model = model - self.perm = 'auth.change_%s' % get_model_name(model) - - def info(self, msg): - print(colorize(msg + '\n', fg='green')) - - def prepare_db(self): - from django.core.management import call_command - call_command('syncdb', interactive=False) - - for model in [User, Group, self.Model]: - model.objects.all().delete() - - @Timed("Creating users") - def create_users(self): - User.objects.bulk_create(User(id=x, username=random_string().capitalize()) - for x in range(self.users_count)) - - @Timed("Creating objects") - def create_objects(self): - Model = self.Model - Model.objects.bulk_create(Model(id=x, name=random_string(20)) - for x in range(self.objects_count)) - - @Timed("Grant permissions") - def grant_perms(self): - ids = range(1, self.objects_count) - for user in User.objects.iterator(): - for x in xrange(self.objects_with_perms_count): - obj = self.Model.objects.get(id=random.choice(ids)) - self.grant_perm(user, obj, self.perm) - - def grant_perm(self, user, obj, perm): - assign_perm(perm, user, obj) - - @Timed("Check permissions") - def check_perms(self): - ids = range(1, self.objects_count) - for user in User.objects.iterator(): - for x in xrange(self.objects_with_perms_count): - obj = self.Model.objects.get(id=random.choice(ids)) - self.check_perm(user, obj, self.perm) - - def check_perm(self, user, obj, perm): - user.has_perm(perm, obj) - - @Timed("Benchmark") - def main(self): - self.info('=' * 80) - self.info(self.name.center(80)) - self.info('=' * 80) - self.prepare_db() - self.create_users() - self.create_objects() - self.grant_perms() - self.check_perms() - - -def main(): - show_settings(settings, 'benchmarks') - benchmark = Benchmark('Direct relations benchmark', - USERS_COUNT, OBJECTS_COUNT, OBJECTS_WIHT_PERMS_COUNT, TestDirectModel) - benchmark.main() - - benchmark = Benchmark('Generic relations benchmark', - USERS_COUNT, OBJECTS_COUNT, OBJECTS_WIHT_PERMS_COUNT, TestModel) - benchmark.main() - -if __name__ == '__main__': - main() - - - diff -Nru django-guardian-1.3.2/benchmarks/settings.py django-guardian-1.4.1/benchmarks/settings.py --- django-guardian-1.3.2/benchmarks/settings.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/benchmarks/settings.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -import os -import sys - -abspath = lambda *p: os.path.abspath(os.path.join(*p)) - -THIS_DIR = abspath(os.path.dirname(__file__)) -ROOT_DIR = abspath(THIS_DIR, '..') - -# so the preferred guardian module is one within this repo and -# not system-wide -sys.path.insert(0, ROOT_DIR) - - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.sessions', - 'django.contrib.contenttypes', - 'django.contrib.admin', - 'django.contrib.sites', - 'guardian', - 'benchmarks', -) - - -ANONYMOUS_USER_ID = -1 - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'guardian_benchmarks', - 'USER': 'guardian_bench', - 'PASSWORD': 'guardian_bench', - }, -} - diff -Nru django-guardian-1.3.2/CHANGES django-guardian-1.4.1/CHANGES --- django-guardian-1.3.2/CHANGES 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/CHANGES 2016-01-09 22:41:23.000000000 +0000 @@ -1,3 +1,29 @@ +Release 1.4.1 (Jan 10, 2016) +=========================== + +* Fix broken documentation. +* Fix setup.py errors (#387). +* Fix tox tests. +* Fix travis tests. + + +Release 1.4.0 (Jan 8, 2016) +=========================== + +* Drop support for Django < 1.7 +* Drop support for django south migrations. +* Remove depreciated code. +* Fix many Django depreciated warnings. +* Fix tests and example_project. +* Work around for postgresql specific Django bug (#366). This is a regression + that was introduced in version 1.3.2. +* Updates to documentation. +* Require can_change permission to change object perms in admin. +* Fixes broke admin URLS (#376 and #381). +* Tests now work with Mysql and Postgresql as well as sqlite. +* Uses django-environ for tests. + + Release 1.3.2 (Nov 14, 2015) ============================ diff -Nru django-guardian-1.3.2/debian/changelog django-guardian-1.4.1/debian/changelog --- django-guardian-1.3.2/debian/changelog 2015-11-14 03:31:26.000000000 +0000 +++ django-guardian-1.4.1/debian/changelog 2016-01-13 09:47:50.000000000 +0000 @@ -1,3 +1,9 @@ +django-guardian (1.4.1-1) unstable; urgency=medium + + * New upstream version. + + -- Brian May Wed, 13 Jan 2016 20:47:45 +1100 + django-guardian (1.3.2-1) unstable; urgency=medium * New upstream version. diff -Nru django-guardian-1.3.2/debian/control django-guardian-1.4.1/debian/control --- django-guardian-1.3.2/debian/control 2015-11-14 03:22:38.000000000 +0000 +++ django-guardian-1.4.1/debian/control 2016-01-13 09:39:17.000000000 +0000 @@ -5,9 +5,9 @@ Uploaders: Brian May Build-Depends: debhelper (>= 8.0.0), dh-python, python-all, python-setuptools, python-django (>= 1.2), - python-mock (>= 0.7.2), python-six, python-unittest2, + python-mock (>= 0.7.2), python-six, python-unittest2, python-django-environ, python3-all, python3-setuptools, python3-django (>= 1.2), - python3-mock (>= 0.7.2), python3-six, + python3-mock (>= 0.7.2), python3-six, python3-django-environ, python3-sphinx, Standards-Version: 3.9.6 X-Python-Version: >= 2.7 diff -Nru django-guardian-1.3.2/debian/.git-dpm django-guardian-1.4.1/debian/.git-dpm --- django-guardian-1.3.2/debian/.git-dpm 2015-11-14 03:22:39.000000000 +0000 +++ django-guardian-1.4.1/debian/.git-dpm 2016-01-13 09:00:46.000000000 +0000 @@ -1,11 +1,11 @@ # see git-dpm(1) from git-dpm package -7361b9c49e539c5959df0b28542733ab9f733c1c -7361b9c49e539c5959df0b28542733ab9f733c1c -5f8470ff0f7419b67905b358555e1777f072f409 -5f8470ff0f7419b67905b358555e1777f072f409 -django-guardian_1.3.2.orig.tar.gz -d352603d13f24b978081dad9de712e0b9e3c4401 -352416 +ebf68b4e9b9f47dc91ea5541e0622f48280bbec2 +ebf68b4e9b9f47dc91ea5541e0622f48280bbec2 +d55dae3e5943c10edd42341baa123543c0f857b2 +d55dae3e5943c10edd42341baa123543c0f857b2 +django-guardian_1.4.1.orig.tar.gz +04497e41c16d3dd68a8b173e6783645e77a1421c +295830 debianTag="debian/%e%v" patchedTag="patched/%e%v" upstreamTag="upstream/%e%u" diff -Nru django-guardian-1.3.2/debian/patches/0001-Append-uncompressed-JavaScript-libraries.patch django-guardian-1.4.1/debian/patches/0001-Append-uncompressed-JavaScript-libraries.patch --- django-guardian-1.3.2/debian/patches/0001-Append-uncompressed-JavaScript-libraries.patch 2015-11-14 03:22:38.000000000 +0000 +++ django-guardian-1.4.1/debian/patches/0001-Append-uncompressed-JavaScript-libraries.patch 2016-01-13 09:00:46.000000000 +0000 @@ -1,4 +1,4 @@ -From 9035fb4fd835b59ffb32a1e414ab3efbad084dbc Mon Sep 17 00:00:00 2001 +From 02193976ef199f066a32f74f484ef53abeeebf50 Mon Sep 17 00:00:00 2001 From: "Twitter, Inc" Date: Tue, 3 Nov 2015 19:47:23 +1100 Subject: Append uncompressed JavaScript libraries diff -Nru django-guardian-1.3.2/debian/patches/0002-Remove-nonlocal-image-for-Travis-ci.patch django-guardian-1.4.1/debian/patches/0002-Remove-nonlocal-image-for-Travis-ci.patch --- django-guardian-1.3.2/debian/patches/0002-Remove-nonlocal-image-for-Travis-ci.patch 2015-11-14 03:22:38.000000000 +0000 +++ django-guardian-1.4.1/debian/patches/0002-Remove-nonlocal-image-for-Travis-ci.patch 2016-01-13 09:00:46.000000000 +0000 @@ -1,4 +1,4 @@ -From 996cf54251e656f895e80819a2634d8a8f394a06 Mon Sep 17 00:00:00 2001 +From 878580ae165b217bfd4d0e7cfb8c0179083f2590 Mon Sep 17 00:00:00 2001 From: Kouhei Maeda Date: Tue, 3 Nov 2015 19:47:24 +1100 Subject: Remove nonlocal image for Travis-ci. @@ -10,10 +10,10 @@ 2 files changed, 6 deletions(-) diff --git a/docs/develop/testing.rst b/docs/develop/testing.rst -index 8040442..04a5ab7 100644 +index 80e307f..05c4a0d 100644 --- a/docs/develop/testing.rst +++ b/docs/develop/testing.rst -@@ -102,9 +102,6 @@ Travis CI +@@ -105,9 +105,6 @@ Travis CI .. versionadded:: 1.0.4 diff -Nru django-guardian-1.3.2/debian/patches/0003-Use-local-js-files.patch django-guardian-1.4.1/debian/patches/0003-Use-local-js-files.patch --- django-guardian-1.3.2/debian/patches/0003-Use-local-js-files.patch 2015-11-14 03:22:39.000000000 +0000 +++ django-guardian-1.4.1/debian/patches/0003-Use-local-js-files.patch 2016-01-13 09:00:46.000000000 +0000 @@ -1,12 +1,11 @@ -From 7361b9c49e539c5959df0b28542733ab9f733c1c Mon Sep 17 00:00:00 2001 +From ebf68b4e9b9f47dc91ea5541e0622f48280bbec2 Mon Sep 17 00:00:00 2001 From: Brian May Date: Sat, 14 Nov 2015 14:02:06 +1100 Subject: Use local js files. --- - docs/theme/rtd_theme/layout.html | 2 +- - example_project/templates/base.html | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) + docs/theme/rtd_theme/layout.html | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/theme/rtd_theme/layout.html b/docs/theme/rtd_theme/layout.html index 87337a9..57ad31c 100644 @@ -21,16 +20,3 @@ -diff --git a/example_project/templates/base.html b/example_project/templates/base.html -index 9b774de..e3eda3a 100644 ---- a/example_project/templates/base.html -+++ b/example_project/templates/base.html -@@ -50,7 +50,7 @@ - - {% endblock %} - -- -+ - - - diff -Nru django-guardian-1.3.2/debian/python3-django-guardian.examples django-guardian-1.4.1/debian/python3-django-guardian.examples --- django-guardian-1.3.2/debian/python3-django-guardian.examples 2015-11-14 03:22:38.000000000 +0000 +++ django-guardian-1.4.1/debian/python3-django-guardian.examples 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -example_project/ -benchmarks/ diff -Nru django-guardian-1.3.2/debian/python-django-guardian.examples django-guardian-1.4.1/debian/python-django-guardian.examples --- django-guardian-1.3.2/debian/python-django-guardian.examples 2015-11-14 03:22:38.000000000 +0000 +++ django-guardian-1.4.1/debian/python-django-guardian.examples 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -example_project/ -benchmarks/ diff -Nru django-guardian-1.3.2/debian/rules django-guardian-1.4.1/debian/rules --- django-guardian-1.3.2/debian/rules 2015-11-14 03:22:38.000000000 +0000 +++ django-guardian-1.4.1/debian/rules 2016-01-13 09:39:17.000000000 +0000 @@ -19,9 +19,6 @@ override_dh_auto_install: dh_auto_install - - find $(CURDIR)/debian/ -type d -name benchmarks | xargs rm -rf - find $(CURDIR)/debian/ -type d -name example_project | xargs rm -rf override_dh_installchangelogs: dh_installchangelogs CHANGES diff -Nru django-guardian-1.3.2/debian/upstream/signing-key.asc django-guardian-1.4.1/debian/upstream/signing-key.asc --- django-guardian-1.3.2/debian/upstream/signing-key.asc 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/debian/upstream/signing-key.asc 2016-01-13 09:00:46.000000000 +0000 @@ -0,0 +1,94 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQINBEtNOzEBEADTKdgK4OUNFjS/VfLENN3IXe30AQuQ8drBYjtUMZn5KMfB/0Yp +R4VZVv0loSxPYLh2UpFumuQj3U3dbn5oTfLSPSYCYYYi1VTHOhj+LzNUuO8QEED2 +WNncCCIGjK3N8Z3M8opXgdTOaTuwR0OrLoZr5XZYNbWUoEPW7qbBhdrvnjKmhDgS +/Uwn7Xzbswl9bca9mdMhKGE2NBeeNhdYM8gB/jwgGktxPUCKBg8GB8C9XtxP2XaE +LqyVhjg7xhUS09Q7SKvaCXA0+ZG6f5keqM9v0fvXGVpBRe5Vxln01sN3li2Ox8BE +8IrO3AWBDC3Mmf1d9kPiIwGEICQaxhFKT3bL6lIyTUFQ+5DTn9uHrdfA7bB0s8Di +9jmyd7GAlS7K1uKHoYUjcQYZlgeqp/AgtUqngJCnlHGMXyOHHQI3a9oXB1Ic9JIt +kIOHO6sd+nDVDEat1TPYCvoqHwz56ZEgyJkmdSs9sFKXVdzAuUcYJQtFtuNcsvZQ +YFC/GZBCZBv96lJOa60qBgYi35rdNf27rZGrBmlTEFTt8WQQg96rgd8dZWUd60Mh +U6S7CEvE0L/cjM797ouJc2BW5/EoXoxbeKxF3irqZzXmiXmZ6cooVqK1+i+/KW1T +RrMLZ+XJNYkv9SwkPRnGhQF209oFgJQOhiEmTDKWzZXuoQovlcmso4heVwARAQAB +tCpCcmlhbiBNYXkgPGJyaWFuQG1pY3JvY29tYXVzdHJhbGlhLmNvbS5hdT6JAjYE +EwECACAFAktNOzECGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCchO4audAm +NjkSEACmYKaJN770TqVg1ktwFkO2Z6QPhHWRBdSiAhCnDxwGU+AuFFGwbqA5eE5A +wYMHRlY4czgqr1eBHgAbbvM4gIyQq6z3/2wchO6944ywgOeZjm85Ggm5PdlKOuhW +1eiDXFB83Kph3RmIIMmOh3bdrNldNw6p7PEwVG08A/zbqdkj8W9+wtjlRXSEOpVQ +HuOrm9OVhsJCgRwYJycLsrM2LTQ4jb2/uG1BntyeQ8EI6+K7ui7dHJ4E6GPO+MnZ +VCuEyBSVed+Vi64Gt90/BTFxTl5K7rhFLrS8HvyCD3jacSCyX9eiR8qP/Ljquu0l +faujLLKCeNiGIgMVA8Q/oz4q5pntZCrz85kiqZ4Dv6cQJe2HLLCynR190LZYX9/R +lREzbMTQyfEAjCjIKfi0tz5U2HjfUchVTphnL8nOi7GenaAdU0MSKzXzJLRnMy+1 +qga+RC0NOkPggsnqZGhpT13dai2Fy3LjRTFX4DpeC7dT+H5oc4lz3iIzI/ht9fHa +egQsaMEO3jfArJQ28+0w2xCey6+mI+Ktbf0ljyF9+8g4464VluyUTkBdRV3skeXH +3n0OFm4nYGreF5Pq3LhDrJtGaqCaHmvWfM4S9yI83DR9dxl6zPTT28ltBqWGeL3V +w0AOdJCeg4nYoKMRP3EHq02488AD7LMS7BiIg+UrGOvNWQLn+7QjQnJpYW4gTWF5 +IDxicmlhbkBzbm9vcHkuZGViaWFuLm5ldD6JAjYEEwECACAFAktNPYwCGwMGCwkI +BwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCchO4audAmNtcMD/9I0PyQIh+Yfrli9quU +zLG/mUxjislpD/8ZKNHNHuh/OF7cvHZeYbuNGW2P1HgEdWQWKzaiSF2CPTss1cSM +wfO840zcFmF1CZL00YhDGkcqc5y7PI1y0US4l4TqbaoAwLfmPNvcJRPubNN7CZ3S +m300SNIPyzrH0ueaOog3/kfqaA7PkZQ18gR+RWv8VdEH8/iX1nSjbiOy9yNz344X +lcdPSfaLbgDCUsn048usDD4qhVqSJcKFP1v87eDxkXdovQcEIaD+2XQHdfH5zpm8 +k333+9922eEmhM2o2BdXV70sk0vglkoWKexSWVobnEE20XGYldicEkJoOTpl2Cvu +OfQlMvxCxgQ0XgQgoCwm00OPV/KL/LNxDvJnRXRoYMjouM8GzUp+zamHsN3wSH75 +5rGjLgBNOjBWVQJUM1RRYx1QsYXEW/HOFoOWGRJI1Zt893dGjxP3mTc1xNWY6qYT +NHxzSwRuRhAtM8bRKwgQJ+W1doqE5nCgM/l6IxaSXJ7NUjpUgLh1GkwHr1ZOkW60 +5aGl0Xg5docl8fSNYvMXf6zksYanl1vkW23bEM/IQOd0r/E2L9edpOQ0E9vovp5v +tb3Ok3woo5YGw4dWyXQjw0c/SdNZK5b92cxjdF0TeesHq+VzGT8suVjJFjEVYK2h +jez5ZYwqBlPENm8sUdVd7tTmyLQaQnJpYW4gTWF5IDxiYW1AZGViaWFuLm9yZz6J +AjYEEwECACAFAktvjM8CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCchO4a +udAmNmx3D/9FrWpBngi99BtnfoDA7jOIgfvoqxHOMtns+4G0AWFZ/kl/fpCIjKbV +a3vpXe4M/mObAxn8MOS3Pgx2V6L/xNu76fh1VNf963co41tisl4Ez5snIEeJZEA+ +GL6VAsDBte14miXnqlh3mKt4EUQNf8IEDo/BWhndGIW7my9CKqjGD+MWXUgQ8Tw6 +dpQ1G+IL+q9zudvvAqG/d5KFA6TFiWdTh4kscKK8w8Aj+IK6BaXJCLlJ/NslOBG9 +f2TXVNF3jkLjCKGVFflRBecAieugkvpJ9gfq9zf2dhVTHSQ5x5RmFEGs/pcJ8q+a +NXlZCqZxam634xGjt9GUdoJ+CUM/hp5hPsBOVoS3i8M9RlH9nW63+S/tVVJhHdwe +m+nLES/N4GZVXVEARnrIZbQEl4yOVxwkh7Wd6ZKslIXuH630L+d8/dC/YovXIzVR +RP1UkC0QVP/mjkMZXPXbSSsk6RSkszst8XtT6bmEc7XjON6BFRY6Q7ULW2kOQc0t +mx5toOaHjwF9jLrTi7b4CV3C9AgfPiRVtWvsbgbdCAYFpXKYoHgiwdiMpaCjxbVK +YL08VqX+Vzrj0quIznO3/1w9pI68W9EW5aGWIqVz/xETNoxnDYIH1C8XpHeMOuk8 +Qj8vdDqAkbQqZN8kq/dAm7E3q4sR1xYYl7RnMLIvevgU9vxeXXTpeLkCDQRLTT5C +ARAA39dlBAgMV2A2o5HZXsc0GjLG6khAymRqSUmeTtwUI1qSuHElfF+t9D5Ha9L6 +PqYVbh/H6OXtS5oanQ5jk6Mjf0bZlDqZrki1UlRYkH2dlR/6blpvsl68sLEjkVk0 +d29EAda1VytQhzt94jFPa/Yjg2r/dfFUSIAyNDIa21kttvDkVpc3fex5fcvtdJY0 +6AWA8vi4SglFvwKdy4pAxDRcqvZuhDWFcqDjNoxXrIRXB863cSTkZ/W40darBdTQ +bglukTlG7D6OjtdvM0JBwK+2A1jc17uBjZbJ9ZWUf8APGs8uTpy8ClOA8t4Ws/RI ++Eve8AWw3NKRpLmkG3kNK8nfB2zh6Jfro7jOJdloczLir2UFQHvfotb4XK5Pgdzq +WRRXIm7eeJEqGn7HkO0ddHMhXKQzbUwcXJ4DuyJ5ZwtVjYiAKVGW30WebzMFCWtM +RxyqS/kEX98eNEOmhOH2ADq34OrNaxbvFI9SvH/9Zbz0OLlW2HTmgBDYbwctqe+j +9yLOFC9a7Oa01fu2upq55c0cZYwaddcHNIoaZ9BCsmmxjMN6pF9M7VSJWYdQ8fn8 +QlHp7LFepteKjfBwn/eppveVx99vRKtEqKuRaS6sV7g7m+kqK7RbMSZucOg0M18/ +9cs0u1PcM5T4UG5Kbls2rMEXt5/C3Ccb9l+WBH0N/I493jUAEQEAAYkCHwQYAQIA +CQUCS00+QgIbDAAKCRCchO4audAmNgjED/4so9X8A+TPjOUb7p1AOpS0QijBTh6y +MggQsVSR7Zb4mLRmc0zBuIS4DQD3scle75SWGw/Le7Up75Q3/5a6lYXJhGC3H5r5 +eWtOPRbv/NFvvdxLuoxOv3mtzvGXDRQmlz3nCoWVvmpljQo7q8Lj/EFWRC9Oc2kM +kgt7Smkm67o3RE9FDYwUOGoSnbm0EpjsgmSWixn1x33TR3hNpwAeKekVIJ760cSC +ooNLiSSPtGlU22JnJoIUE/Y4qx5LqsKYoDohByX8Fvxz7c3qiGNsEXHRZQx8t79c +2ZyA2TDV9znbeVoMNZFGKuMJWKF59LG88d0GUlznnhvwj0mfq+xkoQ97pLaZtpGR +X0khpQnyr24nBpfIlYY9QstGStEOipvzrCmv47zNhn9IB1ynMyt9NFZb2SJTxz4p +DChN1on8opjuhep41ykcX7CuA51kGa3NxkscxjgsSIU6Il8I6+MrXrThEe5CakMO +ZCJvuKGbKI5hhJja19YP+8rRRvoOirJhiiRRF+GMZeLE8ZYU2PYaGxm5QHHghiQg +j5NTQylcNu99ucJlvKIhRhhRlBze4/e8Efs6aApgPrq0Nq5uwmh06dZNVPkBaHr3 +QQFJdPjEyAqihZMbsTBHvDV149yl6pkZMcLUpnXwkrygEImP69V9N8r5CbiF05uM +aW6JKkzQAySR8rkBDQRMoXAJAQgA3zHrNqlTlD0aj2lF3Hk70UScj4Cq/YYV7Ngx +vVvmUHWJBdIS9QQHV04EIyyVPidNjjAR3vs+pRj0tsXtVI675BlBUOE7+W0+xcPb ++xEYNSMi8zcHDppUrMJC0Kub/lPoUSYs9iM2W/q0IUshUM8h06zEQtptilgAIWu1 +g2I0OVAUbsgIy2VAmaI3n9zPcH0II45p1m1bo84PUtEbZ/NYRh+te4oTo1yPJyfG +MMDm17PNMGqQS2W9G/3SvLDYgGm4BatAuQQtBQ8X0GZMwrFDD5PeMQufsYIB4xw0 +AfIBYG8waMLzKGUD4iOueUfQUBFo3eZNW3jALdoZ8FgNGxMcgwARAQABiQIfBBgB +AgAJBQJMoXAJAhsgAAoJEJyE7hq50CY2V+cP/Akxu45UqP2mEyEffty6maidav+R +2YgbIAymls1g7jAn+va9sFQ8giJxibDQX6B82pG3Fm3E6fmM+i0X1OGI2wn6NO0N +2Sk28DOuo3xcc3hgtSLkAsdoDYmAfli3PLQyntEC8bhWPhFKoKj5CsH6yTj7q2vZ +7LJF5mhH/rzZGnelCjMG0NsZcIwYjT8xJbW8eYMmARU2QgdOYamLDDG2KjOBhiQI +Z4t++nm2UuqxTZcpvPJJna+6NoPVdfY4/DqZ0inOqJV2/3Xj/GEje4cIvLRPFUo/ +WPF0c3Mk7CNwpWGbe7vOuMTH0gHbLw4ydf+tXoER3XuBcOvDCA0gIb/lP5NXUZoo +roTzElGhJFc9nr1BWULenHpGxBnBTGBka7smfksw18XfumZI8H43b5UVrc12zSoD +cgiEeO3JrwDJYBNyGSvU9d4I2KVHjO/pl80fKt3KaXRjZ4ThwsiT/P93twswkKok +/NmmIbmK2+7cqv5E6Yu5F3tBzla+pghaWug2xIiZZfHp7lbFcMEZzNaYEpurF6J2 +MdQH6zGSmjqXHIr23NMjQElBuv+L7P+RQJDPAoq4gPgK3w1CE0xJcjEf+TQSp0tt +Of5lMCUouS3nmc7k/J0L5HsjpNh2eZ0mqqaslVP6/OUEOT6Uapua764M/PfmxIPd +zcOslKmTlFubb8Mc +=/Hpf +-----END PGP PUBLIC KEY BLOCK----- diff -Nru django-guardian-1.3.2/debian/watch django-guardian-1.4.1/debian/watch --- django-guardian-1.3.2/debian/watch 2015-11-14 03:22:38.000000000 +0000 +++ django-guardian-1.4.1/debian/watch 2016-01-13 09:00:46.000000000 +0000 @@ -1,2 +1,3 @@ version=3 -https://github.com/lukaszb/django-guardian/tags .*/v(\d[\d\.]+)\.tar\.gz +opts=uversionmangle=s/(rc|a|b|c)/~$1/,pgpsigurlmangle=s/$/.asc/ \ +https://pypi.debian.net/django-guardian/django-guardian-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) diff -Nru django-guardian-1.3.2/django_guardian.egg-info/dependency_links.txt django-guardian-1.4.1/django_guardian.egg-info/dependency_links.txt --- django-guardian-1.3.2/django_guardian.egg-info/dependency_links.txt 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/django_guardian.egg-info/dependency_links.txt 2016-01-09 22:45:20.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru django-guardian-1.3.2/django_guardian.egg-info/not-zip-safe django-guardian-1.4.1/django_guardian.egg-info/not-zip-safe --- django-guardian-1.3.2/django_guardian.egg-info/not-zip-safe 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/django_guardian.egg-info/not-zip-safe 2015-12-22 22:59:52.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru django-guardian-1.3.2/django_guardian.egg-info/PKG-INFO django-guardian-1.4.1/django_guardian.egg-info/PKG-INFO --- django-guardian-1.3.2/django_guardian.egg-info/PKG-INFO 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/django_guardian.egg-info/PKG-INFO 2016-01-09 22:45:20.000000000 +0000 @@ -0,0 +1,23 @@ +Metadata-Version: 1.1 +Name: django-guardian +Version: 1.4.1 +Summary: Implementation of per object permissions for Django. +Home-page: http://github.com/django-guardian/django-guardian +Author: Lukasz Balcerzak +Author-email: lukaszbalcerzak@gmail.com +License: BSD +Download-URL: https://github.com/django-guardian/django-guardian/tags +Description: 1.4.1 +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Django +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Security +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 diff -Nru django-guardian-1.3.2/django_guardian.egg-info/requires.txt django-guardian-1.4.1/django_guardian.egg-info/requires.txt --- django-guardian-1.3.2/django_guardian.egg-info/requires.txt 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/django_guardian.egg-info/requires.txt 2016-01-09 22:45:20.000000000 +0000 @@ -0,0 +1,2 @@ +Django >= 1.7 +six diff -Nru django-guardian-1.3.2/django_guardian.egg-info/SOURCES.txt django-guardian-1.4.1/django_guardian.egg-info/SOURCES.txt --- django-guardian-1.3.2/django_guardian.egg-info/SOURCES.txt 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/django_guardian.egg-info/SOURCES.txt 2016-01-09 22:45:25.000000000 +0000 @@ -0,0 +1,165 @@ +.gitignore +.travis.yml +AUTHORS +CHANGES +LICENSE +MANIFEST.in +README.rst +VERSION.txt +extras.py +manage.py +requirements.txt +run_test_and_report.sh +setup.cfg +setup.py +tests.py +tox.ini +utils.py +django_guardian.egg-info/PKG-INFO +django_guardian.egg-info/SOURCES.txt +django_guardian.egg-info/dependency_links.txt +django_guardian.egg-info/not-zip-safe +django_guardian.egg-info/requires.txt +django_guardian.egg-info/top_level.txt +docs/Makefile +docs/conf.py +docs/configuration.rst +docs/exts.py +docs/exts.pyc +docs/index.rst +docs/installation.rst +docs/license.rst +docs/make.bat +docs/overview.rst +docs/watch-docs.sh +docs/__pycache__/exts.cpython-33.pyc +docs/__pycache__/exts.cpython-34.pyc +docs/__pycache__/exts.cpython-35.pyc +docs/api/guardian.admin.rst +docs/api/guardian.backends.rst +docs/api/guardian.core.rst +docs/api/guardian.decorators.rst +docs/api/guardian.forms.rst +docs/api/guardian.management.commands.rst +docs/api/guardian.managers.rst +docs/api/guardian.mixins.rst +docs/api/guardian.models.rst +docs/api/guardian.shortcuts.rst +docs/api/guardian.templatetags.guardian_tags.rst +docs/api/guardian.utils.rst +docs/api/index.rst +docs/develop/changes.rst +docs/develop/index.rst +docs/develop/overview.rst +docs/develop/supported-versions.rst +docs/develop/testing.rst +docs/theme/rtd_theme/breadcrumbs.html +docs/theme/rtd_theme/footer.html +docs/theme/rtd_theme/layout.html +docs/theme/rtd_theme/layout_old.html +docs/theme/rtd_theme/search.html +docs/theme/rtd_theme/searchbox.html +docs/theme/rtd_theme/theme.conf +docs/theme/rtd_theme/versions.html +docs/theme/rtd_theme/sass/_badge.sass +docs/theme/rtd_theme/sass/_badge_font_awesome_mini.sass +docs/theme/rtd_theme/sass/_breadcrumbs.sass +docs/theme/rtd_theme/sass/_nav.sass +docs/theme/rtd_theme/sass/badge_only.sass +docs/theme/rtd_theme/sass/config.rb +docs/theme/rtd_theme/sass/theme.sass +docs/theme/rtd_theme/static/badge_only.css +docs/theme/rtd_theme/static/theme.css +docs/theme/rtd_theme/static/theme.js +docs/theme/rtd_theme/static/font/fontawesome_webfont.eot +docs/theme/rtd_theme/static/font/fontawesome_webfont.svg +docs/theme/rtd_theme/static/font/fontawesome_webfont.ttf +docs/theme/rtd_theme/static/font/fontawesome_webfont.woff +docs/userguide/admin-integration.rst +docs/userguide/assign.rst +docs/userguide/caveats.rst +docs/userguide/check.rst +docs/userguide/custom-user-model.rst +docs/userguide/example_project.rst +docs/userguide/index.rst +docs/userguide/performance.rst +docs/userguide/remove.rst +guardian/__init__.py +guardian/admin.py +guardian/apps.py +guardian/backends.py +guardian/checks.py +guardian/compat.py +guardian/core.py +guardian/decorators.py +guardian/exceptions.py +guardian/forms.py +guardian/managers.py +guardian/mixins.py +guardian/models.py +guardian/shortcuts.py +guardian/utils.py +guardian/conf/__init__.py +guardian/conf/settings.py +guardian/locale/es/LC_MESSAGES/django.mo +guardian/locale/es/LC_MESSAGES/django.po +guardian/locale/fr/LC_MESSAGES/django.mo +guardian/locale/fr/LC_MESSAGES/django.po +guardian/locale/pl/LC_MESSAGES/django.mo +guardian/locale/pl/LC_MESSAGES/django.po +guardian/locale/pt_BR/LC_MESSAGES/django.mo +guardian/locale/pt_BR/LC_MESSAGES/django.po +guardian/locale/ru/LC_MESSAGES/django.mo +guardian/locale/ru/LC_MESSAGES/django.po +guardian/management/__init__.py +guardian/management/commands/__init__.py +guardian/management/commands/clean_orphan_obj_perms.py +guardian/migrations/0001_initial.py +guardian/migrations/__init__.py +guardian/static/guardian/img/icon-no.svg +guardian/static/guardian/img/icon-yes.svg +guardian/templates/admin/guardian/contrib/grappelli/field.html +guardian/templates/admin/guardian/contrib/grappelli/obj_perms_manage.html +guardian/templates/admin/guardian/contrib/grappelli/obj_perms_manage_group.html +guardian/templates/admin/guardian/contrib/grappelli/obj_perms_manage_user.html +guardian/templates/admin/guardian/model/change_form.html +guardian/templates/admin/guardian/model/field.html +guardian/templates/admin/guardian/model/obj_perms_manage.html +guardian/templates/admin/guardian/model/obj_perms_manage_group.html +guardian/templates/admin/guardian/model/obj_perms_manage_user.html +guardian/templates/admin/guardian/model/obj_perms_no.html +guardian/templates/admin/guardian/model/obj_perms_yes.html +guardian/templatetags/__init__.py +guardian/templatetags/guardian_tags.py +guardian/testapp/__init__.py +guardian/testapp/models.py +guardian/testapp/testsettings.py +guardian/testapp/migrations/0001_initial.py +guardian/testapp/migrations/0002_logentrywithgroup.py +guardian/testapp/migrations/0003_auto_20141124_0729.py +guardian/testapp/migrations/0004_auto_20151112_2209.py +guardian/testapp/migrations/0005_auto_20151217_2344.py +guardian/testapp/migrations/__init__.py +guardian/testapp/tests/__init__.py +guardian/testapp/tests/conf.py +guardian/testapp/tests/test_admin.py +guardian/testapp/tests/test_checks.py +guardian/testapp/tests/test_conf.py +guardian/testapp/tests/test_core.py +guardian/testapp/tests/test_custompkmodel.py +guardian/testapp/tests/test_decorators.py +guardian/testapp/tests/test_direct_rel.py +guardian/testapp/tests/test_forms.py +guardian/testapp/tests/test_management.py +guardian/testapp/tests/test_managers.py +guardian/testapp/tests/test_mixins.py +guardian/testapp/tests/test_orphans.py +guardian/testapp/tests/test_other.py +guardian/testapp/tests/test_shortcuts.py +guardian/testapp/tests/test_tags.py +guardian/testapp/tests/test_utils.py +guardian/testapp/tests/urls.py +guardian/testapp/tests/templates/404.html +guardian/testapp/tests/templates/500.html +guardian/testapp/tests/templates/blank.html +guardian/testapp/tests/templates/dummy403.html \ No newline at end of file diff -Nru django-guardian-1.3.2/django_guardian.egg-info/top_level.txt django-guardian-1.4.1/django_guardian.egg-info/top_level.txt --- django-guardian-1.3.2/django_guardian.egg-info/top_level.txt 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/django_guardian.egg-info/top_level.txt 2016-01-09 22:45:20.000000000 +0000 @@ -0,0 +1,3 @@ +benchmarks +example_project +guardian diff -Nru django-guardian-1.3.2/docs/configuration.rst django-guardian-1.4.1/docs/configuration.rst --- django-guardian-1.3.2/docs/configuration.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/configuration.rst 2015-12-18 05:08:22.000000000 +0000 @@ -29,6 +29,20 @@ ``syncdb`` management command would create ``User`` instance for anonymous user support (with name of ``AnonymousUser``). +.. note:: + + The Guardian anonymous user is different to the Django Anonymous user. The + Django Anonymous user does not have an entry in the database, however the + Guardian anonymous user does. This means that the following code will return + an unexpected result: + + .. code-block:: python + + from guardian.compat import get_user_model + User = get_user_model() + anon = User.get_anonymous() + anon.is_anonymous() # returns False + If ``ANONYMOUS_USER_ID`` is set to ``None``, anonymous user object permissions are disabled. You may need to choose this option if creating a ``User`` object to represent anonymous users would be problematic in your environment. diff -Nru django-guardian-1.3.2/docs/conf.py django-guardian-1.4.1/docs/conf.py --- django-guardian-1.3.2/docs/conf.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/conf.py 2016-01-09 22:41:23.000000000 +0000 @@ -18,10 +18,13 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('..')) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__)))) -os.environ['DJANGO_SETTINGS_MODULE'] = 'guardian.testsettings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'guardian.testapp.testsettings' ANONYMOUS_USER_ID = -1 # Required by guardian guardian = __import__('guardian') +import django +django.setup() + # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions @@ -57,10 +60,11 @@ # |version| and |release|, also used in various other places throughout the # built documents. # -# The short X.Y version. -version = guardian.get_version() -# The full version, including alpha/beta/rc tags. -release = guardian.__version__ +with open('../VERSION.txt', 'r') as f: + # The short X.Y version. + version = f.readline().strip() + # The full version, including alpha/beta/rc tags. + release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -Nru django-guardian-1.3.2/docs/develop/example_project.rst django-guardian-1.4.1/docs/develop/example_project.rst --- django-guardian-1.3.2/docs/develop/example_project.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/develop/example_project.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -.. _example-project: - -Example project -=============== - -Example project should be boundled with archive and be available at -``example_project``. Before you can run it, some requirements have to be met. -Those are easily installed using following command at example project's -directory:: - - $ pip install -r requirements.txt - -And last thing before we can run example project is to create sqlite database:: - - $ python manage.py syncdb - -Finally we can run dev server:: - - $ python manage.py runserver - -Project is really basic and shows almost nothing but eventually it should -expose some ``django-guardian`` functionality. - - -.. note:: - Example project must be run with Django 1.5 or later. This is to ensure that - custom user model can be used. - diff -Nru django-guardian-1.3.2/docs/develop/index.rst django-guardian-1.4.1/docs/develop/index.rst --- django-guardian-1.3.2/docs/develop/index.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/develop/index.rst 2015-12-18 05:08:22.000000000 +0000 @@ -6,7 +6,6 @@ .. toctree:: overview - example_project testing supported-versions changes diff -Nru django-guardian-1.3.2/docs/develop/overview.rst django-guardian-1.4.1/docs/develop/overview.rst --- django-guardian-1.3.2/docs/develop/overview.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/develop/overview.rst 2015-12-18 05:08:22.000000000 +0000 @@ -24,7 +24,7 @@ How to file a ticket? --------------------- -Just go to https://github.com/lukaszb/django-guardian/issues and create new +Just go to https://github.com/django-guardian/django-guardian/issues and create new one. @@ -33,13 +33,13 @@ It's simple! If you want to fix a bug, extend documentation or whatever you think is appropriate for the project and involves changes, just fork the -project at github (https://github.com/lukaszb/django-guardian), create a +project at github (https://github.com/django-guardian/django-guardian), create a separate branch, hack on it, publish changes at your fork and create a pull request. Here is a quick how to: -1. Fork a project: https://github.com/lukaszb/django-guardian/fork +1. Fork a project: https://github.com/django-guardian/django-guardian/fork 2. Checkout project to your local machine:: $ git clone git@github.com:YOUR_NAME/django-guardian.git diff -Nru django-guardian-1.3.2/docs/develop/supported-versions.rst django-guardian-1.4.1/docs/develop/supported-versions.rst --- django-guardian-1.3.2/docs/develop/supported-versions.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/develop/supported-versions.rst 2015-12-18 05:08:22.000000000 +0000 @@ -3,13 +3,12 @@ Supported versions ================== -``django-guardian`` supports Python 2.7+/3.3+ and Django 1.5+. +``django-guardian`` supports Python 2.7+/3.3+ and Django 1.7+. Rules ----- * We would support Python 2.7. We also support Python 3.3+. * Support for Python 3.3 may get dropped in the future. -* We support Django 1.5+, however next big ``guardian`` release (v2.0) we would - support Django 1.7+ (or higher, depending on the date guardian v2.0 would be - released). This is due to many simplifications in code we could do. +* We support Django 1.7+. This is due to many simplifications in code we could + do. diff -Nru django-guardian-1.3.2/docs/develop/testing.rst django-guardian-1.4.1/docs/develop/testing.rst --- django-guardian-1.3.2/docs/develop/testing.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/develop/testing.rst 2016-01-08 08:13:40.000000000 +0000 @@ -34,6 +34,9 @@ $ python manage.py test guardian +or using the bundled ``testapp`` project:: + + $ python manage.py test Coverage support ---------------- Binary files /tmp/tmpWNj4nK/xfAd4TdNGQ/django-guardian-1.3.2/docs/exts.pyc and /tmp/tmpWNj4nK/1xp_hPCHJI/django-guardian-1.4.1/docs/exts.pyc differ diff -Nru django-guardian-1.3.2/docs/installation.rst django-guardian-1.4.1/docs/installation.rst --- django-guardian-1.3.2/docs/installation.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/installation.rst 2016-01-09 22:41:23.000000000 +0000 @@ -3,7 +3,7 @@ Installation ============ -This application requires Django_ 1.3 or higher and it is only prerequisite +This application requires Django_ 1.7 or higher and it is the only prerequisite before ``django-guardian`` may be used. In order to install ``django-guardian`` simply use ``pip``:: Binary files /tmp/tmpWNj4nK/xfAd4TdNGQ/django-guardian-1.3.2/docs/__pycache__/exts.cpython-33.pyc and /tmp/tmpWNj4nK/1xp_hPCHJI/django-guardian-1.4.1/docs/__pycache__/exts.cpython-33.pyc differ Binary files /tmp/tmpWNj4nK/xfAd4TdNGQ/django-guardian-1.3.2/docs/__pycache__/exts.cpython-34.pyc and /tmp/tmpWNj4nK/1xp_hPCHJI/django-guardian-1.4.1/docs/__pycache__/exts.cpython-34.pyc differ Binary files /tmp/tmpWNj4nK/xfAd4TdNGQ/django-guardian-1.3.2/docs/__pycache__/exts.cpython-35.pyc and /tmp/tmpWNj4nK/1xp_hPCHJI/django-guardian-1.4.1/docs/__pycache__/exts.cpython-35.pyc differ diff -Nru django-guardian-1.3.2/docs/userguide/admin-integration.rst django-guardian-1.4.1/docs/userguide/admin-integration.rst --- django-guardian-1.3.2/docs/userguide/admin-integration.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/userguide/admin-integration.rst 2015-12-18 05:08:22.000000000 +0000 @@ -49,7 +49,7 @@ from django.contrib import admin - from example_project.posts.models import Post + from posts.models import Post class PostAdmin(admin.ModelAdmin): @@ -70,7 +70,7 @@ from django.contrib import admin - from example_project.posts.models import Post + from posts.models import Post from guardian.admin import GuardedModelAdmin diff -Nru django-guardian-1.3.2/docs/userguide/assign.rst django-guardian-1.4.1/docs/userguide/assign.rst --- django-guardian-1.3.2/docs/userguide/assign.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/userguide/assign.rst 2016-01-08 08:13:40.000000000 +0000 @@ -104,4 +104,59 @@ >>> joe.groups.add(group) >>> joe.has_perm('change_task', task) True - + +Another example: + +.. code-block:: python + + >>> from django.contrib.auth.models import User, Group + >>> from guardian.shortcuts import assign_perm + # fictional companies + >>> companyA = Company.objects.create(name="Company A") + >>> companyB = Company.objects.create(name="Company B") + # create groups + >>> companyUserGroupA = Group.objects.create(name="Company User Group A") + >>> companyUserGroupB = Group.objects.create(name="Company User Group B") + # assign object specific permissions to groups + >>> assign_perm('change_company', companyUserGroupA, companyA) + >>> assign_perm('change_company', companyUserGroupB, companyB) + # create user and add it to one group for testing + >>> userA = User.objects.create(username="User A") + >>> userA.groups.add(companyUserGroupA) + >>> userA.has_perm('change_company', companyA) + True + >>> userA.has_perm('change_company', companyB) + False + >>> userB = User.objects.create(username="User B") + >>> userB.has_perm('change_company', companyA) + False + >>> userA.has_perm('change_company', companyB) + True + +Assigning Permissions inside Signals +------------------------------------ +Note that the Anonymous User is created before the Permissions are created. +This may result in Django signals, e.g. ``post_save`` being sent before the +Permissions are created. You will need to take this into an account when +processing the signal. + + +.. code-block:: python + + @receiver(post_save, sender=User) + def user_post_save(sender, **kwargs): + """ + Create a Profile instance for all newly created User instances. We only + run on user creation to avoid having to check for existence on each call + to User.save. + """ + user, created = kwargs["instance"], kwargs["created"] + if created and user.pk != settings.ANONYMOUS_USER_ID: + from profiles.models import Profile + profile = Profile.objects.create(pk=user.pk, user=user, creator=user) + assign_perm("change_user", user, user) + assign_perm("change_profile", user, profile) + +The check for ``user.pk != settings.ANONYMOUS_USER_ID`` is required otherwise +the ``assign_perm`` calls will occur when the Anonymous User is created, +however before there are any permissions available. diff -Nru django-guardian-1.3.2/docs/userguide/caveats.rst django-guardian-1.4.1/docs/userguide/caveats.rst --- django-guardian-1.3.2/docs/userguide/caveats.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/userguide/caveats.rst 2015-12-18 05:08:22.000000000 +0000 @@ -6,6 +6,9 @@ Orphaned object permissions --------------------------- +Note the following does not apply if using direct foreign keys, as documented +in :ref:`performance-direct-fk`. + Permissions, including so called *per object permissions*, are sometimes tricky to manage. One case is how we can manage permissions that are no longer used. Normally, there should be no problems, however with some particular setup it is @@ -77,3 +80,10 @@ .. _celery: http://www.celeryproject.org/ + +Using multiple databases +------------------------ +This is not supported at present time due to a Django bug. See 288_ and 16281_. + +.. _288: https://github.com/django-guardian/django-guardian/issues/288 +.. _16281: https://code.djangoproject.com/ticket/16281 diff -Nru django-guardian-1.3.2/docs/userguide/example_project.rst django-guardian-1.4.1/docs/userguide/example_project.rst --- django-guardian-1.3.2/docs/userguide/example_project.rst 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/docs/userguide/example_project.rst 2015-12-18 05:08:22.000000000 +0000 @@ -0,0 +1,23 @@ +.. _example-project: + +Example project +=============== + +Example project should be boundled with archive and be available at +``example_project``. Before you can run it, some requirements have to be met. +Those are easily installed using following command at example project's +directory:: + + $ cd example_project + $ pip install -r requirements.txt + +And last thing before we can run example project is to create sqlite database:: + + $ python manage.py syncdb + +Finally we can run dev server:: + + $ python manage.py runserver + +Project is really basic and shows almost nothing but eventually it should +expose some ``django-guardian`` functionality. diff -Nru django-guardian-1.3.2/docs/userguide/index.rst django-guardian-1.4.1/docs/userguide/index.rst --- django-guardian-1.3.2/docs/userguide/index.rst 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/docs/userguide/index.rst 2015-12-18 05:08:22.000000000 +0000 @@ -6,6 +6,7 @@ .. toctree:: :maxdepth: 2 + example_project assign check remove diff -Nru django-guardian-1.3.2/example_project/context_processors.py django-guardian-1.4.1/example_project/context_processors.py --- django-guardian-1.3.2/example_project/context_processors.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/context_processors.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -import guardian - -def version(request): - return {'version': guardian.get_version()} - diff -Nru django-guardian-1.3.2/example_project/core/models.py django-guardian-1.4.1/example_project/core/models.py --- django-guardian-1.3.2/example_project/core/models.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/core/models.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -from django.contrib.auth.models import AbstractUser -from django.db import models -import datetime - - -class CustomUser(AbstractUser): - real_username = models.CharField(max_length=120, unique=True) - birth_date = models.DateField(null=True, blank=True) - - USERNAME_FIELD = 'real_username' - - def save(self, *args, **kwargs): - if not self.real_username: - self.real_username = self.username - return super(CustomUser, self).save(*args, **kwargs) - - -def get_custom_anon_user(User): - return User( - real_username='AnonymousUser', - birth_date=datetime.date(1410, 7, 15), - ) diff -Nru django-guardian-1.3.2/example_project/integration_tests/tests.py django-guardian-1.4.1/example_project/integration_tests/tests.py --- django-guardian-1.3.2/example_project/integration_tests/tests.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/integration_tests/tests.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -from django.test import TestCase - -from guardian.conf import settings -from guardian.compat import get_user_model -from guardian.management import create_anonymous_user - - -User = get_user_model() - - -class CustomUserTests(TestCase): - def test_create_anonymous_user(self): - create_anonymous_user(object()) - self.assertEqual(1, User.objects.all().count()) - anonymous = User.objects.all()[0] - self.assertEqual(anonymous.pk, settings.ANONYMOUS_USER_ID) - diff -Nru django-guardian-1.3.2/example_project/manage.py django-guardian-1.4.1/example_project/manage.py --- django-guardian-1.3.2/example_project/manage.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/manage.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -#!/usr/bin/env python -import django -import os -import sys - -if django.VERSION < (1, 5): - sys.stderr.write("ERROR: guardian's example project must be run with " - "Django 1.5 or later!\n") - sys.exit(1) - - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") - - from django.core.management import execute_from_command_line - - execute_from_command_line(sys.argv) diff -Nru django-guardian-1.3.2/example_project/posts/admin.py django-guardian-1.4.1/example_project/posts/admin.py --- django-guardian-1.3.2/example_project/posts/admin.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/posts/admin.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -from django.contrib import admin - -from example_project.posts.models import Post - -from guardian.admin import GuardedModelAdmin - - -class PostAdmin(GuardedModelAdmin): - prepopulated_fields = {"slug": ("title",)} - list_display = ('title', 'slug', 'created_at') - search_fields = ('title', 'content') - ordering = ('-created_at',) - date_hierarchy = 'created_at' - -admin.site.register(Post, PostAdmin) - diff -Nru django-guardian-1.3.2/example_project/posts/models.py django-guardian-1.4.1/example_project/posts/models.py --- django-guardian-1.3.2/example_project/posts/models.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/posts/models.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -from django.db import models - - -class Post(models.Model): - title = models.CharField('title', max_length=64) - slug = models.SlugField(max_length=64) - content = models.TextField('content') - created_at = models.DateTimeField(auto_now_add=True, db_index=True) - - class Meta: - permissions = ( - ('view_post', 'Can view post'), - ) - get_latest_by = 'created_at' - - def __unicode__(self): - return self.title - - @models.permalink - def get_absolute_url(self): - return ('posts_post_detail', (), {'slug': self.slug}) - diff -Nru django-guardian-1.3.2/example_project/posts/templates/posts/post_detail.html django-guardian-1.4.1/example_project/posts/templates/posts/post_detail.html --- django-guardian-1.3.2/example_project/posts/templates/posts/post_detail.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/posts/templates/posts/post_detail.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -{% extends "base.html" %} - -{% load guardian_tags %} - -{% block content %} -
-
- Back to posts list -

User permissions

- -
- -
-

{{ post.title }}

-
at {{ post.created_at }}
-
- {{ post.content|safe }} -
-
- -{% endblock %} - diff -Nru django-guardian-1.3.2/example_project/posts/templates/posts/post_list.html django-guardian-1.4.1/example_project/posts/templates/posts/post_list.html --- django-guardian-1.3.2/example_project/posts/templates/posts/post_list.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/posts/templates/posts/post_list.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -{% extends "base.html" %} - -{% block content %} -
- -
- -
- -
-
-

Posts

- Add post -
-
-{% for post in posts %} -
-
-
-

{{ post.title }}

-
at {{ post.created_at }}
-
- {{ post.content|safe }} -
-{% endfor %} -
- - -{% endblock %} diff -Nru django-guardian-1.3.2/example_project/posts/urls.py django-guardian-1.4.1/example_project/posts/urls.py --- django-guardian-1.3.2/example_project/posts/urls.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/posts/urls.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -from guardian.compat import url, patterns - - -urlpatterns = patterns('posts.views', - url(r'^$', view='post_list', name='posts_post_list'), - url(r'^(?P[-\w]+)/$', view='post_detail', name='posts_post_detail'), -) - diff -Nru django-guardian-1.3.2/example_project/posts/views.py django-guardian-1.4.1/example_project/posts/views.py --- django-guardian-1.3.2/example_project/posts/views.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/posts/views.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -from django.contrib.auth.models import Group -from django.shortcuts import render_to_response, get_object_or_404 -from django.views.generic import ListView -from django.template import RequestContext -from guardian.decorators import permission_required_or_403 -from guardian.compat import get_user_model - -from .models import Post - -User = get_user_model() - - -class PostList(ListView): - model = Post - context_object_name = 'posts' - -post_list = PostList.as_view() - - -@permission_required_or_403('posts.view_post', (Post, 'slug', 'slug')) -def post_detail(request, slug, **kwargs): - data = { - 'post': get_object_or_404(Post, slug=slug), - 'users': User.objects.all(), - 'groups': Group.objects.all(), - } - return render_to_response('posts/post_detail.html', data, - RequestContext(request)) - diff -Nru django-guardian-1.3.2/example_project/requirements.txt django-guardian-1.4.1/example_project/requirements.txt --- django-guardian-1.3.2/example_project/requirements.txt 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/requirements.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -Django==1.6 -mock==1.0.1 -django-rosetta==0.7.3 diff -Nru django-guardian-1.3.2/example_project/settings.py django-guardian-1.4.1/example_project/settings.py --- django-guardian-1.3.2/example_project/settings.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/settings.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -import django -import os -import sys - -from django.conf import global_settings - -abspath = lambda *p: os.path.abspath(os.path.join(*p)) - -DEBUG = True -TEMPLATE_DEBUG = DEBUG -SECRET_KEY = 'CHANGE_THIS_TO_SOMETHING_UNIQUE_AND_SECURE' - -TEST_SOUTH = 'GUARDIAN_TEST_SOUTH' in os.environ - -PROJECT_ROOT = abspath(os.path.dirname(__file__)) -GUARDIAN_MODULE_PATH = abspath(PROJECT_ROOT, '..') -sys.path.insert(0, GUARDIAN_MODULE_PATH) -sys.path.insert(0, PROJECT_ROOT) - - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': abspath(PROJECT_ROOT, '.hidden.db'), - 'TEST_NAME': ':memory:', - }, -} - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.admin', - 'django.contrib.messages', - 'guardian', - 'guardian.testapp', - 'posts', - 'core', - 'integration_tests', - 'django.contrib.staticfiles', -) - -if 'GUARDIAN_NO_TESTS_APP' in os.environ: - _apps = list(INSTALLED_APPS) - _apps.remove('guardian.testapp') - INSTALLED_APPS = tuple(_apps) - -if TEST_SOUTH: - INSTALLED_APPS += ('south',) -if 'GRAPPELLI' in os.environ: - try: - __import__('grappelli') - INSTALLED_APPS = ('grappelli',) + INSTALLED_APPS - except ImportError: - print("django-grappelli not installed") - -try: - import rosetta - INSTALLED_APPS += ('rosetta',) -except ImportError: - pass - -#MIDDLEWARE_CLASSES = ( - #'django.middleware.common.CommonMiddleware', - #'django.contrib.sessions.middleware.SessionMiddleware', - #'django.middleware.csrf.CsrfViewMiddleware', - #'django.contrib.auth.middleware.AuthenticationMiddleware', - #'django.contrib.messages.middleware.MessageMiddleware', - #'django.middleware.transaction.TransactionMiddleware', -#) - -STATIC_ROOT = abspath(PROJECT_ROOT, '..', 'public', 'static') -STATIC_URL = '/static/' -STATICFILES_DIRS = [abspath(PROJECT_ROOT, 'static')] -MEDIA_ROOT = abspath(PROJECT_ROOT, 'media') -MEDIA_URL = '/media/' -ADMIN_MEDIA_PREFIX = STATIC_URL + 'grappelli/' - -ROOT_URLCONF = 'example_project.urls' - -TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + ( - 'django.core.context_processors.request', - 'example_project.context_processors.version', - 'django.core.context_processors.static', -) -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -) - -TEMPLATE_DIRS = ( - os.path.join(os.path.dirname(__file__), 'templates'), -) - -SITE_ID = 1 - -USE_I18N = True -USE_L10N = True - -LOGIN_REDIRECT_URL = '/' - -if django.VERSION < (1, 8): - TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner' -else: - TEST_RUNNER = 'django.test.runner.DiscoverRunner' - -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'guardian.backends.ObjectPermissionBackend', -) - -ANONYMOUS_USER_ID = -1 -GUARDIAN_GET_INIT_ANONYMOUS_USER = 'core.models.get_custom_anon_user' - -PASSWORD_HASHERS = ( - 'django.contrib.auth.hashers.MD5PasswordHasher', - 'django.contrib.auth.hashers.SHA1PasswordHasher', -) - -# Neede as some models (located at guardian/tests/models.py) -# are not migrated for tests -SOUTH_TESTS_MIGRATE = TEST_SOUTH - -AUTH_USER_MODEL = 'core.CustomUser' - -try: - from conf.localsettings import * -except ImportError: - pass - diff -Nru django-guardian-1.3.2/example_project/static/css/bootstrap.min.css django-guardian-1.4.1/example_project/static/css/bootstrap.min.css --- django-guardian-1.3.2/example_project/static/css/bootstrap.min.css 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/static/css/bootstrap.min.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -/*! - * Bootstrap v2.3.0 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}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-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} Binary files /tmp/tmpWNj4nK/xfAd4TdNGQ/django-guardian-1.3.2/example_project/static/img/glyphicons-halflings.png and /tmp/tmpWNj4nK/1xp_hPCHJI/django-guardian-1.4.1/example_project/static/img/glyphicons-halflings.png differ Binary files /tmp/tmpWNj4nK/xfAd4TdNGQ/django-guardian-1.3.2/example_project/static/img/glyphicons-halflings-white.png and /tmp/tmpWNj4nK/1xp_hPCHJI/django-guardian-1.4.1/example_project/static/img/glyphicons-halflings-white.png differ diff -Nru django-guardian-1.3.2/example_project/static/js/bootstrap.min.js django-guardian-1.4.1/example_project/static/js/bootstrap.min.js --- django-guardian-1.3.2/example_project/static/js/bootstrap.min.js 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/static/js/bootstrap.min.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -/*! -* Bootstrap.js by @fat & @mdo -* Copyright 2012 Twitter, Inc. -* http://www.apache.org/licenses/LICENSE-2.0.txt -*/ -!function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||s.toggleClass("open"),n.focus(),!1},keydown:function(n){var r,s,o,u,a,f;if(!/(38|40|27)/.test(n.keyCode))return;r=e(this),n.preventDefault(),n.stopPropagation();if(r.is(".disabled, :disabled"))return;u=i(r),a=u.hasClass("open");if(!a||a&&n.keyCode==27)return n.which==27&&u.find(t).focus(),r.click();s=e("[role=menu] li:not(.divider):visible a",u);if(!s.length)return;f=s.index(s.filter(":focus")),n.keyCode==38&&f>0&&f--,n.keyCode==40&&f').appendTo(document.body),this.$backdrop.click(this.options.backdrop=="static"?e.proxy(this.$element[0].focus,this.$element[0]):e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!t)return;i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,t):t()):t&&t()}};var n=e.fn.modal;e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e.fn.modal.noConflict=function(){return e.fn.modal=n,this},e(document).on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s,o,u,a;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,o=this.options.trigger.split(" ");for(a=o.length;a--;)u=o[a],u=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):u!="manual"&&(i=u=="hover"?"mouseenter":"focus",s=u=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this)));this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,this.$element.data(),t),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);if(!n.options.delay||!n.options.delay.show)return n.show();clearTimeout(this.timeout),n.hoverState="in",this.timeout=setTimeout(function(){n.hoverState=="in"&&n.show()},n.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var t,n,r,i,s,o,u=e.Event("show");if(this.hasContent()&&this.enabled){this.$element.trigger(u);if(u.isDefaultPrevented())return;t=this.tip(),this.setContent(),this.options.animation&&t.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,t[0],this.$element[0]):this.options.placement,t.detach().css({top:0,left:0,display:"block"}),this.options.container?t.appendTo(this.options.container):t.insertAfter(this.$element),n=this.getPosition(),r=t[0].offsetWidth,i=t[0].offsetHeight;switch(s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}this.applyPlacement(o,s),this.$element.trigger("shown")}},applyPlacement:function(e,t){var n=this.tip(),r=n[0].offsetWidth,i=n[0].offsetHeight,s,o,u,a;n.offset(e).addClass(t).addClass("in"),s=n[0].offsetWidth,o=n[0].offsetHeight,t=="top"&&o!=i&&(e.top=e.top+i-o,a=!0),t=="bottom"||t=="top"?(u=0,e.left<0&&(u=e.left*-2,e.left=0,n.offset(e),s=n[0].offsetWidth,o=n[0].offsetHeight),this.replaceArrow(u-r+s,s,"left")):this.replaceArrow(o-i,o,"top"),a&&n.offset(e)},replaceArrow:function(e,t,n){this.arrow().css(n,e?50*(1-e/t)+"%":"")},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function i(){var t=setTimeout(function(){n.off(e.support.transition.end).detach()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.detach()})}var t=this,n=this.tip(),r=e.Event("hide");this.$element.trigger(r);if(r.isDefaultPrevented())return;return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?i():n.detach(),this.$element.trigger("hidden"),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").attr("title","")},hasContent:function(){return this.getTitle()},getPosition:function(){var t=this.$element[0];return e.extend({},typeof t.getBoundingClientRect=="function"?t.getBoundingClientRect():{width:t.offsetWidth,height:t.offsetHeight},this.$element.offset())},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},arrow:function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(t){var n=t?e(t.currentTarget)[this.type](this._options).data(this.type):this;n.tip().hasClass("in")?n.hide():n.show()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var n=e.fn.tooltip;e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},e.fn.tooltip.noConflict=function(){return e.fn.tooltip=n,this}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=(typeof n.content=="function"?n.content.call(t[0]):n.content)||t.attr("data-content"),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var n=e.fn.popover;e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'

'}),e.fn.popover.noConflict=function(){return e.fn.popover=n,this}}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var n=e(this),r=n.data("target")||n.attr("href"),i=/^#\w/.test(r)&&e(r);return i&&i.length&&[[i.position().top+(!e.isWindow(t.$scrollElement.get(0))&&t.$scrollElement.scrollTop()),r]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}};var n=e.fn.scrollspy;e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e.fn.scrollspy.noConflict=function(){return e.fn.scrollspy=n,this},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active:last a")[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}};var n=e.fn.tab;e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e.fn.tab.noConflict=function(){return e.fn.tab=n,this},e(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=e(this.options.menu),this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:t.top+t.height,left:t.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length"+t+""})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("focus",e.proxy(this.focus,this)).on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this)).on("mouseleave","li",e.proxy(this.mouseleave,this))},eventSupported:function(e){var t=e in this.$element;return t||(this.$element.setAttribute(e,"return;"),t=typeof this.$element[e]=="function"),t},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},focus:function(e){this.focused=!0},blur:function(e){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(e){e.stopPropagation(),e.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(t){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")},mouseleave:function(e){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var n=e.fn.typeahead;e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'',item:'
  • ',minLength:1},e.fn.typeahead.Constructor=t,e.fn.typeahead.noConflict=function(){return e.fn.typeahead=n,this},e(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;n.typeahead(n.data())})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)).on("click.affix.data-api",e.proxy(function(){setTimeout(e.proxy(this.checkPosition,this),1)},this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))};var n=e.fn.affix;e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e.fn.affix.noConflict=function(){return e.fn.affix=n,this},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery); \ No newline at end of file diff -Nru django-guardian-1.3.2/example_project/templates/403.html django-guardian-1.4.1/example_project/templates/403.html --- django-guardian-1.3.2/example_project/templates/403.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/templates/403.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -{% extends "base.html" %} - -{% block title %}403 - Permission denied{% endblock %} - -{% block content %} -
    -
    -
    -
    -

    403

    -

    Permission Denied

    -
    -
    -
    -
    -{% endblock %} - diff -Nru django-guardian-1.3.2/example_project/templates/404.html django-guardian-1.4.1/example_project/templates/404.html --- django-guardian-1.3.2/example_project/templates/404.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/templates/404.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -{% extends "base.html" %} - -{% block title %}404 - Page does not exist{% endblock %} - -{% block content %} -
    -
    -
    -
    -

    404

    -

    Page does not exist

    -
    -
    -
    -
    -{% endblock %} - - diff -Nru django-guardian-1.3.2/example_project/templates/500.html django-guardian-1.4.1/example_project/templates/500.html --- django-guardian-1.3.2/example_project/templates/500.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/templates/500.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ - - - - Page unavailable - - - -

    Page unavailable

    - -

    Sorry, but the requested page is unavailable due to a - server hiccup.

    - -

    Our engineers have been notified, so check back later.

    - - - diff -Nru django-guardian-1.3.2/example_project/templates/base.html django-guardian-1.4.1/example_project/templates/base.html --- django-guardian-1.3.2/example_project/templates/base.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/templates/base.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ - - - - {% block title %}Guardian example{% endblock %} - - - - - - - {% block navbar %} - - {% endblock %} -
    - {% block content %} -
    -
    -

    Hello, world!

    -
    -
    - {% endblock %} -
    - - - - - - diff -Nru django-guardian-1.3.2/example_project/templates/home.html django-guardian-1.4.1/example_project/templates/home.html --- django-guardian-1.3.2/example_project/templates/home.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/templates/home.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -{% extends "base_1col.html" %} - -{% block col-single-title %}Home{% endblock %} - -{% block col-single-content %} -
    -

    Pages

    - -
    -{% endblock %} - diff -Nru django-guardian-1.3.2/example_project/urls.py django-guardian-1.4.1/example_project/urls.py --- django-guardian-1.3.2/example_project/urls.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/example_project/urls.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -from guardian.compat import include, url, patterns, handler404, handler500 -from django.conf import settings -from django.contrib import admin - -__all__ = ['handler404', 'handler500'] - - -admin.autodiscover() - -urlpatterns = patterns('', - (r'^admin/', include(admin.site.urls)), - url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}, - name='logout'), - (r'^', include('example_project.posts.urls')), -) - -if 'grappelli' in settings.INSTALLED_APPS: - urlpatterns += patterns('', - (r'^grappelli/', include('grappelli.urls')), - ) - -if 'rosetta' in settings.INSTALLED_APPS: - urlpatterns = patterns('', - url(r'^rosetta/', include('rosetta.urls')), - ) + urlpatterns diff -Nru django-guardian-1.3.2/guardian/admin.py django-guardian-1.4.1/guardian/admin.py --- django-guardian-1.3.2/guardian/admin.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/admin.py 2016-01-08 08:13:40.000000000 +0000 @@ -1,9 +1,8 @@ from __future__ import unicode_literals -import django from django import forms from django.conf import settings -from guardian.compat import url, patterns +from guardian.compat import url from django.contrib import admin from django.contrib import messages from django.contrib.admin.widgets import FilteredSelectMultiple @@ -82,12 +81,6 @@ qs = qs.filter(**filters) return qs - # Allow queryset method as fallback for Django versions < 1.6 - # for versions >= 1.6 this is taken care of by Django itself - # and triggers a warning message automatically. - if django.VERSION < (1, 6): - queryset = get_queryset - def get_urls(self): """ Extends standard admin model urls with the following: @@ -104,19 +97,17 @@ urls = super(GuardedModelAdminMixin, self).get_urls() if self.include_object_permissions_urls: info = self.model._meta.app_label, get_model_name(self.model) - myurls = patterns('', - url(r'^(?P.+)/permissions/$', - view=self.admin_site.admin_view(self.obj_perms_manage_view), - name='%s_%s_permissions' % info), - url(r'^(?P.+)/permissions/user-manage/(?P\-?\d+)/$', - view=self.admin_site.admin_view( - self.obj_perms_manage_user_view), - name='%s_%s_permissions_manage_user' % info), - url(r'^(?P.+)/permissions/group-manage/(?P\-?\d+)/$', - view=self.admin_site.admin_view( - self.obj_perms_manage_group_view), - name='%s_%s_permissions_manage_group' % info), - ) + myurls = [ + url(r'^(?P.+)/permissions/$', + view=self.admin_site.admin_view(self.obj_perms_manage_view), + name='%s_%s_permissions' % info), + url(r'^(?P.+)/permissions/user-manage/(?P\-?\d+)/$', + view=self.admin_site.admin_view(self.obj_perms_manage_user_view), + name='%s_%s_permissions_manage_user' % info), + url(r'^(?P.+)/permissions/group-manage/(?P\-?\d+)/$', + view=self.admin_site.admin_view(self.obj_perms_manage_group_view), + name='%s_%s_permissions_manage_group' % info), + ] urls = myurls + urls return urls @@ -131,8 +122,7 @@ 'object': obj, 'app_label': self.model._meta.app_label, 'opts': self.model._meta, - 'original': hasattr(obj, '__unicode__') and obj.__unicode__() or\ - str(obj), + 'original': hasattr(obj, '__unicode__') and obj.__unicode__() or str(obj), 'has_change_permission': self.has_change_permission(request, obj), 'model_perms': get_perms_for_model(obj), 'title': _("Object permissions"), @@ -147,6 +137,10 @@ shown. In order to add or manage user or group one should use links or forms presented within the page. """ + if not self.has_change_permission(request, None): + post_url = reverse('admin:index', current_app=self.admin_site.name) + return redirect(post_url) + try: # django >= 1.7 from django.contrib.admin.utils import unquote @@ -208,8 +202,10 @@ context['user_form'] = user_form context['group_form'] = group_form - return render_to_response(self.get_obj_perms_manage_template(), - context, RequestContext(request, current_app=self.admin_site.name)) + # https://github.com/django/django/commit/cf1f36bb6eb34fafe6c224003ad585a647f6117b + request.current_app = self.admin_site.name + + return render_to_response(self.get_obj_perms_manage_template(), context, RequestContext(request)) def get_obj_perms_manage_template(self): """ @@ -229,6 +225,10 @@ """ Manages selected users' permissions for current object. """ + if not self.has_change_permission(request, None): + post_url = reverse('admin:index', current_app=self.admin_site.name) + return redirect(post_url) + user = get_object_or_404(get_user_model(), pk=user_id) obj = get_object_or_404(self.get_queryset(request), pk=object_pk) form_class = self.get_obj_perms_manage_user_form() @@ -254,8 +254,9 @@ context['user_perms'] = get_perms(user, obj) context['form'] = form - return render_to_response(self.get_obj_perms_manage_user_template(), - context, RequestContext(request, current_app=self.admin_site.name)) + request.current_app = self.admin_site.name + + return render_to_response(self.get_obj_perms_manage_user_template(), context, RequestContext(request)) def get_obj_perms_manage_user_template(self): """ @@ -282,6 +283,10 @@ """ Manages selected groups' permissions for current object. """ + if not self.has_change_permission(request, None): + post_url = reverse('admin:index', current_app=self.admin_site.name) + return redirect(post_url) + group = get_object_or_404(Group, id=group_id) obj = get_object_or_404(self.get_queryset(request), pk=object_pk) form_class = self.get_obj_perms_manage_group_form() @@ -307,8 +312,9 @@ context['group_perms'] = get_perms(group, obj) context['form'] = form - return render_to_response(self.get_obj_perms_manage_group_template(), - context, RequestContext(request, current_app=self.admin_site.name)) + request.current_app = self.admin_site.name + + return render_to_response(self.get_obj_perms_manage_group_template(), context, RequestContext(request)) def get_obj_perms_manage_group_template(self): """ @@ -414,10 +420,10 @@ class UserManage(forms.Form): user = forms.CharField(label=_("User identification"), - max_length=200, - error_messages = {'does_not_exist': _("This user does not exist")}, - help_text=_('Enter a value compatible with User.USERNAME_FIELD') - ) + max_length=200, + error_messages={'does_not_exist': _("This user does not exist")}, + help_text=_('Enter a value compatible with User.USERNAME_FIELD') + ) def clean_user(self): """ @@ -439,7 +445,7 @@ class GroupManage(forms.Form): group = forms.CharField(max_length=80, error_messages={'does_not_exist': - _("This group does not exist")}) + _("This group does not exist")}) def clean_group(self): """ @@ -452,4 +458,3 @@ except Group.DoesNotExist: raise forms.ValidationError( self.fields['group'].error_messages['does_not_exist']) - diff -Nru django-guardian-1.3.2/guardian/apps.py django-guardian-1.4.1/guardian/apps.py --- django-guardian-1.3.2/guardian/apps.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/apps.py 2015-12-18 05:08:22.000000000 +0000 @@ -10,4 +10,3 @@ def ready(self): if settings.MONKEY_PATCH: monkey_patch_user() - diff -Nru django-guardian-1.3.2/guardian/checks.py django-guardian-1.4.1/guardian/checks.py --- django-guardian-1.3.2/guardian/checks.py 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/guardian/checks.py 2015-12-18 05:08:22.000000000 +0000 @@ -0,0 +1,24 @@ + +from django.core.checks import register, Tags, Warning +from django.conf import settings + + +# noinspection PyUnusedLocal +@register(Tags.compatibility) +def check_settings(app_configs, **kwargs): + """ Check that settings are implemented properly + :param app_configs: a list of apps to be checks or None for all + :param kwargs: keyword arguments + :return: a list of errors + """ + checks = [] + if 'guardian.backends.ObjectPermissionBackend' not in settings.AUTHENTICATION_BACKENDS: + msg = ("Guardian authentication backend is not hooked. You can add this in settings as eg: " + "`AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', " + "'guardian.backends.ObjectPermissionBackend')`.") + checks.append(Warning(msg, id='guardian.W001')) + if not settings.ANONYMOUS_USER_ID: + msg = ("No anonymous user ID is defined. Guardian supports anonymous user object permissions, therefore " + "this needs to be specified in settings: `ANONYMOUS_USER_ID = -1`.") + checks.append(Warning(msg, id='guardian.W002')) + return checks diff -Nru django-guardian-1.3.2/guardian/compat.py django-guardian-1.4.1/guardian/compat.py --- django-guardian-1.3.2/guardian/compat.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/compat.py 2015-12-18 05:08:22.000000000 +0000 @@ -8,15 +8,9 @@ import six import sys -try: - from importlib import import_module -except ImportError: - from django.utils.importlib import import_module +from importlib import import_module -try: - from django.conf.urls import url, patterns, include, handler404, handler500 -except ImportError: - from django.conf.urls.defaults import url, patterns, include, handler404, handler500 # pyflakes:ignore +from django.conf.urls import url, patterns, include, handler404, handler500 __all__ = [ 'User', @@ -43,7 +37,7 @@ from unittest import mock # Since Python 3.3 mock is is in stdlib except ImportError: try: - import mock # pyflakes:ignore + import mock # pyflakes:ignore except ImportError: # mock is used for tests only however it is hard to check if user is # running tests or production code so we fail silently here; mock is @@ -63,6 +57,7 @@ from django.contrib.auth.models import User get_user_model = lambda: User + def get_user_model_path(): """ Returns 'app_label.ModelName' for User model. Basically if @@ -71,6 +66,7 @@ """ return getattr(settings, 'AUTH_USER_MODEL', 'auth.User') + def get_user_permission_full_codename(perm): """ Returns 'app_label._'. If standard ``auth.User`` is @@ -78,12 +74,10 @@ ``myapp.CustomUser`` is used it would return ``myapp.change_customuser``. """ User = get_user_model() - if django.VERSION < (1, 7): - model_name = User._meta.module_name - else: - model_name = User._meta.model_name + model_name = User._meta.model_name return '%s.%s_%s' % (User._meta.app_label, perm, model_name) + def get_user_permission_codename(perm): """ Returns '_'. If standard ``auth.User`` is @@ -118,9 +112,9 @@ # Python 3 try: - unicode = unicode # pyflakes:ignore - basestring = basestring # pyflakes:ignore - str = str # pyflakes:ignore + unicode = unicode # pyflakes:ignore + basestring = basestring # pyflakes:ignore + str = str # pyflakes:ignore except NameError: basestring = unicode = str = str @@ -128,23 +122,17 @@ # OrderedDict only available in Python 2.7. # This will always be the case in Django 1.7 and above, as these versions # no longer support Python 2.6. -# For Django <= 1.6 and Python 2.6 fall back to SortedDict. -try: - from collections import OrderedDict -except ImportError: - from django.utils.datastructures import SortedDict as OrderedDict +from collections import OrderedDict # Django 1.7 compatibility # create_permission API changed: skip the create_models (second # positional argument) if we have django 1.7+ and 2+ positional -# arguments with the second one being a list/tuple +# arguments with the second one being a list/tuple def create_permissions(*args, **kwargs): from django.contrib.auth.management import create_permissions as original_create_permissions - import django - if django.get_version().split('.')[:2] >= ['1','7'] and \ - len(args) > 1 and isinstance(args[1], (list, tuple)): + if len(args) > 1 and isinstance(args[1], (list, tuple)): args = args[:1] + args[2:] return original_create_permissions(*args, **kwargs) @@ -157,6 +145,4 @@ """ # model._meta.module_name is deprecated in django version 1.7 and removed in django version 1.8. # It is replaced by model._meta.model_name - if django.VERSION < (1, 7): - return model._meta.module_name return model._meta.model_name diff -Nru django-guardian-1.3.2/guardian/decorators.py django-guardian-1.4.1/guardian/decorators.py --- django-guardian-1.3.2/guardian/decorators.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/decorators.py 2015-12-18 05:08:22.000000000 +0000 @@ -4,13 +4,7 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.utils.functional import wraps from django.db.models import Model -try: - # django >= 1.7 - from django.apps import apps - get_model = apps.get_model -except ImportError: - # django < 1.7 - from django.db.models import get_model +from django.apps import apps from django.db.models.base import ModelBase from django.db.models.query import QuerySet from django.shortcuts import get_object_or_404 @@ -100,7 +94,7 @@ if len(splitted) != 2: raise GuardianError("If model should be looked up from " "string it needs format: 'app_label.ModelClass'") - model = get_model(*splitted) + model = apps.get_model(*splitted) elif issubclass(model.__class__, (Model, ModelBase, QuerySet)): pass else: diff -Nru django-guardian-1.3.2/guardian/__init__.py django-guardian-1.4.1/guardian/__init__.py --- django-guardian-1.3.2/guardian/__init__.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/__init__.py 2016-01-09 22:41:23.000000000 +0000 @@ -1,12 +1,14 @@ """ -Implementation of per object permissions for Django 1.2 or later. +Implementation of per object permissions for Django. """ from __future__ import unicode_literals +from . import checks -VERSION = (1, 3, 2) +VERSION = (1, 4, 1) __version__ = '.'.join((str(each) for each in VERSION[:4])) + def get_version(): """ Returns shorter version (digit parts only) as string. @@ -25,7 +27,6 @@ # Prototype User and Group methods setattr(User, 'get_anonymous', staticmethod(lambda: get_anonymous_user())) setattr(User, 'add_obj_perm', - lambda self, perm, obj: UserObjectPermission.objects.assign_perm(perm, self, obj)) + lambda self, perm, obj: UserObjectPermission.objects.assign_perm(perm, self, obj)) setattr(User, 'del_obj_perm', - lambda self, perm, obj: UserObjectPermission.objects.remove_perm(perm, self, obj)) - + lambda self, perm, obj: UserObjectPermission.objects.remove_perm(perm, self, obj)) diff -Nru django-guardian-1.3.2/guardian/management/__init__.py django-guardian-1.4.1/guardian/management/__init__.py --- django-guardian-1.3.2/guardian/management/__init__.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/management/__init__.py 2015-12-18 05:08:22.000000000 +0000 @@ -40,14 +40,8 @@ # Only create an anonymous user if support is enabled. if guardian_settings.ANONYMOUS_USER_ID is not None: - if django.VERSION >= (1, 7): - # Django 1.7+ uses post_migrate signal - from django.apps import apps - guardian_app = apps.get_app_config('guardian') - signals.post_migrate.connect(create_anonymous_user, sender=guardian_app, - dispatch_uid="guardian.management.create_anonymous_user") - else: - # Django 1.6 and earlier uses post_syncdb signal - from guardian import models as guardian_app - signals.post_syncdb.connect(create_anonymous_user, sender=guardian_app, - dispatch_uid="guardian.management.create_anonymous_user") + # Django 1.7+ uses post_migrate signal + from django.apps import apps + guardian_app = apps.get_app_config('guardian') + signals.post_migrate.connect(create_anonymous_user, sender=guardian_app, + dispatch_uid="guardian.management.create_anonymous_user") diff -Nru django-guardian-1.3.2/guardian/mixins.py django-guardian-1.4.1/guardian/mixins.py --- django-guardian-1.3.2/guardian/mixins.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/mixins.py 2015-12-18 07:07:48.000000000 +0000 @@ -118,6 +118,7 @@ *Default*: ``False``, If accept_global_perms would be set to True, then mixing would first check for global perms, if none found, then it will proceed to check object level permissions. + ``PermissionRequiredMixin.permission_object`` *Default*: ``None``, object against which test the permission; if None fallback to ``self.get_permission_object()`` which return ``self.get_object()`` diff -Nru django-guardian-1.3.2/guardian/models.py django-guardian-1.4.1/guardian/models.py --- django-guardian-1.3.2/guardian/models.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/models.py 2015-12-18 05:08:22.000000000 +0000 @@ -90,13 +90,6 @@ unique_together = ['group', 'permission', 'object_pk'] -# As with Django 1.7, you can't use the get_user_model at this point -# because the app registry isn't ready yet (we're inside a model file). -import django -if django.VERSION < (1, 7) and settings.MONKEY_PATCH: - from . import monkey_patch_user - monkey_patch_user() - setattr(Group, 'add_obj_perm', lambda self, perm, obj: GroupObjectPermission.objects.assign_perm(perm, self, obj)) setattr(Group, 'del_obj_perm', diff -Nru django-guardian-1.3.2/guardian/shortcuts.py django-guardian-1.4.1/guardian/shortcuts.py --- django-guardian-1.3.2/guardian/shortcuts.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/shortcuts.py 2016-01-08 08:13:40.000000000 +0000 @@ -6,15 +6,8 @@ from django.contrib.auth.models import Group from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType -from django.db import models from django.db.models import Count, Q -try: - # django >= 1.7 - from django.apps import apps - get_model = apps.get_model -except ImportError: - # django < 1.7 - from django.db.models import get_model +from django.apps import apps from django.shortcuts import _get_queryset from itertools import groupby @@ -159,7 +152,7 @@ """ if isinstance(cls, basestring): app_label, model_name = cls.split('.') - model = get_model(app_label, model_name) + model = apps.get_model(app_label, model_name) else: model = cls ctype = ContentType.objects.get_for_model(model) @@ -313,8 +306,10 @@ :param use_groups: if ``False``, wouldn't check user's groups object permissions. Default is ``True``. :param any_perm: if True, any of permission in sequence is accepted. Default is ``False``. - :param with_superuser: if ``True`` returns the entire queryset if not it will - only return objects the user has explicit permissions. Default is ``True``. + :param with_superuser: if ``True`` and if ``user.is_superuser`` is set, + returns the entire queryset. Otherwise will only return objects the user + has explicit permissions. This must be ``True`` for the accept_global_perms + parameter to have any affect. Default is ``True``. :param accept_global_perms: if ``True`` takes global permissions into account. Object based permissions are taken into account if more than one permission is handed in in perms and at least one of these perms is not globally set. If any_perm is set to false then the intersection of matching object @@ -351,6 +346,7 @@ [] Take global permissions into account: + >>> jack = User.objects.get(username='jack') >>> assign_perm('auth.change_group', jack) # this will set a global permission >>> get_objects_for_user(jack, 'auth.change_group') @@ -362,6 +358,35 @@ >>> get_objects_for_user(jack, ['auth.change_group', 'auth.delete_group'], any_perm) # this retrieves union [, ] + If accept_global_perms is set to ``True``, then all assigned global + permissions will also be taken into account. + + - Scenario 1: a user has view permissions generally defined on the model + 'books' but no object based permission on a single book instance: + + - If accept_global_perms is ``True``: List of all books will be + returned. + - If accept_global_perms is ``False``: list will be empty. + + - Scenario 2: a user has view permissions generally defined on the model + 'books' and also has an object based permission to view book 'Whatever': + + - If accept_global_perms is ``True``: List of all books will be + returned. + - If accept_global_perms is ``False``: list will only contain book + 'Whatever'. + + - Scenario 3: a user only has object based permission on book 'Whatever': + + - If accept_global_perms is ``True``: List will only contain book + 'Whatever'. + - If accept_global_perms is ``False``: List will only contain book + 'Whatever'. + + - Scenario 4: a user does not have any permission: + + - If accept_global_perms is ``True``: Empty list. + - If accept_global_perms is ``False``: Empty list. """ if isinstance(perms, basestring): perms = [perms] @@ -490,11 +515,17 @@ counts = user_obj_perms_queryset.values(fields[0]).annotate(object_pk_count=Count(fields[0])) user_obj_perms_queryset = counts.filter(object_pk_count__gte=len(codenames)) - q = Q(pk__in=user_obj_perms_queryset.values(fields[0])) + values = user_obj_perms_queryset.values_list(fields[0], flat=True) + if user_model.objects.is_generic(): + values = list(values) + objects = queryset.filter(pk__in=values) if use_groups: - q |= Q(pk__in=groups_obj_perms_queryset.values(fields[0])) + values = groups_obj_perms_queryset.values_list(fields[0], flat=True) + if group_model.objects.is_generic(): + values = list(values) + objects |= queryset.filter(pk__in=values) - return queryset.filter(q) + return objects def get_objects_for_group(group, perms, klass=None, any_perm=False, accept_global_perms=True): diff -Nru django-guardian-1.3.2/guardian/south_migrations/0001_initial.py django-guardian-1.4.1/guardian/south_migrations/0001_initial.py --- django-guardian-1.3.2/guardian/south_migrations/0001_initial.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/south_migrations/0001_initial.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -# encoding: utf-8 -from south.db import db -from south.v2 import SchemaMigration - -from guardian.compat import user_model_label -from guardian.compat import get_user_model - -User = get_user_model() - - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding model 'UserObjectPermission' - db.create_table('guardian_userobjectpermission', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('permission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Permission'])), - ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), - ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm[user_model_label])), - )) - db.send_create_signal('guardian', ['UserObjectPermission']) - - # Adding unique constraint on 'UserObjectPermission', fields ['user', 'permission', 'content_type', 'object_id'] - db.create_unique('guardian_userobjectpermission', ['user_id', 'permission_id', 'content_type_id', 'object_id']) - - # Adding model 'GroupObjectPermission' - db.create_table('guardian_groupobjectpermission', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('permission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Permission'])), - ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), - ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()), - ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Group'])), - )) - db.send_create_signal('guardian', ['GroupObjectPermission']) - - # Adding unique constraint on 'GroupObjectPermission', fields ['group', 'permission', 'content_type', 'object_id'] - db.create_unique('guardian_groupobjectpermission', ['group_id', 'permission_id', 'content_type_id', 'object_id']) - - - def backwards(self, orm): - - # Removing unique constraint on 'GroupObjectPermission', fields ['group', 'permission', 'content_type', 'object_id'] - db.delete_unique('guardian_groupobjectpermission', ['group_id', 'permission_id', 'content_type_id', 'object_id']) - - # Removing unique constraint on 'UserObjectPermission', fields ['user', 'permission', 'content_type', 'object_id'] - db.delete_unique('guardian_userobjectpermission', ['user_id', 'permission_id', 'content_type_id', 'object_id']) - - # Deleting model 'UserObjectPermission' - db.delete_table('guardian_userobjectpermission') - - # Deleting model 'GroupObjectPermission' - db.delete_table('guardian_groupobjectpermission') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - user_model_label: { - 'Meta': {'object_name': user_model_label.split('.')[-1], 'db_table': "'%s'" % User._meta.db_table}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'guardian.groupobjectpermission': { - 'Meta': {'unique_together': "(['group', 'permission', 'content_type', 'object_id'],)", 'object_name': 'GroupObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}) - }, - 'guardian.userobjectpermission': { - 'Meta': {'unique_together': "(['user', 'permission', 'content_type', 'object_id'],)", 'object_name': 'UserObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_model_label}) - } - } - - complete_apps = ['guardian'] diff -Nru django-guardian-1.3.2/guardian/south_migrations/0002_auto__add_field_groupobjectpermission_object_pk__add_field_userobjectp.py django-guardian-1.4.1/guardian/south_migrations/0002_auto__add_field_groupobjectpermission_object_pk__add_field_userobjectp.py --- django-guardian-1.3.2/guardian/south_migrations/0002_auto__add_field_groupobjectpermission_object_pk__add_field_userobjectp.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/south_migrations/0002_auto__add_field_groupobjectpermission_object_pk__add_field_userobjectp.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -# encoding: utf-8 -from south.db import db -from south.v2 import SchemaMigration - -from guardian.compat import user_model_label - - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding field 'GroupObjectPermission.object_pk' - db.add_column('guardian_groupobjectpermission', 'object_pk', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False) - - # Adding field 'UserObjectPermission.object_pk' - db.add_column('guardian_userobjectpermission', 'object_pk', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False) - - - def backwards(self, orm): - - # Deleting field 'GroupObjectPermission.object_pk' - db.delete_column('guardian_groupobjectpermission', 'object_pk') - - # Deleting field 'UserObjectPermission.object_pk' - db.delete_column('guardian_userobjectpermission', 'object_pk') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - user_model_label: { - 'Meta': {'object_name': user_model_label.split('.')[-1]}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'guardian.groupobjectpermission': { - 'Meta': {'unique_together': "(['group', 'permission', 'content_type', 'object_id'],)", 'object_name': 'GroupObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'object_pk': ('django.db.models.fields.TextField', [], {'default': "''"}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}) - }, - 'guardian.userobjectpermission': { - 'Meta': {'unique_together': "(['user', 'permission', 'content_type', 'object_id'],)", 'object_name': 'UserObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'object_pk': ('django.db.models.fields.TextField', [], {'default': "''"}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_model_label}) - } - } - - complete_apps = ['guardian'] diff -Nru django-guardian-1.3.2/guardian/south_migrations/0003_update_objectpermission_object_pk.py django-guardian-1.4.1/guardian/south_migrations/0003_update_objectpermission_object_pk.py --- django-guardian-1.3.2/guardian/south_migrations/0003_update_objectpermission_object_pk.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/south_migrations/0003_update_objectpermission_object_pk.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -# encoding: utf-8 -from south.v2 import DataMigration - -from guardian.compat import user_model_label - - -class Migration(DataMigration): - - def forwards(self, orm): - """ - Updates ``object_pk`` fields on both ``UserObjectPermission`` and - ``GroupObjectPermission`` from ``object_id`` values. - """ - for Model in [orm.UserObjectPermission, orm.GroupObjectPermission]: - for obj in Model.objects.all(): - obj.object_pk = str(obj.object_id) - obj.save() - - def backwards(self, orm): - """ - Updates ``object_id`` fields on both ``UserObjectPermission`` and - ``GroupObjectPermission`` from ``object_pk`` values. - """ - for Model in [orm.UserObjectPermission, orm.GroupObjectPermission]: - for obj in Model.objects.all(): - obj.object_id = int(obj.object_pk) - obj.save() - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - user_model_label: { - 'Meta': {'object_name': user_model_label.split('.')[-1]}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'guardian.groupobjectpermission': { - 'Meta': {'unique_together': "(['group', 'permission', 'content_type', 'object_id'],)", 'object_name': 'GroupObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'object_pk': ('django.db.models.fields.TextField', [], {'default': "''"}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}) - }, - 'guardian.userobjectpermission': { - 'Meta': {'unique_together': "(['user', 'permission', 'content_type', 'object_id'],)", 'object_name': 'UserObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'object_pk': ('django.db.models.fields.TextField', [], {'default': "''"}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_model_label}) - } - } - - complete_apps = ['guardian'] diff -Nru django-guardian-1.3.2/guardian/south_migrations/0004_auto__del_field_groupobjectpermission_object_id__del_unique_groupobjec.py django-guardian-1.4.1/guardian/south_migrations/0004_auto__del_field_groupobjectpermission_object_id__del_unique_groupobjec.py --- django-guardian-1.3.2/guardian/south_migrations/0004_auto__del_field_groupobjectpermission_object_id__del_unique_groupobjec.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/south_migrations/0004_auto__del_field_groupobjectpermission_object_id__del_unique_groupobjec.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -# encoding: utf-8 -from south.db import db -from south.v2 import SchemaMigration - -from guardian.compat import user_model_label - - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Changing field 'GroupObjectPermission.object_pk' - db.alter_column('guardian_groupobjectpermission', 'object_pk', self.gf('django.db.models.fields.CharField')(max_length=255)) - - # Changing field 'UserObjectPermission.object_pk' - db.alter_column('guardian_userobjectpermission', 'object_pk', self.gf('django.db.models.fields.CharField')(max_length=255)) - - # Removing unique constraint on 'UserObjectPermission', fields ['object_id', 'user', 'content_type', 'permission'] - db.delete_unique('guardian_userobjectpermission', ['object_id', 'user_id', 'content_type_id', 'permission_id']) - - # Removing unique constraint on 'GroupObjectPermission', fields ['group', 'object_id', 'content_type', 'permission'] - db.delete_unique('guardian_groupobjectpermission', ['group_id', 'object_id', 'content_type_id', 'permission_id']) - - # Adding unique constraint on 'GroupObjectPermission', fields ['object_pk', 'group', 'content_type', 'permission'] - db.create_unique('guardian_groupobjectpermission', ['object_pk', 'group_id', 'content_type_id', 'permission_id']) - - # Adding unique constraint on 'UserObjectPermission', fields ['object_pk', 'user', 'content_type', 'permission'] - db.create_unique('guardian_userobjectpermission', ['object_pk', 'user_id', 'content_type_id', 'permission_id']) - - - def backwards(self, orm): - - # Changing field 'GroupObjectPermission.object_pk' - db.alter_column('guardian_groupobjectpermission', 'object_pk', self.gf('django.db.models.fields.TextField')()) - - # Changing field 'UserObjectPermission.object_pk' - db.alter_column('guardian_userobjectpermission', 'object_pk', self.gf('django.db.models.fields.TextField')()) - - # Removing unique constraint on 'UserObjectPermission', fields ['object_pk', 'user', 'content_type', 'permission'] - db.delete_unique('guardian_userobjectpermission', ['object_pk', 'user_id', 'content_type_id', 'permission_id']) - - # Removing unique constraint on 'GroupObjectPermission', fields ['object_pk', 'group', 'content_type', 'permission'] - db.delete_unique('guardian_groupobjectpermission', ['object_pk', 'group_id', 'content_type_id', 'permission_id']) - - # Adding unique constraint on 'GroupObjectPermission', fields ['group', 'object_id', 'content_type', 'permission'] - db.create_unique('guardian_groupobjectpermission', ['group_id', 'object_id', 'content_type_id', 'permission_id']) - - # Adding unique constraint on 'UserObjectPermission', fields ['object_id', 'user', 'content_type', 'permission'] - db.create_unique('guardian_userobjectpermission', ['object_id', 'user_id', 'content_type_id', 'permission_id']) - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - user_model_label: { - 'Meta': {'object_name': user_model_label.split('.')[-1]}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'guardian.groupobjectpermission': { - 'Meta': {'unique_together': "(['group', 'permission', 'content_type', 'object_pk'],)", 'object_name': 'GroupObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_pk': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}) - }, - 'guardian.userobjectpermission': { - 'Meta': {'unique_together': "(['user', 'permission', 'content_type', 'object_pk'],)", 'object_name': 'UserObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_pk': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_model_label}) - } - } - - complete_apps = ['guardian'] diff -Nru django-guardian-1.3.2/guardian/south_migrations/0005_auto__chg_field_groupobjectpermission_object_pk__chg_field_userobjectp.py django-guardian-1.4.1/guardian/south_migrations/0005_auto__chg_field_groupobjectpermission_object_pk__chg_field_userobjectp.py --- django-guardian-1.3.2/guardian/south_migrations/0005_auto__chg_field_groupobjectpermission_object_pk__chg_field_userobjectp.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/south_migrations/0005_auto__chg_field_groupobjectpermission_object_pk__chg_field_userobjectp.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -# encoding: utf-8 -from south.db import db -from south.v2 import SchemaMigration - -from guardian.compat import user_model_label - - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Deleting field 'GroupObjectPermission.object_id' - db.delete_column('guardian_groupobjectpermission', 'object_id') - - # Deleting field 'UserObjectPermission.object_id' - db.delete_column('guardian_userobjectpermission', 'object_id') - - - def backwards(self, orm): - - # We cannot add back in field 'GroupObjectPermission.object_id' - raise RuntimeError( - "Cannot reverse this migration. 'GroupObjectPermission.object_id' and its values cannot be restored.") - - # We cannot add back in field 'UserObjectPermission.object_id' - raise RuntimeError( - "Cannot reverse this migration. 'UserObjectPermission.object_id' and its values cannot be restored.") - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - user_model_label: { - 'Meta': {'object_name': user_model_label.split('.')[-1]}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'guardian.groupobjectpermission': { - 'Meta': {'unique_together': "(['group', 'permission', 'content_type', 'object_pk'],)", 'object_name': 'GroupObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_pk': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}) - }, - 'guardian.userobjectpermission': { - 'Meta': {'unique_together': "(['user', 'permission', 'content_type', 'object_pk'],)", 'object_name': 'UserObjectPermission'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_pk': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Permission']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_model_label}) - } - } - - complete_apps = ['guardian'] diff -Nru django-guardian-1.3.2/guardian/static/guardian/img/icon-no.svg django-guardian-1.4.1/guardian/static/guardian/img/icon-no.svg --- django-guardian-1.3.2/guardian/static/guardian/img/icon-no.svg 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/guardian/static/guardian/img/icon-no.svg 2015-12-18 05:08:22.000000000 +0000 @@ -0,0 +1,3 @@ + + + diff -Nru django-guardian-1.3.2/guardian/static/guardian/img/icon-yes.svg django-guardian-1.4.1/guardian/static/guardian/img/icon-yes.svg --- django-guardian-1.3.2/guardian/static/guardian/img/icon-yes.svg 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/guardian/static/guardian/img/icon-yes.svg 2015-12-18 05:08:22.000000000 +0000 @@ -0,0 +1,3 @@ + + + diff -Nru django-guardian-1.3.2/guardian/templates/admin/guardian/contrib/grappelli/obj_perms_manage.html django-guardian-1.4.1/guardian/templates/admin/guardian/contrib/grappelli/obj_perms_manage.html --- django-guardian-1.3.2/guardian/templates/admin/guardian/contrib/grappelli/obj_perms_manage.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/templates/admin/guardian/contrib/grappelli/obj_perms_manage.html 2015-12-18 05:08:22.000000000 +0000 @@ -44,9 +44,9 @@ {% for perm in model_perms %} {% if perm.codename in user_perms %} - + {% else %} - + {% endif %} {% endfor %} @@ -105,9 +105,9 @@ {% for perm in model_perms %} {% if perm.codename in group_perms %} - + {% else %} - + {% endif %} {% endfor %} diff -Nru django-guardian-1.3.2/guardian/templates/admin/guardian/model/change_form.html django-guardian-1.4.1/guardian/templates/admin/guardian/model/change_form.html --- django-guardian-1.3.2/guardian/templates/admin/guardian/model/change_form.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/templates/admin/guardian/model/change_form.html 2015-12-18 05:08:22.000000000 +0000 @@ -1,7 +1,8 @@ {% extends "admin/change_form.html" %} -{% load i18n %} +{% load i18n admin_urls %} {% block object-tools-items %} -
  • {% trans "Object permissions" %}
  • +{% url opts|admin_urlname:'permissions' original.pk|admin_urlquote as history_url %} +
  • {% trans "Object permissions" %}
  • {{ block.super }} {% endblock %} diff -Nru django-guardian-1.3.2/guardian/templates/admin/guardian/model/obj_perms_no.html django-guardian-1.4.1/guardian/templates/admin/guardian/model/obj_perms_no.html --- django-guardian-1.3.2/guardian/templates/admin/guardian/model/obj_perms_no.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/templates/admin/guardian/model/obj_perms_no.html 2015-12-18 05:08:22.000000000 +0000 @@ -1,3 +1,3 @@ {% load guardian_tags %} {% load staticfiles %} - + diff -Nru django-guardian-1.3.2/guardian/templates/admin/guardian/model/obj_perms_yes.html django-guardian-1.4.1/guardian/templates/admin/guardian/model/obj_perms_yes.html --- django-guardian-1.3.2/guardian/templates/admin/guardian/model/obj_perms_yes.html 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/templates/admin/guardian/model/obj_perms_yes.html 2015-12-18 05:08:22.000000000 +0000 @@ -1,3 +1,3 @@ {% load guardian_tags %} {% load staticfiles %} - + diff -Nru django-guardian-1.3.2/guardian/testapp/migrations/0005_auto_20151217_2344.py django-guardian-1.4.1/guardian/testapp/migrations/0005_auto_20151217_2344.py --- django-guardian-1.3.2/guardian/testapp/migrations/0005_auto_20151217_2344.py 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/migrations/0005_auto_20151217_2344.py 2016-01-08 08:13:40.000000000 +0000 @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2015-12-17 23:44 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('testapp', '0004_auto_20151112_2209'), + ] + + operations = [ + migrations.CreateModel( + name='Post', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=64, verbose_name='title')), + ], + ), + ] diff -Nru django-guardian-1.3.2/guardian/testapp/models.py django-guardian-1.4.1/guardian/testapp/models.py --- django-guardian-1.3.2/guardian/testapp/models.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/models.py 2016-01-08 08:13:40.000000000 +0000 @@ -9,6 +9,10 @@ from guardian.models import GroupObjectPermissionBase +class Post(models.Model): + title = models.CharField('title', max_length=64) + + class DynamicAccessor(object): def __init__(self): pass diff -Nru django-guardian-1.3.2/guardian/testapp/tests/conf.py django-guardian-1.4.1/guardian/testapp/tests/conf.py --- django-guardian-1.3.2/guardian/testapp/tests/conf.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/conf.py 2015-12-18 05:08:22.000000000 +0000 @@ -1,6 +1,5 @@ from __future__ import unicode_literals import os -import django from guardian.compat import unittest from guardian.utils import abspath from django.conf import settings diff -Nru django-guardian-1.3.2/guardian/testapp/tests/__init__.py django-guardian-1.4.1/guardian/testapp/tests/__init__.py --- django-guardian-1.3.2/guardian/testapp/tests/__init__.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/__init__.py 2015-12-18 05:08:22.000000000 +0000 @@ -1,24 +1 @@ from __future__ import unicode_literals -import django -if django.VERSION < (1, 7): - from django.conf import settings - - from .test_conf import * - from .test_core import * - from .test_custompkmodel import * - from .test_decorators import * - from .test_direct_rel import * - from .test_forms import * - from .test_managers import * - from .test_management import * - from .test_orphans import * - from .test_other import * - from .test_utils import * - from .test_shortcuts import * - from .test_tags import * - - - if 'django.contrib.admin' in settings.INSTALLED_APPS: - from .test_admin import * - from .test_mixins import * - diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_admin.py django-guardian-1.4.1/guardian/testapp/tests/test_admin.py --- django-guardian-1.3.2/guardian/testapp/tests/test_admin.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_admin.py 2016-01-08 08:13:40.000000000 +0000 @@ -41,8 +41,7 @@ self.user = User.objects.create_user('joe', 'joe@example.com', 'joe') self.group = Group.objects.create(name='group') self.client = Client() - self.obj = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + self.obj = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') self.obj_info = self.obj._meta.app_label, get_model_name(self.obj) def tearDown(self): diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_checks.py django-guardian-1.4.1/guardian/testapp/tests/test_checks.py --- django-guardian-1.3.2/guardian/testapp/tests/test_checks.py 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_checks.py 2015-12-18 05:08:22.000000000 +0000 @@ -0,0 +1,17 @@ + +from django.test import TestCase +from guardian.checks import check_settings + + +class SystemCheckTestCase(TestCase): + def test_checks(self): + """ Test custom system checks + :return: None + """ + self.assertFalse(check_settings(None)) + + with self.settings( + AUTHENTICATION_BACKENDS=('django.contrib.auth.backends.ModelBackend',), + ANONYMOUS_USER_ID=None, + ): + self.assertEqual(len(check_settings(None)), 2) diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_core.py django-guardian-1.4.1/guardian/testapp/tests/test_core.py --- django-guardian-1.3.2/guardian/testapp/tests/test_core.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_core.py 2016-01-08 08:13:40.000000000 +0000 @@ -17,17 +17,26 @@ from guardian.exceptions import NotUserNorGroup from guardian.models import UserObjectPermission, GroupObjectPermission from guardian.shortcuts import assign_perm +from guardian.management import create_anonymous_user User = get_user_model() + +class CustomUserTests(TestCase): + def test_create_anonymous_user(self): + create_anonymous_user(object()) + self.assertEqual(1, User.objects.all().count()) + anonymous = User.objects.all()[0] + self.assertEqual(anonymous.pk, settings.ANONYMOUS_USER_ID) + + class ObjectPermissionTestCase(TestCase): def setUp(self): self.group, created = Group.objects.get_or_create(name='jackGroup') self.user, created = User.objects.get_or_create(username='jack') self.user.groups.add(self.group) - self.ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + self.ctype = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') try: self.anonymous_user = User.objects.get(pk=settings.ANONYMOUS_USER_ID) except User.DoesNotExist: @@ -149,10 +158,8 @@ def test_get_perms(self): group = Group.objects.create(name='group') - obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') - obj2 = ContentType.objects.create(name='ct2', model='bar', - app_label='guardian-tests') + obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') + obj2 = ContentType.objects.create(model='bar', app_label='guardian-tests') assign_perms = { group: ('change_group', 'delete_group'), diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_custompkmodel.py django-guardian-1.4.1/guardian/testapp/tests/test_custompkmodel.py --- django-guardian-1.3.2/guardian/testapp/tests/test_custompkmodel.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_custompkmodel.py 2016-01-08 08:13:40.000000000 +0000 @@ -14,8 +14,7 @@ def setUp(self): self.user = get_user_model().objects.create(username='joe') - self.ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + self.ctype = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') def test_assign_perm(self): assign_perm('contenttypes.change_contenttype', self.user, self.ctype) diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_decorators.py django-guardian-1.4.1/guardian/testapp/tests/test_decorators.py --- django-guardian-1.3.2/guardian/testapp/tests/test_decorators.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_decorators.py 2016-01-08 08:13:40.000000000 +0000 @@ -1,5 +1,5 @@ from __future__ import unicode_literals -from django.conf import settings +from django.conf import settings, global_settings from django.contrib.auth.models import Group, AnonymousUser from django.core.exceptions import PermissionDenied from django.db.models.base import ModelBase @@ -23,7 +23,6 @@ from guardian.testapp.tests.conf import TestDataMixin from guardian.testapp.tests.conf import override_settings from guardian.testapp.tests.conf import skipUnlessTestApp -from django.core.urlresolvers import reverse from django import get_version as django_get_version User = get_user_model() @@ -367,5 +366,6 @@ return response = self.client.get(view_url) - self.assertRedirects(response, reverse(settings.LOGIN_URL) + "?next=" + view_url) + # this should be '/account/login' + self.assertRedirects(response, global_settings.LOGIN_URL + "?next=" + view_url) diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_forms.py django-guardian-1.4.1/guardian/testapp/tests/test_forms.py --- django-guardian-1.3.2/guardian/testapp/tests/test_forms.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_forms.py 2016-01-08 08:13:40.000000000 +0000 @@ -10,8 +10,7 @@ def setUp(self): self.user = get_user_model().objects.create_user( 'joe', 'joe@example.com', 'joe') - self.obj = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + self.obj = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') def test_not_implemented(self): diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_mixins.py django-guardian-1.4.1/guardian/testapp/tests/test_mixins.py --- django-guardian-1.3.2/guardian/testapp/tests/test_mixins.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_mixins.py 2016-01-08 08:13:40.000000000 +0000 @@ -1,6 +1,5 @@ from __future__ import unicode_literals -from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import AnonymousUser from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import PermissionDenied @@ -14,6 +13,8 @@ from guardian.mixins import LoginRequiredMixin from guardian.mixins import PermissionRequiredMixin +from ..models import Post + class DatabaseRemovedError(Exception): pass @@ -23,17 +24,16 @@ raise DatabaseRemovedError("You've just allowed db to be removed!") class TestView(PermissionRequiredMixin, RemoveDatabaseView): - permission_required = 'contenttypes.change_contenttype' + permission_required = 'testapp.change_post' object = None # should be set at each tests explicitly class NoObjectView(PermissionRequiredMixin, RemoveDatabaseView): - permission_required = 'contenttypes.change_contenttype' + permission_required = 'testapp.change_post' class TestViewMixins(TestCase): def setUp(self): - self.ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + self.post = Post.objects.create(title='foo') self.factory = RequestFactory() self.user = get_user_model().objects.create_user( 'joe', 'joe@doe.com', 'doe') @@ -47,12 +47,12 @@ request = self.factory.get('/') request.user = self.user # View.object is set - view = TestView.as_view(object=self.ctype) + view = TestView.as_view(object=self.post) response = view(request) self.assertEqual(response.status_code, 302) # View.get_object returns object - TestView.get_object = lambda instance: self.ctype + TestView.get_object = lambda instance: self.post view = TestView.as_view() response = view(request) self.assertEqual(response.status_code, 302) @@ -65,7 +65,7 @@ """ request = self.factory.get('/') request.user = self.user - view = TestView.as_view(raise_exception=True, object=self.ctype) + view = TestView.as_view(raise_exception=True, object=self.post) with self.assertRaises(PermissionDenied): view(request) @@ -76,8 +76,8 @@ """ request = self.factory.get('/') request.user = self.user - request.user.add_obj_perm('change_contenttype', self.ctype) - view = TestView.as_view(permission_required=None, object=self.ctype) + request.user.add_obj_perm('change_post', self.post) + view = TestView.as_view(permission_required=None, object=self.post) with self.assertRaises(ImproperlyConfigured): view(request) @@ -88,8 +88,8 @@ """ request = self.factory.get('/') request.user = self.user - request.user.add_obj_perm('change_contenttype', self.ctype) - view = TestView.as_view(object=self.ctype) + request.user.add_obj_perm('change_post', self.post) + view = TestView.as_view(object=self.post) with self.assertRaises(DatabaseRemovedError): view(request) @@ -101,7 +101,7 @@ request = self.factory.get('/') request.user = self.user - request.user.add_obj_perm('change_contenttype', self.ctype) + request.user.add_obj_perm('change_post', self.post) view = NoObjectView.as_view() response = view(request) self.assertEqual(response.status_code, 302) @@ -118,16 +118,16 @@ request = self.factory.get('/') request.user = self.user - request.user.add_obj_perm('change_contenttype', self.ctype) - SecretView.permission_required = ['contenttypes.change_contenttype', - 'contenttypes.add_contenttype'] - view = SecretView.as_view(object=self.ctype) + request.user.add_obj_perm('change_post', self.post) + SecretView.permission_required = ['testapp.change_post', + 'testapp.add_post'] + view = SecretView.as_view(object=self.post) response = view(request) self.assertEqual(response.status_code, 302) SecretView.on_permission_check_fail.assert_called_once_with(request, - response, obj=self.ctype) + response, obj=self.post) - request.user.add_obj_perm('add_contenttype', self.ctype) + request.user.add_obj_perm('add_post', self.post) with self.assertRaises(DatabaseRemovedError): view(request) diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_orphans.py django-guardian-1.4.1/guardian/testapp/tests/test_orphans.py --- django-guardian-1.3.2/guardian/testapp/tests/test_orphans.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_orphans.py 2016-01-08 08:13:40.000000000 +0000 @@ -1,11 +1,8 @@ from __future__ import unicode_literals -# Try the new app settings (Django 1.7) and fall back to the old system -try: - from django.apps import apps as django_apps - auth_app = django_apps.get_app_config("auth") -except ImportError: - from django.contrib.auth import models as auth_app +from django.apps import apps as django_apps +auth_app = django_apps.get_app_config("auth") + from django.contrib.contenttypes.models import ContentType from django.core.management import call_command from django.test import TestCase @@ -27,10 +24,8 @@ # Create objects for which we would assing obj perms self.target_user1 = User.objects.create(username='user1') self.target_group1 = Group.objects.create(name='group1') - self.target_obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='fake-for-guardian-tests') - self.target_obj2 = ContentType.objects.create(name='ct2', model='bar', - app_label='fake-for-guardian-tests') + self.target_obj1 = ContentType.objects.create(model='foo', app_label='fake-for-guardian-tests') + self.target_obj2 = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') # Required if MySQL backend is used :/ create_permissions(auth_app, [], 1) diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_other.py django-guardian-1.4.1/guardian/testapp/tests/test_other.py --- django-guardian-1.3.2/guardian/testapp/tests/test_other.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_other.py 2016-01-08 08:13:40.000000000 +0000 @@ -33,12 +33,9 @@ def setUp(self): super(UserPermissionTests, self).setUp() self.user = User.objects.get(username='jack') - self.ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') - self.obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') - self.obj2 = ContentType.objects.create(name='ct2', model='bar', - app_label='guardian-tests') + self.ctype = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') + self.obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') + self.obj2 = ContentType.objects.create(model='bar', app_label='guardian-tests') def test_assignement(self): self.assertFalse(self.user.has_perm('change_contenttype', self.ctype)) @@ -122,12 +119,9 @@ self.user = User.objects.get(username='jack') self.group, created = Group.objects.get_or_create(name='jackGroup') self.user.groups.add(self.group) - self.ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') - self.obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') - self.obj2 = ContentType.objects.create(name='ct2', model='bar', - app_label='guardian-tests') + self.ctype = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') + self.obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') + self.obj2 = ContentType.objects.create(model='bar', app_label='guardian-tests') def test_assignement(self): self.assertFalse(self.user.has_perm('change_contenttype', self.ctype)) @@ -243,8 +237,7 @@ def test_not_active_user(self): user = User.objects.create(username='non active user') - ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + ctype = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') perm = 'change_contenttype' UserObjectPermission.objects.assign_perm(perm, user, ctype) self.assertTrue(self.backend.has_perm(user, perm, ctype)) diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_shortcuts.py django-guardian-1.4.1/guardian/testapp/tests/test_shortcuts.py --- django-guardian-1.3.2/guardian/testapp/tests/test_shortcuts.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_shortcuts.py 2016-01-08 08:13:40.000000000 +0000 @@ -167,10 +167,8 @@ Tests get_users_with_perms function. """ def setUp(self): - self.obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') - self.obj2 = ContentType.objects.create(name='ct2', model='bar', - app_label='guardian-tests') + self.obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') + self.obj2 = ContentType.objects.create(model='bar', app_label='guardian-tests') self.user1 = User.objects.create(username='user1') self.user2 = User.objects.create(username='user2') self.user3 = User.objects.create(username='user3') @@ -331,10 +329,8 @@ Tests get_groups_with_perms function. """ def setUp(self): - self.obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') - self.obj2 = ContentType.objects.create(name='ct2', model='bar', - app_label='guardian-tests') + self.obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') + self.obj2 = ContentType.objects.create(model='bar', app_label='guardian-tests') self.user1 = User.objects.create(username='user1') self.user2 = User.objects.create(username='user2') self.user3 = User.objects.create(username='user3') @@ -411,8 +407,7 @@ def setUp(self): self.user = User.objects.create(username='joe') self.group = Group.objects.create(name='group') - self.ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + self.ctype = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') def test_superuser(self): self.user.is_superuser = True @@ -431,8 +426,7 @@ def test_with_superuser_false(self): self.user.is_superuser = True ctypes = ContentType.objects.all() - obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') + obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') assign_perm('change_contenttype', self.user, obj1) objects = get_objects_for_user(self.user, ['contenttypes.change_contenttype'], ctypes, with_superuser=False) @@ -444,8 +438,7 @@ objects = get_objects_for_user(self.user, ['contenttypes.change_contenttype'], ctypes) - obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') + obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') assign_perm('change_contenttype', self.user, obj1) objects = get_objects_for_user(self.user, ['contenttypes.change_contenttype'], ctypes) @@ -800,12 +793,9 @@ Tests get_objects_for_group function. """ def setUp(self): - self.obj1 = ContentType.objects.create(name='ct1', model='foo', - app_label='guardian-tests') - self.obj2 = ContentType.objects.create(name='ct2', model='bar', - app_label='guardian-tests') - self.obj3 = ContentType.objects.create(name='ct3', model='baz', - app_label='guardian-tests') + self.obj1 = ContentType.objects.create(model='foo', app_label='guardian-tests') + self.obj2 = ContentType.objects.create(model='bar', app_label='guardian-tests') + self.obj3 = ContentType.objects.create(model='baz', app_label='guardian-tests') self.user1 = User.objects.create(username='user1') self.user2 = User.objects.create(username='user2') self.user3 = User.objects.create(username='user3') diff -Nru django-guardian-1.3.2/guardian/testapp/tests/test_tags.py django-guardian-1.4.1/guardian/testapp/tests/test_tags.py --- django-guardian-1.3.2/guardian/testapp/tests/test_tags.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/test_tags.py 2016-01-08 08:13:40.000000000 +0000 @@ -22,8 +22,7 @@ class GetObjPermsTagTest(TestCase): def setUp(self): - self.ctype = ContentType.objects.create(name='foo', model='bar', - app_label='fake-for-guardian-tests') + self.ctype = ContentType.objects.create(model='bar', app_label='fake-for-guardian-tests') self.group = Group.objects.create(name='jackGroup') self.user = User.objects.create(username='jack') self.user.groups.add(self.group) diff -Nru django-guardian-1.3.2/guardian/testapp/tests/urls.py django-guardian-1.4.1/guardian/testapp/tests/urls.py --- django-guardian-1.3.2/guardian/testapp/tests/urls.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/tests/urls.py 2016-01-08 08:13:40.000000000 +0000 @@ -1,25 +1,19 @@ from __future__ import unicode_literals # handler404 and handler500 are needed for admin tests -from guardian.compat import include, patterns, handler404, handler500 # pyflakes:ignore +from guardian.compat import include, url, handler404, handler500 # pyflakes:ignore from guardian.mixins import PermissionRequiredMixin from django.contrib import admin -from django import get_version as django_get_version - -if (django_get_version() >= "1.5"): - from django.views.generic import View +from django.contrib.auth.views import login +from django.views.generic import View admin.autodiscover() -urlpatterns = patterns('', - (r'^admin/', include(admin.site.urls)), -) - -if (django_get_version() >= "1.5"): - class testClassRedirectView(PermissionRequiredMixin, View): - permission_required = 'testapp.change_project' +class TestClassRedirectView(PermissionRequiredMixin, View): + permission_required = 'testapp.change_project' - urlpatterns += patterns('', - (r'^accounts/login/', 'django.contrib.auth.views.login', {'template_name': 'blank.html'}), - (r'^permission_required/', testClassRedirectView.as_view()), - ) +urlpatterns = [ + url(r'^admin/', include(admin.site.urls)), + url(r'^accounts/login/', login, {'template_name': 'blank.html'}), + url(r'^permission_required/', TestClassRedirectView.as_view()), +] diff -Nru django-guardian-1.3.2/guardian/testapp/testsettings.py django-guardian-1.4.1/guardian/testapp/testsettings.py --- django-guardian-1.3.2/guardian/testapp/testsettings.py 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/guardian/testapp/testsettings.py 2016-01-08 08:13:40.000000000 +0000 @@ -0,0 +1,52 @@ +import os +import random +import string +import environ + +env = environ.Env() + +DEBUG = False + +ANONYMOUS_USER_ID = -1 + +AUTH_USER_MODEL = "testapp.CustomUser" +GUARDIAN_MONKEY_PATCH = False + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.admin', + 'django.contrib.messages', + 'guardian', + 'guardian.testapp', +) + +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'guardian.backends.ObjectPermissionBackend', +) + +# this fixes warnings in django 1.7 +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +) + +TEST_RUNNER = 'django.test.runner.DiscoverRunner' + +ROOT_URLCONF = 'guardian.testapp.tests.urls' +SITE_ID = 1 + +TEMPLATE_DIRS = ( + os.path.join(os.path.dirname(__file__), 'tests', 'templates'), +) + +SECRET_KEY = ''.join([random.choice(string.ascii_letters) for x in range(40)]) + +# Database specific + +DATABASES = {'default': env.db(default="sqlite:///")} diff -Nru django-guardian-1.3.2/guardian/testsettings.py django-guardian-1.4.1/guardian/testsettings.py --- django-guardian-1.3.2/guardian/testsettings.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/testsettings.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -import os -import random -import string -import django - -DEBUG = False - -ANONYMOUS_USER_ID = -1 - -AUTH_USER_MODEL = "testapp.CustomUser" -GUARDIAN_MONKEY_PATCH = False - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.admin', - 'django.contrib.messages', - 'guardian', - 'guardian.testapp', -) - -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'guardian.backends.ObjectPermissionBackend', -) - -# this fixes warnings in django 1.7 -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', -) - -if django.VERSION < (1, 7): - TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner' -else: - TEST_RUNNER = 'django.test.runner.DiscoverRunner' - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': ':memory:', - 'TEST_NAME': ':memory:', - }, -} - -ROOT_URLCONF = 'guardian.testapp.tests.urls' -SITE_ID = 1 - -TEMPLATE_DIRS = ( - os.path.join(os.path.dirname(__file__), 'tests', 'templates'), -) - -SECRET_KEY = ''.join([random.choice(string.ascii_letters) for x in range(40)]) - -# Database specific - -if os.environ.get('GUARDIAN_TEST_DB_BACKEND') == 'mysql': - DATABASES['default']['ENGINE'] = 'django.db.backends.mysql' - DATABASES['default']['NAME'] = 'guardian_test' - DATABASES['default']['TEST_NAME'] = 'guardian_test' - DATABASES['default']['USER'] = os.environ.get('USER', 'root') - -if os.environ.get('GUARDIAN_TEST_DB_BACKEND') == 'postgresql': - DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2' - DATABASES['default']['NAME'] = 'guardian' - DATABASES['default']['TEST_NAME'] = 'guardian_test' - DATABASES['default']['USER'] = os.environ.get('USER', 'postgres') - diff -Nru django-guardian-1.3.2/guardian/utils.py django-guardian-1.4.1/guardian/utils.py --- django-guardian-1.3.2/guardian/utils.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/guardian/utils.py 2015-12-18 05:08:22.000000000 +0000 @@ -150,7 +150,14 @@ if isinstance(obj, Model): obj = obj.__class__ ctype = ContentType.objects.get_for_model(obj) - for attr in obj._meta.get_all_related_objects(): + + if django.VERSION >= (1, 8): + fields = (f for f in obj._meta.get_fields() + if (f.one_to_many or f.one_to_one) and f.auto_created) + else: + fields = obj._meta.get_all_related_objects() + + for attr in fields: if django.VERSION < (1, 8): model = getattr(attr, 'model', None) else: @@ -161,7 +168,7 @@ if not model.objects.is_generic(): # make sure that content_object's content_type is same as # the one of given obj - fk = model._meta.get_field_by_name('content_object')[0] + fk = model._meta.get_field('content_object') if ctype == ContentType.objects.get_for_model(fk.rel.to): return model return generic_cls diff -Nru django-guardian-1.3.2/LICENSE django-guardian-1.4.1/LICENSE --- django-guardian-1.3.2/LICENSE 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/LICENSE 2015-12-18 05:08:22.000000000 +0000 @@ -22,3 +22,29 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The SVG icons in guardian/static/guardian/img are copied from Django. + +SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG +Font-Awesome-SVG-PNG is licensed under the MIT license: + +The MIT License (MIT) + +Copyright (c) 2014 Code Charm Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nru django-guardian-1.3.2/manage.py django-guardian-1.4.1/manage.py --- django-guardian-1.3.2/manage.py 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/manage.py 2016-01-08 08:13:40.000000000 +0000 @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "guardian.testapp.testsettings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff -Nru django-guardian-1.3.2/PKG-INFO django-guardian-1.4.1/PKG-INFO --- django-guardian-1.3.2/PKG-INFO 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/PKG-INFO 2016-01-09 22:45:25.000000000 +0000 @@ -0,0 +1,23 @@ +Metadata-Version: 1.1 +Name: django-guardian +Version: 1.4.1 +Summary: Implementation of per object permissions for Django. +Home-page: http://github.com/django-guardian/django-guardian +Author: Lukasz Balcerzak +Author-email: lukaszbalcerzak@gmail.com +License: BSD +Download-URL: https://github.com/django-guardian/django-guardian/tags +Description: 1.4.1 +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Django +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Security +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 diff -Nru django-guardian-1.3.2/requirements.txt django-guardian-1.4.1/requirements.txt --- django-guardian-1.3.2/requirements.txt 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/requirements.txt 2016-01-09 22:41:23.000000000 +0000 @@ -0,0 +1,3 @@ +Django==1.9.1 +six +django-environ diff -Nru django-guardian-1.3.2/setup.cfg django-guardian-1.4.1/setup.cfg --- django-guardian-1.3.2/setup.cfg 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/setup.cfg 2016-01-09 22:45:25.000000000 +0000 @@ -1,7 +1,7 @@ [build_sphinx] source-dir = docs/ -build-dir = docs/build -all_files = 1 +build-dir = docs/build +all_files = 1 [upload_sphinx] upload-dir = docs/build/html @@ -11,3 +11,9 @@ [wheel] universal = 1 + +[egg_info] +tag_build = +tag_date = 0 +tag_svn_revision = 0 + diff -Nru django-guardian-1.3.2/setup.py django-guardian-1.4.1/setup.py --- django-guardian-1.3.2/setup.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/setup.py 2016-01-09 22:41:23.000000000 +0000 @@ -3,16 +3,15 @@ from setuptools import setup, find_packages from extras import RunFlakesCommand -guardian = __import__('guardian') +version_file = os.path.join(os.path.dirname(__file__), 'VERSION.txt') +with open(version_file, 'r') as f: + version = f.readline().strip() + readme_file = os.path.join(os.path.dirname(__file__), 'README.rst') -try: - long_description = open(readme_file).read() -except IOError as err: - sys.stderr.write("[ERROR] Cannot find file specified as " - "``long_description`` (%s)\n" % readme_file) - sys.exit(1) +with open(version_file, 'r') as f: + long_description = f.readline().strip() -tests_require = ['mock'] +tests_require = ['mock', 'django-environ'] extra_kwargs = {} if sys.version_info >= (3,): @@ -22,19 +21,19 @@ setup( name = 'django-guardian', - version = guardian.get_version(), - url = 'http://github.com/lukaszb/django-guardian', + version = version, + url = 'http://github.com/django-guardian/django-guardian', author = 'Lukasz Balcerzak', author_email = 'lukaszbalcerzak@gmail.com', - download_url='https://github.com/lukaszb/django-guardian/tags', - description = guardian.__doc__.strip(), + download_url='https://github.com/django-guardian/django-guardian/tags', + description ="Implementation of per object permissions for Django.", long_description = long_description, zip_safe = False, packages = find_packages(), include_package_data = True, license = 'BSD', install_requires = [ - 'Django', + 'Django >= 1.7', 'six', ], tests_require=tests_require, diff -Nru django-guardian-1.3.2/tests.py django-guardian-1.4.1/tests.py --- django-guardian-1.3.2/tests.py 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/tests.py 2016-01-09 22:41:23.000000000 +0000 @@ -8,48 +8,36 @@ """ import os import sys -import django +import contextlib +import tempfile +import shutil + + +@contextlib.contextmanager +def tempdir(): + dirpath = tempfile.mkdtemp() + prevdir = os.getcwd() + + try: + os.chdir(dirpath) + yield dirpath + finally: + os.chdir(prevdir) + shutil.rmtree(dirpath) -os.environ["DJANGO_SETTINGS_MODULE"] = 'guardian.testsettings' -from guardian import testsettings as settings -settings.INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.sessions', - 'django.contrib.contenttypes', - 'django.contrib.admin', - 'django.contrib.sites', - 'guardian', - 'guardian.testapp', -) -settings.PASSWORD_HASHERS = ( - 'django.contrib.auth.hashers.MD5PasswordHasher', - 'django.contrib.auth.hashers.SHA1PasswordHasher', -) - -def run_tests(settings): - from django.test.utils import get_runner - from utils import show_settings - - show_settings(settings, 'tests') +def main(): + os.environ.setdefault( + "DJANGO_SETTINGS_MODULE", "guardian.testapp.testsettings") import django - if hasattr(django, 'setup'): - django.setup() + from django.core.management import call_command - TestRunner = get_runner(settings) - test_runner = TestRunner(interactive=False) - # As we use different TestRunners for django < 1.8 and >= 1.8 - # the arguments run_tests differs - if django.VERSION < (1, 7): - failures = test_runner.run_tests(['auth', 'guardian', 'testapp']) - else: - failures = test_runner.run_tests(['guardian']) - return failures + django.setup() + with tempdir(): + call_command('test') -def main(): - failures = run_tests(settings) - sys.exit(failures) + sys.exit(0) if __name__ == '__main__': main() diff -Nru django-guardian-1.3.2/tox.ini django-guardian-1.4.1/tox.ini --- django-guardian-1.3.2/tox.ini 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/tox.ini 2016-01-09 22:41:23.000000000 +0000 @@ -1,181 +1,35 @@ [tox] downloadcache = {toxworkdir}/cache/ envlist = - py27, - py27-django15, - py27-django16, py27-django17, py27-django18, py27-django19, - py33-django15, - py33-django16, py33-django17, py33-django18, - py34-django16, py34-django17, py34-django18, py35-django18, py34-django19, py35-django19, - custom-user-model, - no-tests-app, - migrations, - docs27, - docs33, - flakes, - [testenv] -commands = python setup.py test -deps = - django==1.5.5 - mock>=0.7.2 - -[testenv:mysql] -setenv = - GUARDIAN_TEST_DB_BACKEND=mysql -deps = - django==1.6.2 - MySQL-python==1.2.3 - -[testenv:postgresql] -basepython = python2.7 -setenv = - GUARDIAN_TEST_DB_BACKEND=postgresql -deps = - django==1.6.2 - psycopg2==2.4.1 -# psycopg2==2.4.2 has troubles with test runner, see: https://code.djangoproject.com/ticket/16250 - -[django15] -deps = django==1.5.12 - -[django16] -deps = django==1.6.11 - -[django17] -deps = django==1.7.10 - -[django18] -deps = django==1.8 - -[django19] -deps = django==1.9b1 - - -[testenv:py27-django15] -basepython = python2.7 -deps = {[django15]deps} - -[testenv:py27-django16] -basepython = python2.7 -deps = {[django16]deps} - -[testenv:py27-django17] -basepython = python2.7 -deps = {[django17]deps} - -[testenv:py27-django18] -basepython = python2.7 -deps = {[django18]deps} - -[testenv:py27-django19] -basepython = python2.7 -deps = {[django19]deps} - -[testenv:py33-django15] -basepython = python3.3 -deps = {[django15]deps} - -[testenv:py33-django16] -basepython = python3.3 -deps = {[django16]deps} - -[testenv:py33-django17] -basepython = python3.3 -deps = {[django17]deps} - -[testenv:py33-django18] -basepython = python3.3 -deps = {[django18]deps} - -[testenv:py34-django16] -basepython = python3.4 -deps = {[django16]deps} - -[testenv:py34-django17] -basepython = python3.4 -deps = {[django17]deps} - -[testenv:py34-django18] -basepython = python3.4 -deps = {[django18]deps} - -[testenv:py35-django18] -basepython = python3.5 -deps = {[django18]deps} - -[testenv:py34-django19] -basepython = python3.4 -deps = {[django19]deps} - -[testenv:py35-django19] -basepython = python3.5 -deps = {[django19]deps} - -[testenv:custom-user-model] -basepython = python3.4 -deps = {[django16]deps} -changedir = example_project -commands = - {envpython} manage.py test guardian integration_tests --traceback - -[testenv:no-tests-app] -basepython = python3.4 -deps = {[django16]deps} -changedir = example_project -setenv = - GUARDIAN_NO_TESTS_APP=yes -commands = - {envpython} manage.py test guardian - -[testenv:migrations] -setenv = - GUARDIAN_TEST_SOUTH="yes" -changedir = example_project -deps = - {[django15]deps} - mock - south -commands = - python manage.py syncdb --noinput - python manage.py migrationcheck - python manage.py test guardian --traceback - - -[testenv:docs27] -basepython = python2.7 -changedir = docs -deps = - sphinx - mock - {[django16]deps} -commands = - sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html - -[testenv:docs33] -basepython = python3.3 -changedir = docs +passenv = DATABASE_URL +basepython = + py26: python2.6 + py27: python2.7 + py33: python3.3 + py34: python3.4 + py35: python3.5 +commands = + # python setup.py flakes + python setup.py test + sphinx-build -b html -d {envtmpdir}/doctrees docs {envtmpdir}/html deps = sphinx - {[django16]deps} -commands = - sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html - - -[testenv:flakes] -deps = + mock>=0.7.2 + setuptools>=17.1 pyflakes -commands = - python setup.py flakes - + django-environ + django17: django==1.7.10 + django18: django==1.8.7 + django19: django==1.9.1 diff -Nru django-guardian-1.3.2/.travis.yml django-guardian-1.4.1/.travis.yml --- django-guardian-1.3.2/.travis.yml 2015-11-14 01:53:15.000000000 +0000 +++ django-guardian-1.4.1/.travis.yml 2016-01-08 08:13:40.000000000 +0000 @@ -7,20 +7,27 @@ - 3.5 env: - - DJANGO_VERSION=1.5.12 - - DJANGO_VERSION=1.6.11 - - DJANGO_VERSION=1.7.10 - - DJANGO_VERSION=1.8 - - DJANGO_VERSION=1.9b1 + - DJANGO_VERSION=1.7.10 DATABASE_URL=postgres://postgres@/django_guardian + - DJANGO_VERSION=1.8.7 DATABASE_URL=postgres://postgres@/django_guardian + - DJANGO_VERSION=1.9.1 DATABASE_URL=postgres://postgres@/django_guardian + - DJANGO_VERSION=1.7.10 DATABASE_URL=mysql://root:@localhost/django_guardian + - DJANGO_VERSION=1.8.7 DATABASE_URL=mysql://root:@localhost/django_guardian + - DJANGO_VERSION=1.9.1 DATABASE_URL=mysql://root:@localhost/django_guardian + - DJANGO_VERSION=1.7.10 DATABASE_URL=sqlite:// + - DJANGO_VERSION=1.8.7 DATABASE_URL=sqlite:// + - DJANGO_VERSION=1.9.1 DATABASE_URL=sqlite:// install: - travis_retry pip install -q mock==1.0.1 Django==$DJANGO_VERSION coverage coveralls +# Install database drivers + - bash -c "if [[ $DATABASE_URL = postgres* ]]; then pip install psycopg2==2.6.1; fi; " + - bash -c "if [[ $DATABASE_URL = mysql* ]]; then pip install mysqlclient==1.3.7; fi; " script: - coverage run --source=guardian setup.py test after_success: - - coverage report --omit "guardian/compat.py,guardian/testsettings.py" -m guardian/*.py + - coverage report --omit "guardian/compat.py,guardian/testapp/testsettings.py" -m guardian/*.py - coveralls notifications: @@ -29,11 +36,24 @@ matrix: exclude: + # Drop python 3.3 and django 1.9 - python: 3.3 - env: DJANGO_VERSION=1.9b1 + env: DJANGO_VERSION=1.9.1 DATABASE_URL=postgres://postgres@/django_guardian + - python: 3.3 + env: DJANGO_VERSION=1.9.1 DATABASE_URL=mysql://root:@localhost/django_guardian + - python: 3.3 + env: DJANGO_VERSION=1.9.1 DATABASE_URL=sqlite:// + # Drop python 3.5 and django 1.7 - python: 3.5 - env: DJANGO_VERSION=1.5.12 + env: DJANGO_VERSION=1.7.10 DATABASE_URL=postgres://postgres@/django_guardian - python: 3.5 - env: DJANGO_VERSION=1.6.11 + env: DJANGO_VERSION=1.7.10 DATABASE_URL=mysql://root:@localhost/django_guardian - python: 3.5 - env: DJANGO_VERSION=1.7.10 + env: DJANGO_VERSION=1.7.10 DATABASE_URL=sqlite:// + # Drop python 3.3 with postgres due lack of driver + - python: 3.3 + env: DJANGO_VERSION=1.7.10 DATABASE_URL=postgres://postgres@/django_guardian + - python: 3.3 + env: DJANGO_VERSION=1.8.7 DATABASE_URL=postgres://postgres@/django_guardian + - python: 3.3 + env: DJANGO_VERSION=1.9.1 DATABASE_URL=postgres://postgres@/django_guardian diff -Nru django-guardian-1.3.2/VERSION.txt django-guardian-1.4.1/VERSION.txt --- django-guardian-1.3.2/VERSION.txt 1970-01-01 00:00:00.000000000 +0000 +++ django-guardian-1.4.1/VERSION.txt 2016-01-09 22:41:23.000000000 +0000 @@ -0,0 +1 @@ +1.4.1