changeset 5174:65872885d876

Merge stable
author Mads Kiilerich <madski@unity3d.com>
date Tue, 09 Jun 2015 22:46:40 +0200
parents d7f13c2a28ba (diff) a73f98871e2b (current diff)
children 18b0e4d1ae58
files kallithea/lib/helpers.py
diffstat 180 files changed, 9473 insertions(+), 3094 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Jun 09 22:12:21 2015 +0200
+++ b/.hgignore	Tue Jun 09 22:46:40 2015 +0200
@@ -6,6 +6,8 @@
 *.egg-info
 *.egg
 *.mo
+.eggs/
+tarballcache/
 
 syntax: regexp
 ^rcextensions
--- a/development.ini	Tue Jun 09 22:12:21 2015 +0200
+++ b/development.ini	Tue Jun 09 22:46:40 2015 +0200
@@ -134,7 +134,7 @@
 host = 0.0.0.0
 port = 5000
 
-## prefix middleware for rc
+## middleware for hosting the WSGI application under a URL prefix
 #[filter:proxy-prefix]
 #use = egg:PasteDeploy#prefix
 #prefix = /<your-prefix>
--- a/docs/index.rst	Tue Jun 09 22:12:21 2015 +0200
+++ b/docs/index.rst	Tue Jun 09 22:46:40 2015 +0200
@@ -15,6 +15,7 @@
 .. toctree::
    :maxdepth: 1
 
+   overview
    installation
    installation_win
    installation_win_old
--- a/docs/installation.rst	Tue Jun 09 22:12:21 2015 +0200
+++ b/docs/installation.rst	Tue Jun 09 22:46:40 2015 +0200
@@ -4,16 +4,11 @@
 Installation on Unix/Linux
 ==========================
 
-**Kallithea** is written entirely in Python_ and requires Python version
-2.6 or higher. Python 3.x is currently not supported.
-
-There are several ways to install Kallithea:
+Here are more details about 3 ways to install Kallithea:
 
-- :ref:`installation-source`: The Kallithea development repository is stable
-  and can be used in production. In fact, the Kallithea maintainers do
-  use it in production. The advantage of installation from source and regularly
-  updating it is that you take advantage of the most recent improvements, which
-  is particularly useful because Kallithea is evolving rapidly.
+- :ref:`installation-source`: The simplest way to keep the installation
+  uptodate and keep track of local customizations is to run directly from
+  source in a Kallithea repository clone and use virtualenv.
 
 - :ref:`installation-virtualenv`: If you prefer to only use released versions
   of Kallithea, the recommended method is to install Kallithea in a virtual
@@ -205,5 +200,4 @@
 
 
 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
-.. _Python: http://www.python.org/
 .. _pylons: http://www.pylonsproject.org/
--- a/docs/installation_win_old.rst	Tue Jun 09 22:12:21 2015 +0200
+++ b/docs/installation_win_old.rst	Tue Jun 09 22:46:40 2015 +0200
@@ -211,7 +211,7 @@
   cd C:\Kallithea\Bin
   paster make-config Kallithea production.ini
 
-Then, you must edit production.ini to fit your needs (ip address, ip
+Then, you must edit production.ini to fit your needs (network address and
 port, mail settings, database, whatever). I recommend using NotePad++
 (free) or similar text editor, as it handles well the EndOfLine
 character differences between Unix and Windows
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/overview.rst	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,128 @@
+.. _overview:
+
+=====================
+Installation Overview
+=====================
+
+
+Some overview and some details that can help understanding the options when
+installing Kallithea.
+
+
+Python Environment
+------------------
+
+**Kallithea** is written entirely in Python_ and requires Python version
+2.6 or higher. Python 3.x is currently not supported.
+
+Given a Python installation, there are different ways of providing the
+environment for running Python applications. Each of them pretty much
+corresponds to a ``site-packages`` directory somewhere where packages can be
+installed.
+
+Kallithea itself can be run from source or be installed, but even when running
+from source, there are some dependencies that must be installed in the Python
+environment used for running Kallithea.
+
+- Packages *could* be installed in Python's ``site-packages`` directory ... but
+  that would require running pip_ as root and it would be hard to uninstall or
+  upgrade and is probably not a good idea unless using a package manager.
+
+- Packages could also be installed in ``~/.local`` ... but that is probably
+  only a good idea if using a dedicated user per application or instance.
+
+- Finally, it can be installed in a virtualenv_. That is a very lightweight
+  "container" where each Kallithea instance can get its own dedicated and
+  self-contained virtual environment.
+
+We recommend using virtualenv for installing Kallithea.
+
+
+Installation Methods
+--------------------
+
+Kallithea must be installed on a server. Kallithea is installed in a Python
+environment so it can use packages that are installed there and make itself
+available for other packages.
+
+Two different cases will pretty much cover the options for how it can be
+installed.
+
+- The Kallithea source repository can be cloned and used - it is kept stable and
+  can be used in production. The Kallithea maintainers use the development
+  branch in production. The advantage of installation from source and regularly
+  updating it is that you take advantage of the most recent improvements. Using
+  it directly from a DVCS also means that it is easy to track local customizations.
+
+  Running ``setup.py develop`` in the source will use pip to install the
+  necessary dependencies in the Python environment and create a
+  ``.../site-packages/Kallithea.egg-link`` file there that points at the Kallithea
+  source.
+
+- Kallithea can also be installed from ready-made packages using a package manager.
+  The official released versions are available on PyPI_ and can be downloaded and
+  installed with all dependencies using ``pip install kallithea``.
+
+  With this method, Kallithea is installed in the Python environment as any
+  other package, usually as a ``.../site-packages/Kallithea-X-py2.7.egg/``
+  directory with Python files and everything else that is needed.
+
+  (``pip install kallithea`` from a source tree will do pretty much the same
+  but build the Kallithea package itself locally instead of downloading it.)
+
+
+Web Server
+----------
+
+Kallithea is (primarily) a WSGI_ application that must be run from a web
+server that expose WSGI as HTTP.
+
+- Kallithea uses the Paste_ tool for some admin tasks. Paste provides ``paste
+  serve`` as a convenient way to launch Python WSGI / web servers.
+  This method is perfect for development but *can* also be used for production.
+
+  ``paste`` is a command line tool. Using it in production requires some way to
+  wrap it as a managable service.
+
+  Paste come with its own web server but Kallithea defaults to use Waitress_.
+  Gunicorn_ is also an option. These web servers have different limited feature
+  sets.
+
+  It is also common/mandatory to put another web server or (reverse) proxy in
+  front of these Python web servers. Nginx_ is a common choice. This simple
+  setup will thus often end up being quite complex.
+
+  The configuration of which web server to use is in the ini file passed to
+  ``paste``. The entry point for the WSGI application is configured in
+  ``setup.py`` as ``kallithea.config.middleware:make_app``.
+
+- `Apache httpd`_ can serve WSGI applications directly using mod_wsgi_ and a
+  simple Python file with the necessary configuration. This is a good option if
+  Apache is an option.
+
+- IIS_ can also server WSGI applications directly using isapi-wsgi_.
+
+- UWSGI_ is also an option.
+
+The best option depends on what you are familiar with and the requirements for
+performance and stability. Also, keep in mind that Kallithea mainly is serving
+custom data generated from relatively slow Python process. Kallithea is also
+often used inside organizations with a limited amount of users and thus no
+continuous hammering from the internet.
+
+
+.. _Python: http://www.python.org/
+.. _Gunicorn: http://gunicorn.org/
+.. _Waitress: http://waitress.readthedocs.org/en/latest/
+.. _virtualenv: http://pypi.python.org/pypi/virtualenv
+.. _Paste: http://pythonpaste.org/
+.. _PyPI: https://pypi.python.org/pypi
+.. _Apache httpd: http://httpd.apache.org/
+.. _mod_wsgi: https://code.google.com/p/modwsgi/
+.. _isapi-wsgi: https://github.com/hexdump42/isapi-wsgi
+.. _UWSGI: https://uwsgi-docs.readthedocs.org/en/latest/
+.. _nginx: http://nginx.org/en/
+.. _iis: http://en.wikipedia.org/wiki/Internet_Information_Services
+.. _pip: http://en.wikipedia.org/wiki/Pip_%28package_manager%29
+.. _WSGI: http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface
+.. _pylons: http://www.pylonsproject.org/
--- a/docs/setup.rst	Tue Jun 09 22:12:21 2015 +0200
+++ b/docs/setup.rst	Tue Jun 09 22:46:40 2015 +0200
@@ -68,16 +68,21 @@
   settings, as well as edit more advanced options on users and
   repositories
 
+
+Extensions
+----------
+
 Optionally users can create an ``rcextensions`` package that extends Kallithea
 functionality. To do this simply execute::
 
     paster make-rcext my.ini
 
-This will create an ``rcextensions`` package in the same place that your ``ini`` file
-lives. With ``rcextensions`` it's possible to add additional mapping for whoosh,
+This will create an ``rcextensions`` package next to the specified ``ini`` file.
+With ``rcextensions`` it's possible to add additional mapping for whoosh,
 stats and add additional code into the push/pull/create/delete repo hooks,
-for example, for sending signals to build-bots such as Jenkins.
-Please see the ``__init__.py`` file inside ``rcextensions`` package
+for example for sending signals to build-bots such as Jenkins.
+
+See the ``__init__.py`` file inside the generated ``rcextensions`` package
 for more details.
 
 
--- a/docs/usage/performance.rst	Tue Jun 09 22:12:21 2015 +0200
+++ b/docs/usage/performance.rst	Tue Jun 09 22:46:40 2015 +0200
@@ -39,7 +39,8 @@
     sqlite is a good option when having a small load on the system. But due to
     locking issues with sqlite, it is not recommended to use it for larger
     deployments. Switching to mysql or postgres will result in an immediate
-    performance increase.
+    performance increase. A tool like SQLAlchemyGrate_ can be used for
+    migrating to another database platform.
 
 3. Scale Kallithea horizontally
 
@@ -61,3 +62,5 @@
     - Load balance using round robin or IP hash, recommended is writing LB rules
       that will separate regular user traffic from automated processes like CI
       servers or build bots.
+
+.. _SQLAlchemyGrate: https://github.com/shazow/sqlalchemygrate
--- a/kallithea/bin/template.ini.mako	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/bin/template.ini.mako	Tue Jun 09 22:46:40 2015 +0200
@@ -132,7 +132,7 @@
 host = ${host}
 port = ${port}
 
-<%text>## prefix middleware for rc</%text>
+<%text>## middleware for hosting the WSGI application under a URL prefix</%text>
 #[filter:proxy-prefix]
 #use = egg:PasteDeploy#prefix
 #prefix = /<your-prefix>
--- a/kallithea/config/deployment.ini_tmpl	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/config/deployment.ini_tmpl	Tue Jun 09 22:46:40 2015 +0200
@@ -129,7 +129,7 @@
 host = 127.0.0.1
 port = 5000
 
-## prefix middleware for rc
+## middleware for hosting the WSGI application under a URL prefix
 #[filter:proxy-prefix]
 #use = egg:PasteDeploy#prefix
 #prefix = /<your-prefix>
--- a/kallithea/config/middleware.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/config/middleware.py	Tue Jun 09 22:46:40 2015 +0200
@@ -15,7 +15,6 @@
     Pylons middleware initialization
 """
 
-from beaker.middleware import SessionMiddleware
 from routes.middleware import RoutesMiddleware
 from paste.cascade import Cascade
 from paste.registry import RegistryManager
@@ -29,6 +28,7 @@
 from kallithea.lib.middleware.simplehg import SimpleHg
 from kallithea.lib.middleware.simplegit import SimpleGit
 from kallithea.lib.middleware.https_fixup import HttpsFixup
+from kallithea.lib.middleware.sessionmiddleware import SecureSessionMiddleware
 from kallithea.config.environment import load_environment
 from kallithea.lib.middleware.wrapper import RequestWrapper
 
@@ -60,7 +60,7 @@
 
     # Routing/Session/Cache Middleware
     app = RoutesMiddleware(app, config['routes.map'])
-    app = SessionMiddleware(app, config)
+    app = SecureSessionMiddleware(app, config)
 
     # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
     if asbool(config['pdebug']):
--- a/kallithea/config/routing.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/config/routing.py	Tue Jun 09 22:46:40 2015 +0200
@@ -206,7 +206,7 @@
         m.connect("edit_user_api_keys", "/users/{id}/edit/api_keys",
                   action="edit_api_keys", conditions=dict(method=["GET"]))
         m.connect("edit_user_api_keys", "/users/{id}/edit/api_keys",
-                  action="add_api_key", conditions=dict(method=["PUT"]))
+                  action="add_api_key", conditions=dict(method=["POST"]))
         m.connect("edit_user_api_keys", "/users/{id}/edit/api_keys",
                   action="delete_api_key", conditions=dict(method=["DELETE"]))
 
--- a/kallithea/controllers/admin/gists.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/admin/gists.py	Tue Jun 09 22:46:40 2015 +0200
@@ -56,7 +56,7 @@
 
     def __load_defaults(self, extra_values=None):
         c.lifetime_values = [
-            (str(-1), _('forever')),
+            (str(-1), _('Forever')),
             (str(5), _('5 minutes')),
             (str(60), _('1 hour')),
             (str(60 * 24), _('1 day')),
@@ -230,7 +230,7 @@
             log.error(traceback.format_exc())
             raise HTTPNotFound()
 
-        self.__load_defaults(extra_values=('0', _('unmodified')))
+        self.__load_defaults(extra_values=('0', _('Unmodified')))
         rendered = render('admin/gists/edit.html')
 
         if request.POST:
--- a/kallithea/controllers/admin/my_account.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/admin/my_account.py	Tue Jun 09 22:46:40 2015 +0200
@@ -235,7 +235,7 @@
         self.__load_data()
         show_expired = True
         c.lifetime_values = [
-            (str(-1), _('forever')),
+            (str(-1), _('Forever')),
             (str(5), _('5 minutes')),
             (str(60), _('1 hour')),
             (str(60 * 24), _('1 day')),
@@ -251,7 +251,7 @@
         description = request.POST.get('description')
         ApiKeyModel().create(self.authuser.user_id, description, lifetime)
         Session().commit()
-        h.flash(_("Api key successfully created"), category='success')
+        h.flash(_("API key successfully created"), category='success')
         return redirect(url('my_account_api_keys'))
 
     def my_account_api_keys_delete(self):
@@ -263,10 +263,10 @@
                 user.api_key = generate_api_key(user.username)
                 Session().add(user)
                 Session().commit()
-                h.flash(_("Api key successfully reset"), category='success')
+                h.flash(_("API key successfully reset"), category='success')
         elif api_key:
             ApiKeyModel().delete(api_key, self.authuser.user_id)
             Session().commit()
-            h.flash(_("Api key successfully deleted"), category='success')
+            h.flash(_("API key successfully deleted"), category='success')
 
         return redirect(url('my_account_api_keys'))
--- a/kallithea/controllers/admin/users.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/admin/users.py	Tue Jun 09 22:46:40 2015 +0200
@@ -34,13 +34,14 @@
 from pylons.controllers.util import redirect
 from pylons.i18n.translation import _
 from sqlalchemy.sql.expression import func
+from webob.exc import HTTPNotFound
 
 import kallithea
 from kallithea.lib.exceptions import DefaultUserException, \
     UserOwnsReposException, UserCreationError
 from kallithea.lib import helpers as h
 from kallithea.lib.auth import LoginRequired, HasPermissionAllDecorator, \
-    AuthUser, generate_api_key
+    AuthUser
 import kallithea.lib.auth_modules.auth_internal
 from kallithea.lib import auth_modules
 from kallithea.lib.base import BaseController, render
@@ -52,7 +53,7 @@
 from kallithea.model.meta import Session
 from kallithea.lib.utils import action_logger
 from kallithea.lib.compat import json
-from kallithea.lib.utils2 import datetime_to_time, safe_int
+from kallithea.lib.utils2 import datetime_to_time, safe_int, generate_api_key
 
 log = logging.getLogger(__name__)
 
@@ -233,14 +234,17 @@
         # url('user', id=ID)
         User.get_or_404(-1)
 
+    def _get_user_or_raise_if_default(self, id):
+        try:
+            return User.get_or_404(id, allow_default=False)
+        except DefaultUserException:
+            h.flash(_("The default user cannot be edited"), category='warning')
+            raise HTTPNotFound
+
     def edit(self, id, format='html'):
         """GET /users/id/edit: Form to edit an existing item"""
         # url('edit_user', id=ID)
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
-
+        c.user = self._get_user_or_raise_if_default(id)
         c.active = 'profile'
         c.extern_type = c.user.extern_type
         c.extern_name = c.user.extern_name
@@ -254,11 +258,7 @@
             force_defaults=False)
 
     def edit_advanced(self, id):
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
-
+        c.user = self._get_user_or_raise_if_default(id)
         c.active = 'advanced'
         c.perm_user = AuthUser(user_id=id, ip_addr=self.ip_addr)
 
@@ -277,15 +277,11 @@
             force_defaults=False)
 
     def edit_api_keys(self, id):
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
-
+        c.user = self._get_user_or_raise_if_default(id)
         c.active = 'api_keys'
         show_expired = True
         c.lifetime_values = [
-            (str(-1), _('forever')),
+            (str(-1), _('Forever')),
             (str(5), _('5 minutes')),
             (str(60), _('1 hour')),
             (str(60 * 24), _('1 day')),
@@ -302,23 +298,17 @@
             force_defaults=False)
 
     def add_api_key(self, id):
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
+        c.user = self._get_user_or_raise_if_default(id)
 
         lifetime = safe_int(request.POST.get('lifetime'), -1)
         description = request.POST.get('description')
         ApiKeyModel().create(c.user.user_id, description, lifetime)
         Session().commit()
-        h.flash(_("Api key successfully created"), category='success')
+        h.flash(_("API key successfully created"), category='success')
         return redirect(url('edit_user_api_keys', id=c.user.user_id))
 
     def delete_api_key(self, id):
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
+        c.user = self._get_user_or_raise_if_default(id)
 
         api_key = request.POST.get('del_api_key')
         if request.POST.get('del_api_key_builtin'):
@@ -327,11 +317,11 @@
                 user.api_key = generate_api_key(user.username)
                 Session().add(user)
                 Session().commit()
-                h.flash(_("Api key successfully reset"), category='success')
+                h.flash(_("API key successfully reset"), category='success')
         elif api_key:
             ApiKeyModel().delete(api_key, c.user.user_id)
             Session().commit()
-            h.flash(_("Api key successfully deleted"), category='success')
+            h.flash(_("API key successfully deleted"), category='success')
 
         return redirect(url('edit_user_api_keys', id=c.user.user_id))
 
@@ -339,11 +329,7 @@
         pass
 
     def edit_perms(self, id):
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
-
+        c.user = self._get_user_or_raise_if_default(id)
         c.active = 'perms'
         c.perm_user = AuthUser(user_id=id, ip_addr=self.ip_addr)
 
@@ -364,7 +350,7 @@
     def update_perms(self, id):
         """PUT /users_perm/id: Update an existing item"""
         # url('user_perm', id=ID, method='put')
-        user = User.get_or_404(id)
+        user = self._get_user_or_raise_if_default(id)
 
         try:
             form = CustomDefaultPermissionsForm()()
@@ -402,11 +388,7 @@
         return redirect(url('edit_user_perms', id=id))
 
     def edit_emails(self, id):
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
-
+        c.user = self._get_user_or_raise_if_default(id)
         c.active = 'emails'
         c.user_email_map = UserEmailMap.query()\
             .filter(UserEmailMap.user == c.user).all()
@@ -421,7 +403,7 @@
     def add_email(self, id):
         """POST /user_emails:Add an existing item"""
         # url('user_emails', id=ID, method='put')
-
+        user = self._get_user_or_raise_if_default(id)
         email = request.POST.get('new_email')
         user_model = UserModel()
 
@@ -441,6 +423,7 @@
     def delete_email(self, id):
         """DELETE /user_emails_delete/id: Delete an existing item"""
         # url('user_emails_delete', id=ID, method='delete')
+        user = self._get_user_or_raise_if_default(id)
         email_id = request.POST.get('del_email_id')
         user_model = UserModel()
         user_model.delete_extra_email(id, email_id)
@@ -449,11 +432,7 @@
         return redirect(url('edit_user_emails', id=id))
 
     def edit_ips(self, id):
-        c.user = User.get_or_404(id)
-        if c.user.username == User.DEFAULT_USER:
-            h.flash(_("You can't edit this user"), category='warning')
-            return redirect(url('users'))
-
+        c.user = self._get_user_or_raise_if_default(id)
         c.active = 'ips'
         c.user_ip_map = UserIpMap.query()\
             .filter(UserIpMap.user == c.user).all()
@@ -479,7 +458,7 @@
         try:
             user_model.add_extra_ip(id, ip)
             Session().commit()
-            h.flash(_("Added ip %s to user whitelist") % ip, category='success')
+            h.flash(_("Added IP address %s to user whitelist") % ip, category='success')
         except formencode.Invalid, error:
             msg = error.error_dict['ip']
             h.flash(msg, category='error')
@@ -499,7 +478,7 @@
         user_model = UserModel()
         user_model.delete_extra_ip(id, ip_id)
         Session().commit()
-        h.flash(_("Removed ip address from user whitelist"), category='success')
+        h.flash(_("Removed IP address from user whitelist"), category='success')
 
         if 'default_user' in request.POST:
             return redirect(url('admin_permissions_ips'))
--- a/kallithea/controllers/api/__init__.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/api/__init__.py	Tue Jun 09 22:46:40 2015 +0200
@@ -134,7 +134,7 @@
                                  message="JSON parse error ERR:%s RAW:%r"
                                  % (e, raw_body))
 
-        # check AUTH based on API KEY
+        # check AUTH based on API key
         try:
             self._req_api_key = json_body['api_key']
             self._req_id = json_body['id']
@@ -156,7 +156,7 @@
             u = User.get_by_api_key(self._req_api_key)
             if u is None:
                 return jsonrpc_error(retid=self._req_id,
-                                     message='Invalid API KEY')
+                                     message='Invalid API key')
 
             #check if we are allowed to use this IP
             auth_u = AuthUser(u.user_id, self._req_api_key, ip_addr=ip_addr)
@@ -168,7 +168,7 @@
 
         except Exception, e:
             return jsonrpc_error(retid=self._req_id,
-                                 message='Invalid API KEY')
+                                 message='Invalid API key')
 
         self._error = None
         try:
@@ -208,7 +208,7 @@
         # get our arglist and check if we provided them as args
         for arg, default in func_kwargs.iteritems():
             if arg == USER_SESSION_ATTR:
-                # USER_SESSION_ATTR is something translated from api key and
+                # USER_SESSION_ATTR is something translated from API key and
                 # this is checked before so we don't need validate it
                 continue
 
--- a/kallithea/controllers/api/api.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/api/api.py	Tue Jun 09 22:46:40 2015 +0200
@@ -553,7 +553,7 @@
                     {
                         "user_id" :     "<user_id>",
                         "api_key" :     "<api_key>",
-                        "api_keys":     "[<list of all api keys including additional ones>]"
+                        "api_keys":     "[<list of all API keys including additional ones>]"
                         "username" :    "<username>",
                         "firstname":    "<firstname>",
                         "lastname" :    "<lastname>",
--- a/kallithea/controllers/changeset.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/changeset.py	Tue Jun 09 22:46:40 2015 +0200
@@ -166,7 +166,7 @@
     if ig_ws:
         params[ig_ws_key] += [ig_ws_val]
 
-    lbl = _('increase diff context to %(num)s lines') % {'num': ln_ctx}
+    lbl = _('Increase diff context to %(num)s lines') % {'num': ln_ctx}
 
     params['anchor'] = fileid
     icon = h.literal('<i class="icon-sort"></i>')
@@ -349,9 +349,9 @@
     @jsonify
     def comment(self, repo_name, revision):
         status = request.POST.get('changeset_status')
-        text = request.POST.get('text', '').strip() or _('No comments.')
+        text = request.POST.get('text', '').strip()
 
-        c.co = comm = ChangesetCommentsModel().create(
+        c.comment = comment = ChangesetCommentsModel().create(
             text=text,
             repo=c.db_repo.repo_id,
             user=c.authuser.user_id,
@@ -373,7 +373,7 @@
                     c.db_repo.repo_id,
                     status,
                     c.authuser.user_id,
-                    comm,
+                    comment,
                     revision=revision,
                     dont_allow_on_closed_pull_request=True
                 )
@@ -397,8 +397,8 @@
         data = {
            'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
         }
-        if comm:
-            data.update(comm.get_dict())
+        if comment:
+            data.update(comment.get_dict())
             data.update({'rendered_text':
                          render('changeset/changeset_comment_block.html')})
 
--- a/kallithea/controllers/error.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/error.py	Tue Jun 09 22:46:40 2015 +0200
@@ -32,7 +32,7 @@
 
 from pylons import tmpl_context as c, request, config
 from pylons.i18n.translation import _
-from pylons.middleware import  media_path
+from pylons.middleware import media_path
 
 from kallithea.lib.base import BaseController, render
 
@@ -50,7 +50,7 @@
     """
 
     def __before__(self):
-        #disable all base actions since we don't need them here
+        # disable all base actions since we don't need them here
         pass
 
     def document(self):
@@ -60,12 +60,16 @@
         log.debug('### %s ###' % (resp and resp.status or 'no response'))
 
         e = request.environ
-        c.serv_p = r'%(protocol)s://%(host)s/' \
-                                    % {'protocol': e.get('wsgi.url_scheme'),
-                                       'host': e.get('HTTP_HOST'), }
-
-        c.error_message = resp and cgi.escape(request.GET.get('code', str(resp.status)))
-        c.error_explanation = resp and self.get_error_explanation(resp.status_int)
+        c.serv_p = r'%(protocol)s://%(host)s/' % {
+            'protocol': e.get('wsgi.url_scheme'),
+            'host': e.get('HTTP_HOST'), }
+        if resp:
+            c.error_message = cgi.escape(request.GET.get('code',
+                                                         str(resp.status)))
+            c.error_explanation = self.get_error_explanation(resp.status_int)
+        else:
+            c.error_message = _('No response')
+            c.error_explanation = _('Unknown error')
 
         return render('/errors/error_document.html')
 
--- a/kallithea/controllers/journal.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/journal.py	Tue Jun 09 22:46:40 2015 +0200
@@ -108,11 +108,11 @@
         journal = self._get_journal_data(repos)
         if public:
             _link = h.canonical_url('public_journal_atom')
-            _desc = '%s %s %s' % (c.site_name, _('public journal'),
+            _desc = '%s %s %s' % (c.site_name, _('Public Journal'),
                                   'atom feed')
         else:
             _link = h.canonical_url('journal_atom')
-            _desc = '%s %s %s' % (c.site_name, _('journal'), 'atom feed')
+            _desc = '%s %s %s' % (c.site_name, _('Journal'), 'atom feed')
 
         feed = Atom1Feed(title=_desc,
                          link=_link,
@@ -150,11 +150,11 @@
         journal = self._get_journal_data(repos)
         if public:
             _link = h.canonical_url('public_journal_atom')
-            _desc = '%s %s %s' % (c.site_name, _('public journal'),
+            _desc = '%s %s %s' % (c.site_name, _('Public Journal'),
                                   'rss feed')
         else:
             _link = h.canonical_url('journal_atom')
-            _desc = '%s %s %s' % (c.site_name, _('journal'), 'rss feed')
+            _desc = '%s %s %s' % (c.site_name, _('Journal'), 'rss feed')
 
         feed = Rss201rev2Feed(title=_desc,
                          link=_link,
--- a/kallithea/controllers/login.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/login.py	Tue Jun 09 22:46:40 2015 +0200
@@ -42,6 +42,7 @@
 from kallithea.lib.auth_modules import importplugin
 from kallithea.lib.base import BaseController, render
 from kallithea.lib.exceptions import UserCreationError
+from kallithea.lib.utils2 import safe_str
 from kallithea.model.db import User, Setting
 from kallithea.model.forms import LoginForm, RegisterForm, PasswordResetForm
 from kallithea.model.user import UserModel
@@ -102,9 +103,14 @@
             came_from = url('home')
         return came_from
 
+    def _redirect_to_origin(self, origin, headers=None):
+        '''redirect to the original page, preserving any get arguments given'''
+        request.GET.pop('came_from', None)
+        raise HTTPFound(location=url(origin, **request.GET), headers=headers)
+
     def index(self):
         _default_came_from = url('home')
-        came_from = self._validate_came_from(request.GET.get('came_from'))
+        came_from = self._validate_came_from(safe_str(request.GET.get('came_from', '')))
         c.came_from = came_from or _default_came_from
 
         not_default = self.authuser.username != User.DEFAULT_USER
@@ -112,7 +118,7 @@
 
         # redirect if already logged in
         if self.authuser.is_authenticated and not_default and ip_allowed:
-            raise HTTPFound(location=c.came_from)
+            return self._redirect_to_origin(c.came_from)
 
         if request.POST:
             # import Login Form validator class
@@ -124,7 +130,8 @@
                 headers = self._store_user_in_session(
                                         username=c.form_result['username'],
                                         remember=c.form_result['remember'])
-                raise HTTPFound(location=c.came_from, headers=headers)
+                return self._redirect_to_origin(c.came_from, headers)
+
             except formencode.Invalid, errors:
                 defaults = errors.value
                 # remove password from filling in form again
@@ -157,7 +164,8 @@
 
             if auth_info:
                 headers = self._store_user_in_session(auth_info.get('username'))
-                raise HTTPFound(location=c.came_from, headers=headers)
+                return self._redirect_to_origin(c.came_from, headers)
+
         return render('/login.html')
 
     @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
@@ -185,7 +193,7 @@
                                       remoteip=self.ip_addr)
                     if c.captcha_active and not response.is_valid:
                         _value = form_result
-                        _msg = _('bad captcha')
+                        _msg = _('Bad captcha')
                         error_dict = {'recaptcha_field': _msg}
                         raise formencode.Invalid(_msg, _value, None,
                                                  error_dict=error_dict)
@@ -231,7 +239,7 @@
                                       remoteip=self.ip_addr)
                     if c.captcha_active and not response.is_valid:
                         _value = form_result
-                        _msg = _('bad captcha')
+                        _msg = _('Bad captcha')
                         error_dict = {'recaptcha_field': _msg}
                         raise formencode.Invalid(_msg, _value, None,
                                                  error_dict=error_dict)
--- a/kallithea/controllers/pullrequests.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/pullrequests.py	Tue Jun 09 22:46:40 2015 +0200
@@ -696,11 +696,11 @@
         if allowed_to_change_status:
             status = request.POST.get('changeset_status')
             close_pr = request.POST.get('save_close')
-        text = request.POST.get('text', '').strip() or _('No comments.')
+        text = request.POST.get('text', '').strip()
         if close_pr:
             text = _('Closing.') + '\n' + text
 
-        comm = ChangesetCommentsModel().create(
+        comment = ChangesetCommentsModel().create(
             text=text,
             repo=c.db_repo.repo_id,
             user=c.authuser.user_id,
@@ -723,7 +723,7 @@
                     c.db_repo.repo_id,
                     status,
                     c.authuser.user_id,
-                    comm,
+                    comment,
                     pull_request=pull_request_id
                 )
 
@@ -741,9 +741,9 @@
         data = {
            'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
         }
-        if comm:
-            c.co = comm
-            data.update(comm.get_dict())
+        if comment:
+            c.comment = comment
+            data.update(comment.get_dict())
             data.update({'rendered_text':
                          render('changeset/changeset_comment_block.html')})
 
--- a/kallithea/controllers/summary.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/controllers/summary.py	Tue Jun 09 22:46:40 2015 +0200
@@ -67,25 +67,6 @@
     def __before__(self):
         super(SummaryController, self).__before__()
 
-    def _get_download_links(self, repo):
-
-        download_l = []
-
-        branches_group = ([], _("Branches"))
-        tags_group = ([], _("Tags"))
-
-        for name, chs in c.db_repo_scm_instance.branches.items():
-            #chs = chs.split(':')[-1]
-            branches_group[0].append((chs, name),)
-        download_l.append(branches_group)
-
-        for name, chs in c.db_repo_scm_instance.tags.items():
-            #chs = chs.split(':')[-1]
-            tags_group[0].append((chs, name),)
-        download_l.append(tags_group)
-
-        return download_l
-
     def __get_readme_data(self, db_repo):
         repo_name = db_repo.repo_name
         log.debug('Looking for README file')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/i18n/be/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,5922 @@
+# Translations template for Kallithea.
+# Copyright (C) 2015 Various authors, licensing as GPLv3
+# This file is distributed under the same license as the Kallithea project.
+# Automatically generated, 2015.
+# #, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Kallithea 0.1\n"
+"Report-Msgid-Bugs-To: translations@kallithea-scm.org\n"
+"POT-Creation-Date: 2015-04-01 03:17+0200\n"
+"PO-Revision-Date: 2015-05-13 09:51+0200\n"
+"Last-Translator: Viktar Palstsiuk <vipals@gmail.com>\n"
+"Language-Team: Belarusian "
+"<https://hosted.weblate.org/projects/kallithea/kallithea/be/>\n"
+"Language: be\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<="
+"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 2.3-dev\n"
+
+#: kallithea/controllers/changelog.py:86
+#: kallithea/controllers/pullrequests.py:247 kallithea/lib/base.py:449
+msgid "There are no changesets yet"
+msgstr "Яшчэ не было змен"
+
+#: kallithea/controllers/changelog.py:157
+#: kallithea/controllers/admin/permissions.py:62
+#: kallithea/controllers/admin/permissions.py:66
+#: kallithea/controllers/admin/permissions.py:70
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:104
+msgid "None"
+msgstr "Нічога"
+
+#: kallithea/controllers/changelog.py:160 kallithea/controllers/files.py:197
+msgid "(closed)"
+msgstr "(зачынена)"
+
+#: kallithea/controllers/changeset.py:89
+msgid "Show whitespace"
+msgstr "Адлюстроўваць прабелы"
+
+#: kallithea/controllers/changeset.py:96
+#: kallithea/controllers/changeset.py:103
+#: kallithea/templates/files/diff_2way.html:55
+msgid "Ignore whitespace"
+msgstr "Ігнараваць прабелы"
+
+#: kallithea/controllers/changeset.py:169
+#, python-format
+msgid "increase diff context to %(num)s lines"
+msgstr "павялічыць кантэкст да %(num)s радкоў"
+
+#: kallithea/controllers/changeset.py:212 kallithea/controllers/files.py:97
+#: kallithea/controllers/files.py:117 kallithea/controllers/files.py:746
+msgid "Such revision does not exist for this repository"
+msgstr "Няма такой рэвізіі ў гэтым рэпазітары"
+
+#: kallithea/controllers/changeset.py:352
+#: kallithea/controllers/pullrequests.py:699
+msgid "No comments."
+msgstr "Няма каментароў."
+
+#: kallithea/controllers/changeset.py:382
+msgid ""
+"Changing status on a changeset associated with a closed pull request is not "
+"allowed"
+msgstr "Нельга рэдагаваць статут змен, злучаных з зачыненымі pull-request'ами"
+
+#: kallithea/controllers/compare.py:158 kallithea/templates/base/root.html:42
+msgid "Select changeset"
+msgstr "Абраць набор змен"
+
+#: kallithea/controllers/compare.py:255
+msgid "Cannot compare repositories without using common ancestor"
+msgstr "Немагчыма параўноўваць рэпазітары без агульнага продка"
+
+#: kallithea/controllers/error.py:96
+msgid ""
+"The request could not be understood by the server due to malformed syntax."
+msgstr "Запыт не распазнаны серверам з-за няправільнага сінтаксісу."
+
+#: kallithea/controllers/error.py:99
+msgid "Unauthorized access to resource"
+msgstr "Несанкцыянаваны доступ да рэсурсу"
+
+#: kallithea/controllers/error.py:101
+msgid "You don't have permission to view this page"
+msgstr "У вас няма правоў для прагляду гэтай старонкі"
+
+#: kallithea/controllers/error.py:103
+msgid "The resource could not be found"
+msgstr "Рэсурс не знойдзены"
+
+#: kallithea/controllers/error.py:105
+msgid ""
+"The server encountered an unexpected condition which prevented it from "
+"fulfilling the request."
+msgstr "Сервер не можа выканаць запыт з-за няправільнай умовы ў запыце."
+
+#: kallithea/controllers/feed.py:55
+#, python-format
+msgid "Changes on %s repository"
+msgstr "Змены ў рэпазітары %s"
+
+#: kallithea/controllers/feed.py:56
+#, python-format
+msgid "%s %s feed"
+msgstr "Стужка навін %s %s"
+
+#: kallithea/controllers/feed.py:89
+#: kallithea/templates/changeset/changeset.html:153
+#: kallithea/templates/changeset/changeset.html:166
+#: kallithea/templates/compare/compare_diff.html:78
+#: kallithea/templates/compare/compare_diff.html:89
+#: kallithea/templates/pullrequests/pullrequest_show.html:328
+#: kallithea/templates/pullrequests/pullrequest_show.html:351
+msgid "Changeset was too big and was cut off..."
+msgstr "Змены апынуліся занадта вялікімі і былі выразаны..."
+
+#: kallithea/controllers/feed.py:93
+#, python-format
+msgid "%s committed on %s"
+msgstr "%s выканаў каміт у %s"
+
+#: kallithea/controllers/files.py:92
+msgid "Click here to add new file"
+msgstr "Націсніце каб дадаць новы файл"
+
+#: kallithea/controllers/files.py:93
+#, python-format
+msgid "There are no files yet. %s"
+msgstr "Няма файлаў. %s"
+
+#: kallithea/controllers/files.py:194
+#, python-format
+msgid "%s at %s"
+msgstr "%s (%s)"
+
+#: kallithea/controllers/files.py:306 kallithea/controllers/files.py:366
+#: kallithea/controllers/files.py:433
+#, python-format
+msgid "This repository has been locked by %s on %s"
+msgstr "Рэпазітар заблакаваў %s у %s"
+
+#: kallithea/controllers/files.py:318
+msgid "You can only delete files with revision being a valid branch "
+msgstr "Вы можаце выдаляць файлы толькі ў рэвізіі, злучанай з існай галінкай "
+
+#: kallithea/controllers/files.py:329
+#, python-format
+msgid "Deleted file %s via Kallithea"
+msgstr "Файл %s выдалены з дапамогай Kallithea"
+
+#: kallithea/controllers/files.py:351
+#, python-format
+msgid "Successfully deleted file %s"
+msgstr "Файл %s выдалены"
+
+#: kallithea/controllers/files.py:355 kallithea/controllers/files.py:421
+#: kallithea/controllers/files.py:502
+msgid "Error occurred during commit"
+msgstr "Падчас каміта адбылася памылка"
+
+#: kallithea/controllers/files.py:378
+msgid "You can only edit files with revision being a valid branch "
+msgstr "Вы можаце рэдагаваць файлы толькі ў рэвізіі, злучанай з існай галінкай "
+
+#: kallithea/controllers/files.py:392
+#, python-format
+msgid "Edited file %s via Kallithea"
+msgstr "Файл %s адрэдагаваны з дапамогай Kallithea"
+
+#: kallithea/controllers/files.py:408
+msgid "No changes"
+msgstr "Без змен"
+
+#: kallithea/controllers/files.py:417 kallithea/controllers/files.py:491
+#, python-format
+msgid "Successfully committed to %s"
+msgstr "Змены ўжыты ў %s"
+
+#: kallithea/controllers/files.py:444
+msgid "Added file via Kallithea"
+msgstr "Файл дададзены з дапамогай Kallithea"
+
+#: kallithea/controllers/files.py:465
+msgid "No content"
+msgstr "Пуста"
+
+#: kallithea/controllers/files.py:469
+msgid "No filename"
+msgstr "Безназоўны"
+
+#: kallithea/controllers/files.py:494
+msgid "Location must be relative path and must not contain .. in path"
+msgstr ""
+"Размяшчэнне павінна быць адносным шляхам, і не павінна ўтрымоўваць \"..\" у "
+"шляхі"
+
+#: kallithea/controllers/files.py:528
+msgid "Downloads disabled"
+msgstr "Магчымасць спампоўваць адключана"
+
+#: kallithea/controllers/files.py:539
+#, python-format
+msgid "Unknown revision %s"
+msgstr "Невядомая рэвізія %s"
+
+#: kallithea/controllers/files.py:541
+msgid "Empty repository"
+msgstr "Пусты рэпазітар"
+
+#: kallithea/controllers/files.py:543
+msgid "Unknown archive type"
+msgstr "Невядомы тып архіва"
+
+#: kallithea/controllers/files.py:775
+#: kallithea/templates/changeset/changeset_range.html:9
+#: kallithea/templates/email_templates/pull_request.html:15
+#: kallithea/templates/pullrequests/pullrequest.html:116
+msgid "Changesets"
+msgstr "Набор змен"
+
+#: kallithea/controllers/files.py:776
+#: kallithea/controllers/pullrequests.py:182
+#: kallithea/controllers/summary.py:74 kallithea/model/scm.py:816
+#: kallithea/templates/switch_to_list.html:3
+#: kallithea/templates/branches/branches.html:10
+msgid "Branches"
+msgstr "Галінкі"
+
+#: kallithea/controllers/files.py:777
+#: kallithea/controllers/pullrequests.py:183
+#: kallithea/controllers/summary.py:75 kallithea/model/scm.py:827
+#: kallithea/templates/switch_to_list.html:25
+#: kallithea/templates/tags/tags.html:10
+msgid "Tags"
+msgstr "Пазнакі"
+
+#: kallithea/controllers/forks.py:187
+#, python-format
+msgid "An error occurred during repository forking %s"
+msgstr "Адбылася памылка падчас стварэння форка рэпазітара %s"
+
+#: kallithea/controllers/home.py:84
+msgid "Groups"
+msgstr "Групы"
+
+#: kallithea/controllers/home.py:89
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:106
+#: kallithea/templates/admin/repos/repo_add.html:12
+#: kallithea/templates/admin/repos/repo_add.html:16
+#: kallithea/templates/admin/repos/repos.html:9
+#: kallithea/templates/admin/users/user_edit_advanced.html:6
+#: kallithea/templates/base/base.html:60 kallithea/templates/base/base.html:77
+#: kallithea/templates/base/base.html:127
+#: kallithea/templates/base/base.html:390
+#: kallithea/templates/base/base.html:562
+msgid "Repositories"
+msgstr "Рэпазітары"
+
+#: kallithea/controllers/home.py:130
+#: kallithea/templates/files/files_add.html:32
+#: kallithea/templates/files/files_delete.html:23
+#: kallithea/templates/files/files_edit.html:32
+msgid "Branch"
+msgstr "Галінка"
+
+#: kallithea/controllers/home.py:136
+msgid "Tag"
+msgstr "Тэгі"
+
+#: kallithea/controllers/home.py:142
+msgid "Bookmark"
+msgstr "Закладкі"
+
+#: kallithea/controllers/journal.py:111 kallithea/controllers/journal.py:153
+msgid "public journal"
+msgstr "агульнадаступны часопіс"
+
+#: kallithea/controllers/journal.py:115 kallithea/controllers/journal.py:157
+msgid "journal"
+msgstr "часопіс"
+
+#: kallithea/controllers/login.py:188 kallithea/controllers/login.py:234
+msgid "bad captcha"
+msgstr "няслушная капча"
+
+#: kallithea/controllers/login.py:194
+msgid "You have successfully registered into Kallithea"
+msgstr "Рэгістрацыя ў Kallithea прайшла паспяхова"
+
+#: kallithea/controllers/login.py:239
+msgid "Your password reset link was sent"
+msgstr "Спасылка для скіду пароля адпраўлена"
+
+#: kallithea/controllers/login.py:260
+msgid ""
+"Your password reset was successful, new password has been sent to your email"
+msgstr "Скід пароля выраблены, новы пароль быў адпраўлены на ваш email"
+
+#: kallithea/controllers/pullrequests.py:130
+#, python-format
+msgid "%s (closed)"
+msgstr "%s (зачынена)"
+
+#: kallithea/controllers/pullrequests.py:158
+#: kallithea/templates/changeset/changeset.html:12
+#: kallithea/templates/email_templates/changeset_comment.html:17
+msgid "Changeset"
+msgstr "Змены"
+
+#: kallithea/controllers/pullrequests.py:179
+msgid "Special"
+msgstr "Адмысловы"
+
+#: kallithea/controllers/pullrequests.py:180
+msgid "Peer branches"
+msgstr "Галінкі ўдзельніка"
+
+#: kallithea/controllers/pullrequests.py:181 kallithea/model/scm.py:822
+#: kallithea/templates/switch_to_list.html:38
+#: kallithea/templates/bookmarks/bookmarks.html:10
+msgid "Bookmarks"
+msgstr "Закладкі"
+
+#: kallithea/controllers/pullrequests.py:312
+#, python-format
+msgid "Error creating pull request: %s"
+msgstr "Памылка пры стварэнні pull-запыту: %s"
+
+#: kallithea/controllers/pullrequests.py:356
+#: kallithea/controllers/pullrequests.py:497
+msgid "No description"
+msgstr "Няма апісання"
+
+#: kallithea/controllers/pullrequests.py:363
+msgid "Successfully opened new pull request"
+msgstr "Pull-запыт створаны паспяхова"
+
+#: kallithea/controllers/pullrequests.py:366
+#: kallithea/controllers/pullrequests.py:450
+msgid "Error occurred while creating pull request"
+msgstr "Адбылася памылка пры стварэнні pull-запыту"
+
+#: kallithea/controllers/pullrequests.py:398
+msgid "Missing changesets since the previous pull request:"
+msgstr "Адсутныя рэвізіі адносна папярэдняга pull-запыту:"
+
+#: kallithea/controllers/pullrequests.py:405
+#, python-format
+msgid "New changesets on %s %s since the previous pull request:"
+msgstr "Новыя рэвізіі на %s %s адносна папярэдняга pull-запыту:"
+
+#: kallithea/controllers/pullrequests.py:412
+msgid "Ancestor didn't change - show diff since previous version:"
+msgstr ""
+
+#: kallithea/controllers/pullrequests.py:419
+#, python-format
+msgid ""
+"This pull request is based on another %s revision and there is no simple "
+"diff."
+msgstr "Гэты pull-запыт заснаваны на іншай рэвізіі %s, просты diff немагчымы."
+
+#: kallithea/controllers/pullrequests.py:421
+#, python-format
+msgid "No changes found on %s %s since previous version."
+msgstr "Няма змен на %s %s адносна папярэдняй версіі."
+
+#: kallithea/controllers/pullrequests.py:456
+#, python-format
+msgid "Closed, replaced by %s ."
+msgstr "Зачынены, замешчаны %s ."
+
+#: kallithea/controllers/pullrequests.py:464
+msgid "Pull request update created"
+msgstr "Абнаўленне для pull-запыту створана"
+
+#: kallithea/controllers/pullrequests.py:503
+msgid "Pull request updated"
+msgstr "Pull-запыт абноўлены"
+
+#: kallithea/controllers/pullrequests.py:518
+msgid "Successfully deleted pull request"
+msgstr "Pull-запыт паспяхова выдалены"
+
+#: kallithea/controllers/pullrequests.py:577
+#, python-format
+msgid "This pull request has already been merged to %s."
+msgstr "Гэты pull-запыт ужо прыняты на галінку %s."
+
+#: kallithea/controllers/pullrequests.py:579
+msgid "This pull request has been closed and can not be updated."
+msgstr "Гэты pull-запыт быў зачынены і не можа быць абноўлены."
+
+#: kallithea/controllers/pullrequests.py:597
+#, python-format
+msgid "This pull request can be updated with changes on %s:"
+msgstr "Гэты pull-запыт можа быць абноўлены з %s:"
+
+#: kallithea/controllers/pullrequests.py:600
+msgid "No changesets found for updating this pull request."
+msgstr "Няма змен для абнаўлення гэтага pull-запыту."
+
+#: kallithea/controllers/pullrequests.py:608
+#, python-format
+msgid "Note: Branch %s has another head: %s."
+msgstr "Увага: Галінка %s мае яшчэ адну верхавіну: %s."
+
+#: kallithea/controllers/pullrequests.py:614
+msgid "Git pull requests don't support updates yet."
+msgstr "Абнаўленне pull-запыты git не падтрымліваецца."
+
+#: kallithea/controllers/pullrequests.py:701
+msgid "Closing."
+msgstr "Зачынены."
+
+#: kallithea/controllers/search.py:135
+msgid "Invalid search query. Try quoting it."
+msgstr "Недапушчальны пошукавы запыт. Паспрабуйце скласці яго ў двукоссі."
+
+#: kallithea/controllers/search.py:140
+msgid "There is no index to search in. Please run whoosh indexer"
+msgstr "Індэксы адсутнічаюць. Калі ласка, запусціце індэксатар Whoosh"
+
+#: kallithea/controllers/search.py:144
+msgid "An error occurred during search operation."
+msgstr "Адбылася памылка пры выкананні гэтага пошуку."
+
+#: kallithea/controllers/summary.py:199
+#: kallithea/templates/summary/summary.html:387
+msgid "No data ready yet"
+msgstr "Няма дадзеных"
+
+#: kallithea/controllers/summary.py:202
+#: kallithea/templates/summary/summary.html:101
+msgid "Statistics are disabled for this repository"
+msgstr "Статыстычныя дадзеныя адключаны для гэтага рэпазітара"
+
+#: kallithea/controllers/admin/auth_settings.py:125
+msgid "Auth settings updated successfully"
+msgstr "Налады аўтарызацыі паспяхова абноўлены"
+
+#: kallithea/controllers/admin/auth_settings.py:136
+msgid "error occurred during update of auth settings"
+msgstr "адбылася памылка пры абнаўленні налад аўтарызацыі"
+
+#: kallithea/controllers/admin/defaults.py:97
+msgid "Default settings updated successfully"
+msgstr "Стандартныя налады паспяхова абноўлены"
+
+#: kallithea/controllers/admin/defaults.py:112
+msgid "Error occurred during update of defaults"
+msgstr "Адбылася памылка пры абнаўленні стандартных налад"
+
+#: kallithea/controllers/admin/gists.py:59
+#: kallithea/controllers/admin/my_account.py:238
+#: kallithea/controllers/admin/users.py:288
+msgid "forever"
+msgstr "назаўжды"
+
+#: kallithea/controllers/admin/gists.py:60
+#: kallithea/controllers/admin/my_account.py:239
+#: kallithea/controllers/admin/users.py:289
+msgid "5 minutes"
+msgstr "5 хвілін"
+
+#: kallithea/controllers/admin/gists.py:61
+#: kallithea/controllers/admin/my_account.py:240
+#: kallithea/controllers/admin/users.py:290
+msgid "1 hour"
+msgstr "1 гадзіна"
+
+#: kallithea/controllers/admin/gists.py:62
+#: kallithea/controllers/admin/my_account.py:241
+#: kallithea/controllers/admin/users.py:291
+msgid "1 day"
+msgstr "1 дзень"
+
+#: kallithea/controllers/admin/gists.py:63
+#: kallithea/controllers/admin/my_account.py:242
+#: kallithea/controllers/admin/users.py:292
+msgid "1 month"
+msgstr "1 месяц"
+
+#: kallithea/controllers/admin/gists.py:67
+#: kallithea/controllers/admin/my_account.py:244
+#: kallithea/controllers/admin/users.py:294
+msgid "Lifetime"
+msgstr "Тэрмін"
+
+#: kallithea/controllers/admin/gists.py:146
+msgid "Error occurred during gist creation"
+msgstr "Адбылася памылка падчас стварэння gist-запіса"
+
+#: kallithea/controllers/admin/gists.py:184
+#, python-format
+msgid "Deleted gist %s"
+msgstr "Gist-запіс %s выдалены"
+
+#: kallithea/controllers/admin/gists.py:233
+msgid "unmodified"
+msgstr ""
+
+#: kallithea/controllers/admin/gists.py:262
+msgid "Successfully updated gist content"
+msgstr ""
+
+#: kallithea/controllers/admin/gists.py:267
+msgid "Successfully updated gist data"
+msgstr "Дадзеныя gist-запісы абноўлены"
+
+#: kallithea/controllers/admin/gists.py:270
+#, python-format
+msgid "Error occurred during update of gist %s"
+msgstr "Адбылася памылка пры абнаўленні gist-запісы %s"
+
+#: kallithea/controllers/admin/my_account.py:70
+msgid "You can't edit this user since it's crucial for entire application"
+msgstr ""
+"Вы не можаце змяніць дадзеныя гэтага карыстача, паколькі ён важны для працы "
+"ўсяго прыкладання"
+
+#: kallithea/controllers/admin/my_account.py:128
+msgid "Your account was updated successfully"
+msgstr "Ваш уліковы запіс паспяхова абноўлены"
+
+#: kallithea/controllers/admin/my_account.py:143
+#: kallithea/controllers/admin/users.py:206
+#, python-format
+msgid "Error occurred during update of user %s"
+msgstr "Адбылася памылка пры абнаўленні карыстача %s"
+
+#: kallithea/controllers/admin/my_account.py:162
+msgid "Successfully updated password"
+msgstr "Пароль абноўлены"
+
+#: kallithea/controllers/admin/my_account.py:173
+msgid "Error occurred during update of user password"
+msgstr "Памылка пры абнаўленні пароля"
+
+#: kallithea/controllers/admin/my_account.py:215
+#: kallithea/controllers/admin/users.py:431
+#, python-format
+msgid "Added email %s to user"
+msgstr "Карыстачу дададзены e-mail %s"
+
+#: kallithea/controllers/admin/my_account.py:221
+#: kallithea/controllers/admin/users.py:437
+msgid "An error occurred during email saving"
+msgstr "Адбылася памылка пры захаванні e-mail"
+
+#: kallithea/controllers/admin/my_account.py:230
+#: kallithea/controllers/admin/users.py:448
+msgid "Removed email from user"
+msgstr "E-mail карыстача выдалены"
+
+#: kallithea/controllers/admin/my_account.py:254
+#: kallithea/controllers/admin/users.py:314
+msgid "Api key successfully created"
+msgstr "API-ключ паспяхова створаны"
+
+#: kallithea/controllers/admin/my_account.py:266
+#: kallithea/controllers/admin/users.py:330
+msgid "Api key successfully reset"
+msgstr "API-ключ паспяхова скінуты"
+
+#: kallithea/controllers/admin/my_account.py:270
+#: kallithea/controllers/admin/users.py:334
+msgid "Api key successfully deleted"
+msgstr "API-ключ паспяхова выдалены"
+
+#: kallithea/controllers/admin/permissions.py:63
+#: kallithea/controllers/admin/permissions.py:67
+#: kallithea/controllers/admin/permissions.py:71
+msgid "Read"
+msgstr "Чытанне"
+
+#: kallithea/controllers/admin/permissions.py:64
+#: kallithea/controllers/admin/permissions.py:68
+#: kallithea/controllers/admin/permissions.py:72
+msgid "Write"
+msgstr "Запіс"
+
+#: kallithea/controllers/admin/permissions.py:65
+#: kallithea/controllers/admin/permissions.py:69
+#: kallithea/controllers/admin/permissions.py:73
+#: kallithea/templates/admin/auth/auth_settings.html:9
+#: kallithea/templates/admin/defaults/defaults.html:9
+#: kallithea/templates/admin/permissions/permissions.html:9
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:9
+#: kallithea/templates/admin/repo_groups/repo_group_edit.html:9
+#: kallithea/templates/admin/repo_groups/repo_groups.html:10
+#: kallithea/templates/admin/repos/repo_add.html:10
+#: kallithea/templates/admin/repos/repo_add.html:14
+#: kallithea/templates/admin/repos/repos.html:9
+#: kallithea/templates/admin/settings/settings.html:9
+#: kallithea/templates/admin/user_groups/user_group_add.html:8
+#: kallithea/templates/admin/user_groups/user_group_edit.html:9
+#: kallithea/templates/admin/user_groups/user_groups.html:10
+#: kallithea/templates/admin/users/user_add.html:8
+#: kallithea/templates/admin/users/user_edit.html:9
+#: kallithea/templates/admin/users/user_edit_profile.html:114
+#: kallithea/templates/admin/users/users.html:10
+#: kallithea/templates/admin/users/users.html:55
+#: kallithea/templates/base/base.html:255
+#: kallithea/templates/base/base.html:256
+#: kallithea/templates/base/base.html:262
+#: kallithea/templates/base/base.html:263
+msgid "Admin"
+msgstr "Адміністратар"
+
+#: kallithea/controllers/admin/permissions.py:76
+#: kallithea/controllers/admin/permissions.py:87
+#: kallithea/controllers/admin/permissions.py:92
+#: kallithea/controllers/admin/permissions.py:95
+#: kallithea/controllers/admin/permissions.py:98
+#: kallithea/controllers/admin/permissions.py:101
+msgid "Disabled"
+msgstr "Адключана"
+
+#: kallithea/controllers/admin/permissions.py:78
+msgid "Allowed with manual account activation"
+msgstr "Дазволена, з ручной актывацыяй уліковага запісу"
+
+#: kallithea/controllers/admin/permissions.py:80
+msgid "Allowed with automatic account activation"
+msgstr "Дазволена, з аўтаматычнай актывацыяй уліковага запісу"
+
+#: kallithea/controllers/admin/permissions.py:83
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1439
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1485
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1542
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1543
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1564
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1603
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1655
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1682 kallithea/model/db.py:1684
+msgid "Manual activation of external account"
+msgstr "Ручная актывацыя вонкавага ўліковага запісу"
+
+#: kallithea/controllers/admin/permissions.py:84
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1440
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1486
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1543
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1544
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1565
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1604
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1656
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1683 kallithea/model/db.py:1685
+msgid "Automatic activation of external account"
+msgstr "Аўтаматычная актывацыя вонкавага ўліковага запісу"
+
+#: kallithea/controllers/admin/permissions.py:88
+#: kallithea/controllers/admin/permissions.py:91
+#: kallithea/controllers/admin/permissions.py:96
+#: kallithea/controllers/admin/permissions.py:99
+#: kallithea/controllers/admin/permissions.py:102
+msgid "Enabled"
+msgstr "Уключана"
+
+#: kallithea/controllers/admin/permissions.py:125
+msgid "Global permissions updated successfully"
+msgstr "Глабальныя прывілеі паспяхова абноўлены"
+
+#: kallithea/controllers/admin/permissions.py:140
+msgid "Error occurred during update of permissions"
+msgstr "Адбылася памылка падчас абнаўлення прывілеяў"
+
+#: kallithea/controllers/admin/repo_groups.py:184
+#, python-format
+msgid "Created repository group %s"
+msgstr "Створана новая група рэпазітароў %s"
+
+#: kallithea/controllers/admin/repo_groups.py:197
+#, python-format
+msgid "Error occurred during creation of repository group %s"
+msgstr "Адбылася памылка пры стварэнні групы рэпазітароў %s"
+
+#: kallithea/controllers/admin/repo_groups.py:255
+#, python-format
+msgid "Updated repository group %s"
+msgstr "Група рэпазітароў %s абноўлена"
+
+#: kallithea/controllers/admin/repo_groups.py:271
+#, python-format
+msgid "Error occurred during update of repository group %s"
+msgstr "Адбылася памылка пры абнаўленні групы рэпазітароў %s"
+
+#: kallithea/controllers/admin/repo_groups.py:289
+#, python-format
+msgid "This group contains %s repositories and cannot be deleted"
+msgstr "Дадзеная група ўтрымоўвае %s рэпазітароў і не можа быць выдалена"
+
+#: kallithea/controllers/admin/repo_groups.py:296
+#, python-format
+msgid "This group contains %s subgroups and cannot be deleted"
+msgstr "Група ўтрымоўвае ў сабе %s падгруп і не можа быць выдалены"
+
+#: kallithea/controllers/admin/repo_groups.py:302
+#, python-format
+msgid "Removed repository group %s"
+msgstr "Група рэпазітароў %s выдалена"
+
+#: kallithea/controllers/admin/repo_groups.py:307
+#, python-format
+msgid "Error occurred during deletion of repository group %s"
+msgstr "Адбылася памылка пры выдаленні групы рэпазітароў %s"
+
+#: kallithea/controllers/admin/repo_groups.py:420
+#: kallithea/controllers/admin/repo_groups.py:455
+#: kallithea/controllers/admin/user_groups.py:340
+msgid "Cannot revoke permission for yourself as admin"
+msgstr "Адміністратар не можа адклікаць свае прывелеі"
+
+#: kallithea/controllers/admin/repo_groups.py:435
+msgid "Repository Group permissions updated"
+msgstr "Прывілеі групы рэпазітароў абноўлены"
+
+#: kallithea/controllers/admin/repo_groups.py:472
+#: kallithea/controllers/admin/repos.py:430
+#: kallithea/controllers/admin/user_groups.py:352
+msgid "An error occurred during revoking of permission"
+msgstr "Адбылася памылка пры водгуку прывелеі"
+
+#: kallithea/controllers/admin/repos.py:163
+#, python-format
+msgid "Error creating repository %s"
+msgstr "Адбылася памылка пры стварэнні рэпазітара %s"
+
+#: kallithea/controllers/admin/repos.py:238
+#, python-format
+msgid "Created repository %s from %s"
+msgstr "Рэпазітар %s створаны з %s"
+
+#: kallithea/controllers/admin/repos.py:247
+#, python-format
+msgid "Forked repository %s as %s"
+msgstr "Зроблены форк(копія) рэпазітара %s на %s"
+
+#: kallithea/controllers/admin/repos.py:250
+#, python-format
+msgid "Created repository %s"
+msgstr "Рэпазітар %s створаны"
+
+#: kallithea/controllers/admin/repos.py:290
+#, python-format
+msgid "Repository %s updated successfully"
+msgstr "Рэпазітар %s паспяхова абноўлены"
+
+#: kallithea/controllers/admin/repos.py:309
+#, python-format
+msgid "Error occurred during update of repository %s"
+msgstr "Адбылася памылка падчас абнаўлення рэпазітара %s"
+
+#: kallithea/controllers/admin/repos.py:336
+#, python-format
+msgid "Detached %s forks"
+msgstr "Форки %s адлучаны"
+
+#: kallithea/controllers/admin/repos.py:339
+#, python-format
+msgid "Deleted %s forks"
+msgstr "Выдалены форки рэпазітара %s"
+
+#: kallithea/controllers/admin/repos.py:344
+#, python-format
+msgid "Deleted repository %s"
+msgstr "Рэпазітар %s выдалены"
+
+#: kallithea/controllers/admin/repos.py:347
+#, python-format
+msgid "Cannot delete %s it still contains attached forks"
+msgstr "Немагчыма выдаліць %s, ён усё-яшчэ ўтрымоўвае форки"
+
+#: kallithea/controllers/admin/repos.py:352
+#, python-format
+msgid "An error occurred during deletion of %s"
+msgstr "Адбылася памылка падчас выдалення %s"
+
+#: kallithea/controllers/admin/repos.py:406
+msgid "Repository permissions updated"
+msgstr "Прывілеі рэпазітара абноўлены"
+
+#: kallithea/controllers/admin/repos.py:462
+msgid "An error occurred during creation of field"
+msgstr "Адбылася памылка пры стварэнні поля"
+
+#: kallithea/controllers/admin/repos.py:476
+msgid "An error occurred during removal of field"
+msgstr "Адбылася памылка пры выдаленні поля"
+
+#: kallithea/controllers/admin/repos.py:492
+msgid "-- Not a fork --"
+msgstr "-- Не форк --"
+
+#: kallithea/controllers/admin/repos.py:526
+msgid "Updated repository visibility in public journal"
+msgstr "Бачнасць рэпазітара ў публічным часопісе абноўлена"
+
+#: kallithea/controllers/admin/repos.py:530
+msgid "An error occurred during setting this repository in public journal"
+msgstr "Адбылася памылка пры ўсталёўцы рэпазітара ў агульнадаступны часопіс"
+
+#: kallithea/controllers/admin/repos.py:535 kallithea/model/validators.py:340
+msgid "Token mismatch"
+msgstr "Несупадзенне токенаў"
+
+#: kallithea/controllers/admin/repos.py:550
+msgid "Nothing"
+msgstr "Нічога"
+
+#: kallithea/controllers/admin/repos.py:552
+#, python-format
+msgid "Marked repo %s as fork of %s"
+msgstr "Рэпазітар %s адзначаны як форк %s"
+
+#: kallithea/controllers/admin/repos.py:559
+msgid "An error occurred during this operation"
+msgstr "Адбылася памылка пры выкананні аперацыі"
+
+#: kallithea/controllers/admin/repos.py:575
+msgid "Locked repository"
+msgstr "Зачынены рэпазітар"
+
+#: kallithea/controllers/admin/repos.py:578
+msgid "Unlocked repository"
+msgstr "Адкрыты рэпазітар"
+
+#: kallithea/controllers/admin/repos.py:581
+#: kallithea/controllers/admin/repos.py:608
+msgid "An error occurred during unlocking"
+msgstr "Адбылася памылка падчас разблакавання"
+
+#: kallithea/controllers/admin/repos.py:599
+msgid "Unlocked"
+msgstr "Разблакавана"
+
+#: kallithea/controllers/admin/repos.py:602
+msgid "Locked"
+msgstr "Заблакавана"
+
+#: kallithea/controllers/admin/repos.py:604
+#, python-format
+msgid "Repository has been %s"
+msgstr "Рэпазітар %s"
+
+#: kallithea/controllers/admin/repos.py:622
+msgid "Cache invalidation successful"
+msgstr "Кэш скінуты"
+
+#: kallithea/controllers/admin/repos.py:626
+msgid "An error occurred during cache invalidation"
+msgstr "Адбылася памылка пры ачыстцы кэша"
+
+#: kallithea/controllers/admin/repos.py:641
+msgid "Pulled from remote location"
+msgstr "Занесены змены з выдаленага рэпазітара"
+
+#: kallithea/controllers/admin/repos.py:644
+msgid "An error occurred during pull from remote location"
+msgstr "Адбылася памылка пры занясенні змен з выдаленага рэпазітара"
+
+#: kallithea/controllers/admin/repos.py:677
+msgid "An error occurred during deletion of repository stats"
+msgstr "Адбылася памылка пры выдаленні статыстыкі рэпазітара"
+
+#: kallithea/controllers/admin/settings.py:170
+msgid "Updated VCS settings"
+msgstr "Абноўлены налады VCS"
+
+#: kallithea/controllers/admin/settings.py:174
+msgid ""
+"Unable to activate hgsubversion support. The \"hgsubversion\" library is "
+"missing"
+msgstr ""
+"Немагчыма ўключыць падтрымку hgsubversion. Бібліятэка «hgsubversion» "
+"адсутнічае"
+
+#: kallithea/controllers/admin/settings.py:180
+#: kallithea/controllers/admin/settings.py:274
+msgid "Error occurred during updating application settings"
+msgstr "Адбылася памылка пры абнаўленні налад прыкладання"
+
+#: kallithea/controllers/admin/settings.py:213
+#, python-format
+msgid "Repositories successfully rescanned. Added: %s. Removed: %s."
+msgstr "Рэпазітары паспяхова перасканіраваны, дададзена: %s, выдалена: %s."
+
+#: kallithea/controllers/admin/settings.py:270
+msgid "Updated application settings"
+msgstr "Абноўленыя параметры налады прыкладання"
+
+#: kallithea/controllers/admin/settings.py:327
+msgid "Updated visualisation settings"
+msgstr "Налады візуалізацыі абноўлены"
+
+#: kallithea/controllers/admin/settings.py:332
+msgid "Error occurred during updating visualisation settings"
+msgstr "Адбылася памылка пры абнаўленні налад візуалізацыі"
+
+#: kallithea/controllers/admin/settings.py:358
+msgid "Please enter email address"
+msgstr "Калі ласка, увядзіце адрас электроннай пошты"
+
+#: kallithea/controllers/admin/settings.py:373
+msgid "Send email task created"
+msgstr "Задача адпраўкі Email створана"
+
+#: kallithea/controllers/admin/settings.py:404
+msgid "Added new hook"
+msgstr "Дададзена новая пастка"
+
+#: kallithea/controllers/admin/settings.py:418
+msgid "Updated hooks"
+msgstr "Абноўленыя пасткі"
+
+#: kallithea/controllers/admin/settings.py:422
+msgid "Error occurred during hook creation"
+msgstr "адбылася памылка пры стварэнні хука"
+
+#: kallithea/controllers/admin/settings.py:448
+msgid "Whoosh reindex task scheduled"
+msgstr "Запланавана пераіндэксаванне базы Whoosh"
+
+#: kallithea/controllers/admin/user_groups.py:150
+#, python-format
+msgid "Created user group %s"
+msgstr "Створана група карыстачоў %s"
+
+#: kallithea/controllers/admin/user_groups.py:163
+#, python-format
+msgid "Error occurred during creation of user group %s"
+msgstr "Адбылася памылка пры стварэнні групы карыстачоў %s"
+
+#: kallithea/controllers/admin/user_groups.py:201
+#, python-format
+msgid "Updated user group %s"
+msgstr "Група карыстачоў %s абноўлена"
+
+#: kallithea/controllers/admin/user_groups.py:224
+#, python-format
+msgid "Error occurred during update of user group %s"
+msgstr "Адбылася памылка пры абнаўленні групы карыстачоў %s"
+
+#: kallithea/controllers/admin/user_groups.py:242
+msgid "Successfully deleted user group"
+msgstr "Група карыстачоў паспяхова выдалена"
+
+#: kallithea/controllers/admin/user_groups.py:247
+msgid "An error occurred during deletion of user group"
+msgstr "Адбылася памылка пры выдаленні групы карыстачоў"
+
+#: kallithea/controllers/admin/user_groups.py:314
+msgid "Target group cannot be the same"
+msgstr "Мэтавая група не можа быць такі ж"
+
+#: kallithea/controllers/admin/user_groups.py:320
+msgid "User Group permissions updated"
+msgstr "Прывілеі групы карыстачоў абноўлены"
+
+#: kallithea/controllers/admin/user_groups.py:440
+#: kallithea/controllers/admin/users.py:396
+msgid "Updated permissions"
+msgstr "Абноўлены прывілеі"
+
+#: kallithea/controllers/admin/user_groups.py:444
+#: kallithea/controllers/admin/users.py:400
+msgid "An error occurred during permissions saving"
+msgstr "Адбылася памылка пры захаванні прывілеяў"
+
+#: kallithea/controllers/admin/users.py:132
+#, python-format
+msgid "Created user %s"
+msgstr "Карыстач %s створаны"
+
+#: kallithea/controllers/admin/users.py:147
+#, python-format
+msgid "Error occurred during creation of user %s"
+msgstr "Адбылася памылка пры стварэнні карыстача %s"
+
+#: kallithea/controllers/admin/users.py:186
+msgid "User updated successfully"
+msgstr "Карыстач паспяхова абноўлены"
+
+#: kallithea/controllers/admin/users.py:222
+msgid "Successfully deleted user"
+msgstr "Карыстач паспяхова выдалены"
+
+#: kallithea/controllers/admin/users.py:227
+msgid "An error occurred during deletion of user"
+msgstr "Адбылася памылка пры выдаленні карыстача"
+
+#: kallithea/controllers/admin/users.py:241
+#: kallithea/controllers/admin/users.py:259
+#: kallithea/controllers/admin/users.py:282
+#: kallithea/controllers/admin/users.py:307
+#: kallithea/controllers/admin/users.py:320
+#: kallithea/controllers/admin/users.py:344
+#: kallithea/controllers/admin/users.py:407
+#: kallithea/controllers/admin/users.py:454
+msgid "You can't edit this user"
+msgstr "Вы не можаце рэдагаваць дадзенага карыстача"
+
+#: kallithea/controllers/admin/users.py:482
+#, python-format
+msgid "Added IP address %s to user whitelist"
+msgstr "Дададзены IP %s у белы спіс карыстача"
+
+#: kallithea/controllers/admin/users.py:488
+msgid "An error occurred during ip saving"
+msgstr "Адбылася памылка пры захаванні IP"
+
+#: kallithea/controllers/admin/users.py:502
+msgid "Removed IP address from user whitelist"
+msgstr "Выдалены IP %s з белага спісу карыстача"
+
+#: kallithea/lib/auth.py:745
+#, python-format
+msgid "IP %s not allowed"
+msgstr "IP %s заблакаваны"
+
+#: kallithea/lib/auth.py:806
+msgid "You need to be a registered user to perform this action"
+msgstr "Вы павінны быць зарэгістраваным карыстачом, каб выканаць гэта дзеянне"
+
+#: kallithea/lib/auth.py:843
+msgid "You need to be signed in to view this page"
+msgstr "Старонка даступная толькі аўтарызаваным карыстачам"
+
+#: kallithea/lib/base.py:427
+msgid "Repository not found in the filesystem"
+msgstr "Рэпазітар не знойдзены на файлавай сістэме"
+
+#: kallithea/lib/base.py:453 kallithea/lib/helpers.py:643
+msgid "Changeset not found"
+msgstr "Набор змен не знойдзены"
+
+#: kallithea/lib/diffs.py:66
+msgid "Binary file"
+msgstr "Двайковы файл"
+
+#: kallithea/lib/diffs.py:82
+msgid ""
+"Changeset was too big and was cut off, use diff menu to display this diff"
+msgstr ""
+"Набор змены апынуўся занадта вялікімі і быў падрэзаны, выкарыстоўвайце меню "
+"параўнання для паказу выніку параўнання"
+
+#: kallithea/lib/diffs.py:92
+msgid "No changes detected"
+msgstr "Змен не выяўлена"
+
+#: kallithea/lib/helpers.py:627
+#, python-format
+msgid "Deleted branch: %s"
+msgstr "Выдалена галінка: %s"
+
+#: kallithea/lib/helpers.py:630
+#, python-format
+msgid "Created tag: %s"
+msgstr "Створаны тэг: %s"
+
+#: kallithea/lib/helpers.py:693
+#, python-format
+msgid "Show all combined changesets %s->%s"
+msgstr "Паказаць адрозненні разам %s->%s"
+
+#: kallithea/lib/helpers.py:699
+msgid "compare view"
+msgstr "параўнанне"
+
+#: kallithea/lib/helpers.py:718
+msgid "and"
+msgstr "і"
+
+#: kallithea/lib/helpers.py:719
+#, python-format
+msgid "%s more"
+msgstr "на %s больш"
+
+#: kallithea/lib/helpers.py:720
+#: kallithea/templates/changelog/changelog.html:44
+msgid "revisions"
+msgstr "версіі"
+
+#: kallithea/lib/helpers.py:744
+#, python-format
+msgid "fork name %s"
+msgstr "імя форка %s"
+
+#: kallithea/lib/helpers.py:761
+#, python-format
+msgid "Pull request #%s"
+msgstr "Pull-запыт #%s"
+
+#: kallithea/lib/helpers.py:771
+msgid "[deleted] repository"
+msgstr "[выдалены] рэпазітар"
+
+#: kallithea/lib/helpers.py:773 kallithea/lib/helpers.py:785
+msgid "[created] repository"
+msgstr "[створаны] рэпазітар"
+
+#: kallithea/lib/helpers.py:775
+msgid "[created] repository as fork"
+msgstr "[створаны] рэпазітар як форк"
+
+#: kallithea/lib/helpers.py:777 kallithea/lib/helpers.py:787
+msgid "[forked] repository"
+msgstr "[форкнуты] рэпазітар"
+
+#: kallithea/lib/helpers.py:779 kallithea/lib/helpers.py:789
+msgid "[updated] repository"
+msgstr "[абноўлены] рэпазітар"
+
+#: kallithea/lib/helpers.py:781
+msgid "[downloaded] archive from repository"
+msgstr "[загружаны] архіў з рэпазітара"
+
+#: kallithea/lib/helpers.py:783
+msgid "[delete] repository"
+msgstr "[выдалены] рэпазітар"
+
+#: kallithea/lib/helpers.py:791
+msgid "[created] user"
+msgstr "[створаны] карыстач"
+
+#: kallithea/lib/helpers.py:793
+msgid "[updated] user"
+msgstr "[абноўлены] карыстач"
+
+#: kallithea/lib/helpers.py:795
+msgid "[created] user group"
+msgstr "[створана] група карыстачоў"
+
+#: kallithea/lib/helpers.py:797
+msgid "[updated] user group"
+msgstr "[абноўлена] група карыстачоў"
+
+#: kallithea/lib/helpers.py:799
+msgid "[commented] on revision in repository"
+msgstr "[каментар] да рэвізіі ў рэпазітары"
+
+#: kallithea/lib/helpers.py:801
+msgid "[commented] on pull request for"
+msgstr "[пракаменціравана] у запыце на занясенне змен для"
+
+#: kallithea/lib/helpers.py:803
+msgid "[closed] pull request for"
+msgstr "[зачынены] Pull-запыт для"
+
+#: kallithea/lib/helpers.py:805
+msgid "[pushed] into"
+msgstr "[адпраўлена] у"
+
+#: kallithea/lib/helpers.py:807
+msgid "[committed via Kallithea] into repository"
+msgstr "[занесены змены з дапамогай Kallithea] у рэпазітары"
+
+#: kallithea/lib/helpers.py:809
+msgid "[pulled from remote] into repository"
+msgstr "[занесены змены з выдаленага рэпазітара] у рэпазітар"
+
+#: kallithea/lib/helpers.py:811
+msgid "[pulled] from"
+msgstr "[занесены змены] з"
+
+#: kallithea/lib/helpers.py:813
+msgid "[started following] repository"
+msgstr "[дададзены ў назіранні] рэпазітар"
+
+#: kallithea/lib/helpers.py:815
+msgid "[stopped following] repository"
+msgstr "[выдалены з назірання] рэпазітар"
+
+#: kallithea/lib/helpers.py:1144
+#, python-format
+msgid " and %s more"
+msgstr " і на %s больш"
+
+#: kallithea/lib/helpers.py:1148
+msgid "No Files"
+msgstr "Файлаў няма"
+
+#: kallithea/lib/helpers.py:1214
+msgid "new file"
+msgstr "новы файл"
+
+#: kallithea/lib/helpers.py:1217
+msgid "mod"
+msgstr "зменены"
+
+#: kallithea/lib/helpers.py:1220
+msgid "del"
+msgstr "выдалены"
+
+#: kallithea/lib/helpers.py:1223
+msgid "rename"
+msgstr "пераназваны"
+
+#: kallithea/lib/helpers.py:1228
+msgid "chmod"
+msgstr "chmod"
+
+#: kallithea/lib/helpers.py:1460
+#, python-format
+msgid ""
+"%s repository is not mapped to db perhaps it was created or renamed from the "
+"filesystem please run the application again in order to rescan repositories"
+msgstr ""
+"Рэпазітар %s адсутнічае ў базе дадзеных; магчыма, ён быў створаны ці "
+"пераназваны з файлавай сістэмы. Калі ласка, перазапусціце прыкладанне для "
+"сканавання рэпазітароў"
+
+#: kallithea/lib/utils2.py:425
+#, python-format
+msgid "%d year"
+msgid_plural "%d years"
+msgstr[0] "%d год"
+msgstr[1] "%d гадоў"
+msgstr[2] "%d гады"
+
+#: kallithea/lib/utils2.py:426
+#, python-format
+msgid "%d month"
+msgid_plural "%d months"
+msgstr[0] "%d месяц"
+msgstr[1] "%d месяца"
+msgstr[2] "%d месяцаў"
+
+#: kallithea/lib/utils2.py:427
+#, python-format
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] "%d дзень"
+msgstr[1] "%d дня"
+msgstr[2] "%d дзён"
+
+#: kallithea/lib/utils2.py:428
+#, python-format
+msgid "%d hour"
+msgid_plural "%d hours"
+msgstr[0] "%d гадзіна"
+msgstr[1] "%d гадзін"
+msgstr[2] "%d гадзіны"
+
+#: kallithea/lib/utils2.py:429
+#, python-format
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] "%d хвіліна"
+msgstr[1] "%d хвіліны"
+msgstr[2] "%d хвілін"
+
+#: kallithea/lib/utils2.py:430
+#, python-format
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] "%d секунды"
+msgstr[1] "%d секунды"
+msgstr[2] "%d секунды"
+
+#: kallithea/lib/utils2.py:446
+#, python-format
+msgid "in %s"
+msgstr "у %s"
+
+#: kallithea/lib/utils2.py:448
+#, python-format
+msgid "%s ago"
+msgstr "%s назад"
+
+#: kallithea/lib/utils2.py:450
+#, python-format
+msgid "in %s and %s"
+msgstr "у %s і %s"
+
+#: kallithea/lib/utils2.py:453
+#, python-format
+msgid "%s and %s ago"
+msgstr "%s і %s назад"
+
+#: kallithea/lib/utils2.py:456
+msgid "just now"
+msgstr "прама цяпер"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1163
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1182
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1303
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1388
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1408
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1454
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1511
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1512
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1533
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1572
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1622
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1649 kallithea/model/db.py:1651
+msgid "Repository no access"
+msgstr "Рэпазітар - няма доступу"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1164
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1183
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1304
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1389
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1409
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1455
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1512
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1513
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1534
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1573
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1623
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1650 kallithea/model/db.py:1652
+msgid "Repository read access"
+msgstr "Рэпазітар - доступ на чытанне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1165
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1184
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1305
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1390
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1410
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1456
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1513
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1514
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1535
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1574
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1624
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1651 kallithea/model/db.py:1653
+msgid "Repository write access"
+msgstr "Рэпазітар - доступ на запіс"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1166
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1185
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1306
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1391
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1411
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1457
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1514
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1515
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1536
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1575
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1625
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1652 kallithea/model/db.py:1654
+msgid "Repository admin access"
+msgstr "Рэпазітар - адміністраванне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1168
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1187
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1308
+msgid "Repository Group no access"
+msgstr "Група Рэпазітароў - няма доступу"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1169
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1188
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1309
+msgid "Repository Group read access"
+msgstr "Група Рэпазітароў - доступ на чытанне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1170
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1189
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1310
+msgid "Repository Group write access"
+msgstr "Група Рэпазітароў - доступ на запіс"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1171
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1190
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1311
+msgid "Repository Group admin access"
+msgstr "Група Рэпазітароў - адміністраванне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1173
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1192
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1313
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1398
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1406
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1452
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1509
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1510
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1531
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1570
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1620
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1647 kallithea/model/db.py:1649
+msgid "Kallithea Administrator"
+msgstr "Адміністратар Kallithea"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1174
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1193
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1314
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1399
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1429
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1475
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1532
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1533
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1554
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1593
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1643
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1670 kallithea/model/db.py:1672
+msgid "Repository creation disabled"
+msgstr "Стварэнне рэпазітароў адключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1175
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1194
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1315
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1400
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1430
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1476
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1533
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1534
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1555
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1594
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1644
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1671 kallithea/model/db.py:1673
+msgid "Repository creation enabled"
+msgstr "Стварэнне рэпазітароў уключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1176
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1195
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1316
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1401
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1432
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1478
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1535
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1536
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1557
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1596
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1648
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1675 kallithea/model/db.py:1677
+msgid "Repository forking disabled"
+msgstr "Магчымасць ствараць форк рэпазітара адключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1177
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1196
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1317
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1402
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1433
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1479
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1536
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1537
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1558
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1597
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1649
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1676 kallithea/model/db.py:1678
+msgid "Repository forking enabled"
+msgstr "Магчымасць ствараць форк рэпазітара ўключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1178
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1197
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1318
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1403
+msgid "Register disabled"
+msgstr "Рэгістрацыя адключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1179
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1198
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1319
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1404
+msgid "Register new user with Kallithea with manual activation"
+msgstr "Рэгістрацыя новага карыстача ў Kallithea з ручной актывацыяй"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1182
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1201
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1322
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1407
+msgid "Register new user with Kallithea with auto activation"
+msgstr "Рэгістрацыя новага карыстача ў Kallithea з аўтаматычнай актывацыяй"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1623
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1650
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1763
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1838
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1934
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1980
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:2040
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:2041
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:2062
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:2101
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:2154
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:2200 kallithea/model/db.py:2202
+msgid "Not Reviewed"
+msgstr "Не прагледжана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1624
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1651
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1764
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1839
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1935
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1981
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:2041
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:2042
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:2063
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:2102
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:2155
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:2201 kallithea/model/db.py:2203
+msgid "Approved"
+msgstr "Ухвалена"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1625
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1652
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1765
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1840
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1936
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1982
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:2042
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:2043
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:2064
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:2103
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:2156
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:2202 kallithea/model/db.py:2204
+msgid "Rejected"
+msgstr "Адхілена"
+
+#: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1626
+#: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1653
+#: kallithea/lib/dbmigrate/schema/db_1_5_2.py:1766
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1841
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1937
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1983
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:2043
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:2044
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:2065
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:2104
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:2157
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:2203 kallithea/model/db.py:2205
+msgid "Under Review"
+msgstr "На разглядзе"
+
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1252
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1270
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1300
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1357
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1358
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1379
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1418
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1471
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1498 kallithea/model/db.py:1500
+msgid "top level"
+msgstr "верхні ўзровень"
+
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1393
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1413
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1459
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1516
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1517
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1538
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1577
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1627
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1654 kallithea/model/db.py:1656
+msgid "Repository group no access"
+msgstr "Група Рэпазітароў - няма доступу"
+
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1394
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1414
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1460
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1517
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1518
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1539
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1578
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1628
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1655 kallithea/model/db.py:1657
+msgid "Repository group read access"
+msgstr "Група рэпазітароў - доступ на чытанне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1395
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1415
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1461
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1518
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1519
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1540
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1579
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1629
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1656 kallithea/model/db.py:1658
+msgid "Repository group write access"
+msgstr "Група рэпазітароў - доступ на запіс"
+
+#: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1396
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1416
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1462
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1519
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1520
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1541
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1580
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1630
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1657 kallithea/model/db.py:1659
+msgid "Repository group admin access"
+msgstr "Група рэпазітароў - адміністраванне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1418
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1464
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1521
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1522
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1543
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1582
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1632
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1659 kallithea/model/db.py:1661
+msgid "User group no access"
+msgstr "Група карыстачоў - няма доступу"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1419
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1465
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1522
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1523
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1544
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1583
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1633
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1660 kallithea/model/db.py:1662
+msgid "User group read access"
+msgstr "Група карыстачоў - доступ на чытанне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1420
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1466
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1523
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1524
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1545
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1584
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1634
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1661 kallithea/model/db.py:1663
+msgid "User group write access"
+msgstr "Група карыстачоў - доступ на запіс"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1421
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1467
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1524
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1525
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1546
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1585
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1635
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1662 kallithea/model/db.py:1664
+msgid "User group admin access"
+msgstr "Група карыстачоў - адміністраванне"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1423
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1469
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1526
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1527
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1548
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1587
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1637
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1664 kallithea/model/db.py:1666
+msgid "Repository Group creation disabled"
+msgstr "Стварэнне груп рэпазітароў адключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1424
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1470
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1527
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1528
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1549
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1588
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1638
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1665 kallithea/model/db.py:1667
+msgid "Repository Group creation enabled"
+msgstr "Стварэнне груп рэпазітароў уключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1426
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1472
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1529
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1530
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1551
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1590
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1640
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1667 kallithea/model/db.py:1669
+msgid "User Group creation disabled"
+msgstr "Стварэнне груп карыстачоў адключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1427
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1473
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1530
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1531
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1552
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1591
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1641
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1668 kallithea/model/db.py:1670
+msgid "User Group creation enabled"
+msgstr "Стварэнне груп карыстачоў уключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1435
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1481
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1538
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1539
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1560
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1599
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1651
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1678 kallithea/model/db.py:1680
+msgid "Registration disabled"
+msgstr "Рэгістрацыя адключана"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1436
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1482
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1539
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1540
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1561
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1600
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1652
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1679 kallithea/model/db.py:1681
+msgid "User Registration with manual account activation"
+msgstr "Рэгістрацыя карыстача з ручной актывацыяй уліковага запісу"
+
+#: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1437
+#: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1483
+#: kallithea/lib/dbmigrate/schema/db_2_0_0.py:1540
+#: kallithea/lib/dbmigrate/schema/db_2_0_1.py:1541
+#: kallithea/lib/dbmigrate/schema/db_2_0_2.py:1562
+#: kallithea/lib/dbmigrate/schema/db_2_1_0.py:1601
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1653
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1680 kallithea/model/db.py:1682
+msgid "User Registration with automatic account activation"
+msgstr "Рэгістрацыя карыстача з аўтаматычнай актывацыяй"
+
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1645
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1672 kallithea/model/db.py:1674
+msgid "Repository creation enabled with write permission to a repository group"
+msgstr ""
+
+#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1646
+#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1673 kallithea/model/db.py:1675
+msgid ""
+"Repository creation disabled with write permission to a repository group"
+msgstr ""
+
+#: kallithea/model/comment.py:76
+#, python-format
+msgid "on line %s"
+msgstr "на радку %s"
+
+#: kallithea/model/comment.py:231 kallithea/model/pull_request.py:164
+msgid "[Mention]"
+msgstr "[Згадванне]"
+
+#: kallithea/model/forms.py:57
+msgid "Please enter a login"
+msgstr "Калі ласка, увядзіце лагін"
+
+#: kallithea/model/forms.py:58
+#, python-format
+msgid "Enter a value %(min)i characters long or more"
+msgstr "Увядзіце значэнне даўжынёй не меней %(min)i знакаў"
+
+#: kallithea/model/forms.py:66
+msgid "Please enter a password"
+msgstr "Калі ласка, увядзіце пароль"
+
+#: kallithea/model/forms.py:67
+#, python-format
+msgid "Enter %(min)i characters or more"
+msgstr "Увядзіце не меней %(min)i знакаў"
+
+#: kallithea/model/forms.py:156
+msgid "Name must not contain only digits"
+msgstr ""
+
+#: kallithea/model/notification.py:252
+#, python-format
+msgid "%(user)s commented on changeset at %(when)s"
+msgstr "%(user)s пакінуў каментар да набору змен %(when)s"
+
+#: kallithea/model/notification.py:253
+#, python-format
+msgid "%(user)s sent message at %(when)s"
+msgstr "%(user)s адправіў паведамленне %(when)s"
+
+#: kallithea/model/notification.py:254
+#, python-format
+msgid "%(user)s mentioned you at %(when)s"
+msgstr "%(user)s згадаў вас %(when)s"
+
+#: kallithea/model/notification.py:255
+#, python-format
+msgid "%(user)s registered in Kallithea at %(when)s"
+msgstr "%(user)s зарэгістраваўся ў Kallithea %(when)s"
+
+#: kallithea/model/notification.py:256
+#, python-format
+msgid "%(user)s opened new pull request at %(when)s"
+msgstr "%(user)s адкрыў новы pull-запыт %(when)s"
+
+#: kallithea/model/notification.py:257
+#, python-format
+msgid "%(user)s commented on pull request at %(when)s"
+msgstr "%(user)s пакінуў каментар да pull-запыту %(when)s"
+
+#: kallithea/model/notification.py:296
+#, python-format
+msgid ""
+"Comment on %(repo_name)s changeset %(short_id)s on %(branch)s by "
+"%(comment_username)s"
+msgstr ""
+
+#: kallithea/model/notification.py:299
+#, python-format
+msgid "New user %(new_username)s registered"
+msgstr "Новы карыстач \"%(new_username)s\" зарэгістраваны"
+
+#: kallithea/model/notification.py:301
+#, python-format
+msgid ""
+"Review request on %(repo_name)s pull request #%(pr_id)s from %(ref)s by "
+"%(pr_username)s"
+msgstr ""
+
+#: kallithea/model/notification.py:302
+#, python-format
+msgid ""
+"Comment on %(repo_name)s pull request #%(pr_id)s from %(ref)s by "
+"%(comment_username)s"
+msgstr ""
+
+#: kallithea/model/notification.py:315
+msgid "Closing"
+msgstr "Зачынены"
+
+#: kallithea/model/pull_request.py:132
+#, python-format
+msgid "%(user)s wants you to review pull request #%(pr_id)s: %(pr_title)s"
+msgstr "%(user)s просіць вас разгледзець pull request #%(pr_id)s: %(pr_title)s"
+
+#: kallithea/model/scm.py:808
+msgid "latest tip"
+msgstr "апошняя версія"
+
+#: kallithea/model/user.py:194
+msgid "New user registration"
+msgstr "Рэгістрацыя новага карыстача"
+
+#: kallithea/model/user.py:214 kallithea/model/user.py:236
+msgid "You can't Edit this user since it's crucial for entire application"
+msgstr ""
+"Вы не можаце рэдагаваць карыстача, паколькі гэта крытычна для працы ўсяго "
+"прыкладання"
+
+#: kallithea/model/user.py:255
+msgid "You can't remove this user since it's crucial for entire application"
+msgstr ""
+"Вы не можаце выдаліць карыстача, паколькі гэта крытычна для працы ўсяго "
+"прыкладання"
+
+#: kallithea/model/user.py:261
+#, python-format
+msgid ""
+"User \"%s\" still owns %s repositories and cannot be removed. Switch owners "
+"or remove those repositories: %s"
+msgstr ""
+"Карыстач \"%s\" усё яшчэ з'яўляецца ўладальнікам %s рэпазітароў і таму не "
+"можа быць выдалены. Зменіце ўладальніка ці выдаліце гэтыя рэпазітары: %s"
+
+#: kallithea/model/user.py:268
+#, python-format
+msgid ""
+"User \"%s\" still owns %s repository groups and cannot be removed. Switch "
+"owners or remove those repository groups: %s"
+msgstr ""
+"Карыстач \"%s\" усё яшчэ з'яўляецца ўладальнікам %s груп рэпазітароў і таму "
+"не можа быць выдалены. Зменіце ўладальніка ці выдаліце дадзеныя групы: %s"
+
+#: kallithea/model/user.py:275
+#, python-format
+msgid ""
+"User \"%s\" still owns %s user groups and cannot be removed. Switch owners "
+"or remove those user groups: %s"
+msgstr ""
+"Карыстач \"%s\" усё яшчэ з'яўляецца ўладальнікам %s груп карыстачоў і таму "
+"не можа быць выдалены. Зменіце ўладальніка ці выдаліце дадзеныя групы: %s"
+
+#: kallithea/model/user.py:305
+msgid "Password reset link"
+msgstr "Спасылка скіду пароля"
+
+#: kallithea/model/user.py:328
+msgid "Your new password"
+msgstr "Ваш новы пароль"
+
+#: kallithea/model/user.py:329
+#, python-format
+msgid "Your new Kallithea password:%s"
+msgstr "Ваш новы пароль ад Kallithea: %s"
+
+#: kallithea/model/validators.py:83 kallithea/model/validators.py:84
+msgid "Value cannot be an empty list"
+msgstr "Значэнне не можа быць пустым спісам"
+
+#: kallithea/model/validators.py:101
+#, python-format
+msgid "Username \"%(username)s\" already exists"
+msgstr "Карыстач з імем \"%(username)s\" ужо існуе"
+
+#: kallithea/model/validators.py:103
+#, python-format
+msgid "Username \"%(username)s\" is forbidden"
+msgstr "Імя \"%(username)s\" адхілена"
+
+#: kallithea/model/validators.py:105
+msgid ""
+"Username may only contain alphanumeric characters underscores, periods or "
+"dashes and must begin with alphanumeric character or underscore"
+msgstr ""
+"Імя карыстача можа ўтрымоўваць толькі літары, лічбы, знакі падкрэслення, "
+"кропкі і працяжнік; а гэтак жа павінна пачынацца з літары, лічбы або са "
+"знака падкрэслення"
+
+#: kallithea/model/validators.py:132
+msgid "The input is not valid"
+msgstr ""
+
+#: kallithea/model/validators.py:139
+#, python-format
+msgid "Username %(username)s is not valid"
+msgstr "Імя \"%(username)s\" недапушчальна"
+
+#: kallithea/model/validators.py:158
+msgid "Invalid user group name"
+msgstr "Няслушнае імя групы карыстачоў"
+
+#: kallithea/model/validators.py:159
+#, python-format
+msgid "User group \"%(usergroup)s\" already exists"
+msgstr "Група карыстачоў \"%(usergroup)s\" ужо існуе"
+
+#: kallithea/model/validators.py:161
+msgid ""
+"user group name may only contain alphanumeric characters underscores, "
+"periods or dashes and must begin with alphanumeric character"
+msgstr ""
+"імя групы карыстачоў можа ўтрымоўваць толькі літары, лічбы, знакі "
+"падкрэслення, кропкі і працяжнік; а гэтак жа павінна пачынацца з літары ці "
+"лічбы"
+
+#: kallithea/model/validators.py:199
+msgid "Cannot assign this group as parent"
+msgstr "Немагчыма выкарыстоўваць гэту групу як бацькоўскую"
+
+#: kallithea/model/validators.py:200
+#, python-format
+msgid "Group \"%(group_name)s\" already exists"
+msgstr "Група \"%(group_name)s\" ужо існуе"
+
+#: kallithea/model/validators.py:202
+#, python-format
+msgid "Repository with name \"%(group_name)s\" already exists"
+msgstr "Рэпазітар з  імем \"%(group_name)s\" ужо існуе"
+
+#: kallithea/model/validators.py:260
+msgid "Invalid characters (non-ascii) in password"
+msgstr "Недапушчальныя знакі (не ascii) у паролі"
+
+#: kallithea/model/validators.py:275
+msgid "Invalid old password"
+msgstr "Няслушна зададзены стары пароль"
+
+#: kallithea/model/validators.py:291
+msgid "Passwords do not match"
+msgstr "Паролі не супадаюць"
+
+#: kallithea/model/validators.py:308
+msgid "invalid password"
+msgstr "няслушны пароль"
+
+#: kallithea/model/validators.py:309
+msgid "invalid user name"
+msgstr "няслушнае імя карыстача"
+
+#: kallithea/model/validators.py:310
+msgid "Your account is disabled"
+msgstr "Ваш акаўнт выключаны"
+
+#: kallithea/model/validators.py:354
+#, python-format
+msgid "Repository name %(repo)s is disallowed"
+msgstr "Імя рэпазітара %(repo)s забаронена"
+
+#: kallithea/model/validators.py:356
+#, python-format
+msgid "Repository named %(repo)s already exists"
+msgstr "Рэпазітар %(repo)s ужо існуе"
+
+#: kallithea/model/validators.py:357
+#, python-format
+msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
+msgstr "Рэпазітар \"%(repo)s\" ужо існуе ў групе \"%(group)s\""
+
+#: kallithea/model/validators.py:359
+#, python-format
+msgid "Repository group with name \"%(repo)s\" already exists"
+msgstr "Група рэпазітароў \"%(repo)s\" ужо існуе"
+
+#: kallithea/model/validators.py:474
+msgid "invalid clone URL"
+msgstr "няслушны URL для кланавання"
+
+#: kallithea/model/validators.py:475
+msgid "Invalid clone URL, provide a valid clone http(s)/svn+http(s)/ssh URL"
+msgstr ""
+"Няслушны URL кланаванні, падайце карэктны URL для кланавання ў фармаце "
+"http(s)/svn+http(s)/ssh"
+
+#: kallithea/model/validators.py:500
+msgid "Fork has to be the same type as parent"
+msgstr "Тып форка будзе супадаць з бацькоўскім"
+
+#: kallithea/model/validators.py:515
+msgid "You don't have permissions to create repository in this group"
+msgstr "У вас недастаткова мае рацыю для стварэння рэпазітароў у гэтай групе"
+
+#: kallithea/model/validators.py:517
+msgid "no permission to create repository in root location"
+msgstr "недастаткова мае рацыю для стварэння рэпазітара ў каранёвым каталогу"
+
+#: kallithea/model/validators.py:566
+msgid "You don't have permissions to create a group in this location"
+msgstr "У Вас недастаткова прывілеяў для стварэння групы ў гэтым месцы"
+
+#: kallithea/model/validators.py:607
+msgid "This username or user group name is not valid"
+msgstr "Дадзенае імя карыстача ці групы карыстачоў недапушчальна"
+
+#: kallithea/model/validators.py:700
+msgid "This is not a valid path"
+msgstr "Гэты шлях хібны"
+
+#: kallithea/model/validators.py:715
+msgid "This e-mail address is already taken"
+msgstr "Гэты E-mail ужо заняты"
+
+#: kallithea/model/validators.py:735
+#, python-format
+msgid "e-mail \"%(email)s\" does not exist."
+msgstr "\"%(email)s\" не існуе."
+
+#: kallithea/model/validators.py:772
+msgid ""
+"The LDAP Login attribute of the CN must be specified - this is the name of "
+"the attribute that is equivalent to \"username\""
+msgstr ""
+"Для ўваходу па LDAP павінна быць паказана значэнне атрыбута CN - гэта "
+"эквівалент імя карыстача"
+
+#: kallithea/model/validators.py:785
+#, python-format
+msgid "Revisions %(revs)s are already part of pull request or have set status"
+msgstr "Рэвізіі %(revs)s ужо ўключаны ў pull-request ці маюць усталяваны статус"
+
+#: kallithea/model/validators.py:817
+msgid "Please enter a valid IPv4 or IPv6 address"
+msgstr "Калі ласка, увядзіце існы IPv4 ці IPv6 адрас"
+
+#: kallithea/model/validators.py:818
+#, python-format
+msgid "The network size (bits) must be within the range of 0-32 (not %(bits)r)"
+msgstr ""
+"Значэнне маскі падсеткі павінна быць у межах ад 0 да 32 (%(bits)r - няслушна)"
+
+#: kallithea/model/validators.py:851
+msgid "Key name can only consist of letters, underscore, dash or numbers"
+msgstr ""
+"Ключавое імя можа толькі складацца з літар, знака падкрэслення, працяжнік ці "
+"лікаў"
+
+#: kallithea/model/validators.py:865
+msgid "Filename cannot be inside a directory"
+msgstr "Файла няма ў каталогу"
+
+#: kallithea/model/validators.py:881
+#, python-format
+msgid "Plugins %(loaded)s and %(next_to_load)s both export the same name"
+msgstr ""
+
+#: kallithea/templates/about.html:4 kallithea/templates/about.html:17
+msgid "About"
+msgstr "Пра праграму"
+
+#: kallithea/templates/index.html:5
+msgid "Dashboard"
+msgstr "Панэль кіравання"
+
+#: kallithea/templates/index_base.html:6
+#: kallithea/templates/admin/my_account/my_account_repos.html:3
+#: kallithea/templates/admin/my_account/my_account_watched.html:3
+#: kallithea/templates/admin/repo_groups/repo_groups.html:9
+#: kallithea/templates/admin/repos/repos.html:9
+#: kallithea/templates/admin/user_groups/user_groups.html:9
+#: kallithea/templates/admin/users/users.html:9
+#: kallithea/templates/bookmarks/bookmarks.html:9
+#: kallithea/templates/branches/branches.html:9
+#: kallithea/templates/journal/journal.html:9
+#: kallithea/templates/journal/journal.html:48
+#: kallithea/templates/journal/journal.html:49
+#: kallithea/templates/tags/tags.html:9
+msgid "quick filter..."
+msgstr "фільтр..."
+
+#: kallithea/templates/index_base.html:6
+msgid "repositories"
+msgstr "рэпазітары"
+
+#: kallithea/templates/index_base.html:20
+#: kallithea/templates/index_base.html:25
+#: kallithea/templates/admin/repos/repo_add.html:5
+#: kallithea/templates/admin/repos/repo_add.html:19
+#: kallithea/templates/admin/repos/repos.html:22
+msgid "Add Repository"
+msgstr "Дадаць рэпазітар"
+
+#: kallithea/templates/index_base.html:22
+#: kallithea/templates/index_base.html:27
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:5
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:13
+#: kallithea/templates/admin/repo_groups/repo_groups.html:26
+msgid "Add Repository Group"
+msgstr "Дадаць групу рэпазітароў"
+
+#: kallithea/templates/index_base.html:32
+msgid "You have admin right to this group, and can edit it"
+msgstr "Вы маеце адміністратарскія правы на гэту групу і можаце рэдагаваць яе"
+
+#: kallithea/templates/index_base.html:32
+msgid "Edit Repository Group"
+msgstr "Змяніць групу рэпазітароў"
+
+#: kallithea/templates/index_base.html:45
+msgid "Group Name"
+msgstr "Імя групы"
+
+#: kallithea/templates/index_base.html:46
+#: kallithea/templates/index_base.html:131
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:64
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:42
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:17
+#: kallithea/templates/admin/repo_groups/repo_groups.html:47
+#: kallithea/templates/admin/repos/repo_add_base.html:32
+#: kallithea/templates/admin/repos/repo_edit_settings.html:72
+#: kallithea/templates/admin/repos/repos.html:48
+#: kallithea/templates/admin/user_groups/user_group_add.html:40
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:15
+#: kallithea/templates/admin/user_groups/user_groups.html:47
+#: kallithea/templates/admin/users/user_edit_api_keys.html:64
+#: kallithea/templates/email_templates/changeset_comment.html:18
+#: kallithea/templates/email_templates/pull_request.html:12
+#: kallithea/templates/forks/fork.html:38
+#: kallithea/templates/pullrequests/pullrequest.html:40
+#: kallithea/templates/pullrequests/pullrequest_show.html:38
+#: kallithea/templates/pullrequests/pullrequest_show.html:63
+#: kallithea/templates/summary/summary.html:84
+msgid "Description"
+msgstr "Апісанне"
+
+#: kallithea/templates/index_base.html:129
+#: kallithea/templates/admin/my_account/my_account_repos.html:46
+#: kallithea/templates/admin/my_account/my_account_watched.html:46
+#: kallithea/templates/admin/repo_groups/repo_groups.html:46
+#: kallithea/templates/admin/repos/repo_add_base.html:9
+#: kallithea/templates/admin/repos/repo_edit_settings.html:7
+#: kallithea/templates/admin/repos/repos.html:47
+#: kallithea/templates/admin/user_groups/user_groups.html:46
+#: kallithea/templates/base/perms_summary.html:53
+#: kallithea/templates/bookmarks/bookmarks.html:49
+#: kallithea/templates/bookmarks/bookmarks_data.html:7
+#: kallithea/templates/branches/branches.html:49
+#: kallithea/templates/branches/branches_data.html:7
+#: kallithea/templates/files/files_browser.html:60
+#: kallithea/templates/journal/journal.html:187
+#: kallithea/templates/journal/journal.html:278
+#: kallithea/templates/tags/tags.html:49
+#: kallithea/templates/tags/tags_data.html:7
+msgid "Name"
+msgstr "Імя"
+
+#: kallithea/templates/index_base.html:132
+msgid "Last Change"
+msgstr "Апошняя змена"
+
+#: kallithea/templates/index_base.html:134
+#: kallithea/templates/admin/my_account/my_account_repos.html:48
+#: kallithea/templates/admin/my_account/my_account_watched.html:48
+#: kallithea/templates/admin/repos/repos.html:49
+#: kallithea/templates/journal/journal.html:189
+#: kallithea/templates/journal/journal.html:280
+msgid "Tip"
+msgstr "Стан"
+
+#: kallithea/templates/index_base.html:136
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:10
+#: kallithea/templates/admin/repo_groups/repo_groups.html:49
+#: kallithea/templates/admin/repos/repo_edit_settings.html:60
+#: kallithea/templates/admin/repos/repos.html:50
+#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:8
+#: kallithea/templates/admin/user_groups/user_groups.html:50
+#: kallithea/templates/summary/summary.html:137
+msgid "Owner"
+msgstr "Уладальнік"
+
+#: kallithea/templates/index_base.html:144
+#: kallithea/templates/admin/my_account/my_account_repos.html:57
+#: kallithea/templates/admin/my_account/my_account_watched.html:57
+#: kallithea/templates/base/root.html:44
+#: kallithea/templates/bookmarks/bookmarks.html:79
+#: kallithea/templates/branches/branches.html:79
+#: kallithea/templates/journal/journal.html:198
+#: kallithea/templates/journal/journal.html:289
+#: kallithea/templates/tags/tags.html:79
+msgid "Click to sort ascending"
+msgstr "Па ўзрастанні"
+
+#: kallithea/templates/index_base.html:145
+#: kallithea/templates/admin/my_account/my_account_repos.html:58
+#: kallithea/templates/admin/my_account/my_account_watched.html:58
+#: kallithea/templates/base/root.html:45
+#: kallithea/templates/bookmarks/bookmarks.html:80
+#: kallithea/templates/branches/branches.html:80
+#: kallithea/templates/journal/journal.html:199
+#: kallithea/templates/journal/journal.html:290
+#: kallithea/templates/tags/tags.html:80
+msgid "Click to sort descending"
+msgstr "Па змяншэнні"
+
+#: kallithea/templates/index_base.html:146
+msgid "No repositories found."
+msgstr "Рэпазітары не знойдзены."
+
+#: kallithea/templates/index_base.html:147
+#: kallithea/templates/admin/my_account/my_account_repos.html:60
+#: kallithea/templates/admin/my_account/my_account_watched.html:60
+#: kallithea/templates/base/root.html:47
+#: kallithea/templates/bookmarks/bookmarks.html:82
+#: kallithea/templates/branches/branches.html:82
+#: kallithea/templates/journal/journal.html:201
+#: kallithea/templates/journal/journal.html:292
+#: kallithea/templates/tags/tags.html:82
+msgid "Data error."
+msgstr "Памылка дадзеных."
+
+#: kallithea/templates/index_base.html:148
+#: kallithea/templates/admin/my_account/my_account_repos.html:61
+#: kallithea/templates/admin/my_account/my_account_watched.html:61
+#: kallithea/templates/base/base.html:143
+#: kallithea/templates/base/root.html:48
+#: kallithea/templates/bookmarks/bookmarks.html:83
+#: kallithea/templates/branches/branches.html:83
+#: kallithea/templates/journal/journal.html:202
+#: kallithea/templates/journal/journal.html:293
+#: kallithea/templates/tags/tags.html:83
+msgid "Loading..."
+msgstr "Загрузка..."
+
+#: kallithea/templates/login.html:5 kallithea/templates/login.html:15
+#: kallithea/templates/base/base.html:329
+msgid "Log In"
+msgstr "Увайсці"
+
+#: kallithea/templates/login.html:13
+#, python-format
+msgid "Log In to %s"
+msgstr "Увайсці ў %s"
+
+#: kallithea/templates/login.html:27 kallithea/templates/register.html:24
+#: kallithea/templates/admin/admin_log.html:5
+#: kallithea/templates/admin/my_account/my_account_profile.html:32
+#: kallithea/templates/admin/users/user_add.html:32
+#: kallithea/templates/admin/users/user_edit_profile.html:33
+#: kallithea/templates/admin/users/users.html:50
+#: kallithea/templates/base/base.html:305
+msgid "Username"
+msgstr "Імя карыстача"
+
+#: kallithea/templates/login.html:36 kallithea/templates/register.html:33
+#: kallithea/templates/admin/my_account/my_account.html:36
+#: kallithea/templates/admin/users/user_add.html:41
+#: kallithea/templates/base/base.html:314
+msgid "Password"
+msgstr "Пароль"
+
+#: kallithea/templates/login.html:46
+msgid "Remember me"
+msgstr "Запомніць"
+
+#: kallithea/templates/login.html:50
+msgid "Sign In"
+msgstr "Увайсці"
+
+#: kallithea/templates/login.html:56
+msgid "Forgot your password ?"
+msgstr "Забыліся пароль?"
+
+#: kallithea/templates/login.html:59 kallithea/templates/base/base.html:325
+msgid "Don't have an account ?"
+msgstr "Няма акаўнта?"
+
+#: kallithea/templates/password_reset.html:5
+msgid "Password Reset"
+msgstr "Скід пароля"
+
+#: kallithea/templates/password_reset.html:12
+#, python-format
+msgid "Reset Your Password to %s"
+msgstr "Забыліся пароль для %s?"
+
+#: kallithea/templates/password_reset.html:14
+msgid "Reset Your Password"
+msgstr "Скінуць Ваш пароль"
+
+#: kallithea/templates/password_reset.html:25
+msgid "Email Address"
+msgstr "Паштовы адрас"
+
+#: kallithea/templates/password_reset.html:35
+#: kallithea/templates/register.html:79
+msgid "Captcha"
+msgstr "Капча"
+
+#: kallithea/templates/password_reset.html:46
+msgid "Send Password Reset Email"
+msgstr "Паслаць спасылку скіду пароля"
+
+#: kallithea/templates/password_reset.html:47
+msgid ""
+"Password reset link will be sent to the email address matching your username."
+msgstr "Спасылка для скіду пароля была адпраўлена на адпаведны e-mail."
+
+#: kallithea/templates/register.html:5 kallithea/templates/register.html:14
+#: kallithea/templates/register.html:90
+msgid "Sign Up"
+msgstr "Рэгістрацыя"
+
+#: kallithea/templates/register.html:12
+#, python-format
+msgid "Sign Up to %s"
+msgstr "Рэгістра на %s"
+
+#: kallithea/templates/register.html:42
+msgid "Re-enter password"
+msgstr "Паўторыце пароль"
+
+#: kallithea/templates/register.html:51
+#: kallithea/templates/admin/my_account/my_account_profile.html:43
+#: kallithea/templates/admin/users/user_add.html:59
+#: kallithea/templates/admin/users/user_edit_profile.html:87
+#: kallithea/templates/admin/users/users.html:51
+msgid "First Name"
+msgstr "Імя"
+
+#: kallithea/templates/register.html:60
+#: kallithea/templates/admin/my_account/my_account_profile.html:52
+#: kallithea/templates/admin/users/user_add.html:68
+#: kallithea/templates/admin/users/user_edit_profile.html:96
+#: kallithea/templates/admin/users/users.html:52
+msgid "Last Name"
+msgstr "Прозвішча"
+
+#: kallithea/templates/register.html:69
+#: kallithea/templates/admin/my_account/my_account_profile.html:61
+#: kallithea/templates/admin/settings/settings.html:31
+#: kallithea/templates/admin/users/user_add.html:77
+#: kallithea/templates/admin/users/user_edit_profile.html:42
+msgid "Email"
+msgstr "E-mail"
+
+#: kallithea/templates/register.html:92
+msgid "Registered accounts are ready to use and need no further action."
+msgstr ""
+
+#: kallithea/templates/register.html:94
+msgid "Please wait for an administrator to activate your account."
+msgstr ""
+"Калі ласка, пачакайце, пакуль адміністратар пацвердзіць Вашу рэгістрацыю."
+
+#: kallithea/templates/switch_to_list.html:10
+#: kallithea/templates/branches/branches_data.html:69
+msgid "There are no branches yet"
+msgstr "Галінкі яшчэ не створаны"
+
+#: kallithea/templates/switch_to_list.html:16
+msgid "Closed Branches"
+msgstr "Зачыненыя галінкі"
+
+#: kallithea/templates/switch_to_list.html:32
+#: kallithea/templates/tags/tags_data.html:44
+msgid "There are no tags yet"
+msgstr "Пазнакі адсутнічаюць"
+
+#: kallithea/templates/switch_to_list.html:45
+#: kallithea/templates/bookmarks/bookmarks_data.html:43
+msgid "There are no bookmarks yet"
+msgstr "Закладак яшчэ няма"
+
+#: kallithea/templates/admin/admin.html:5
+#: kallithea/templates/admin/admin.html:13
+#: kallithea/templates/base/base.html:59
+msgid "Admin Journal"
+msgstr "Часопіс адміністратара"
+
+#: kallithea/templates/admin/admin.html:10
+msgid "journal filter..."
+msgstr "Фільтр часопіса..."
+
+#: kallithea/templates/admin/admin.html:12
+#: kallithea/templates/journal/journal.html:11
+msgid "Filter"
+msgstr "Адфільтраваць"
+
+#: kallithea/templates/admin/admin.html:13
+#: kallithea/templates/journal/journal.html:12
+#, python-format
+msgid "%s Entry"
+msgid_plural "%s Entries"
+msgstr[0] "%s запіс"
+msgstr[1] "%s запісаў"
+msgstr[2] "%s запісы"
+
+#: kallithea/templates/admin/admin_log.html:6
+#: kallithea/templates/admin/my_account/my_account_repos.html:50
+#: kallithea/templates/admin/my_account/my_account_watched.html:50
+#: kallithea/templates/admin/repo_groups/repo_groups.html:50
+#: kallithea/templates/admin/repos/repo_edit_fields.html:8
+#: kallithea/templates/admin/repos/repos.html:52
+#: kallithea/templates/admin/user_groups/user_groups.html:51
+#: kallithea/templates/admin/users/users.html:57
+#: kallithea/templates/journal/journal.html:191
+#: kallithea/templates/journal/journal.html:282
+msgid "Action"
+msgstr "Дзеянне"
+
+#: kallithea/templates/admin/admin_log.html:7
+#: kallithea/templates/admin/permissions/permissions_globals.html:18
+msgid "Repository"
+msgstr "Рэпазітар"
+
+#: kallithea/templates/admin/admin_log.html:8
+#: kallithea/templates/bookmarks/bookmarks.html:51
+#: kallithea/templates/bookmarks/bookmarks_data.html:9
+#: kallithea/templates/branches/branches.html:51
+#: kallithea/templates/branches/branches_data.html:9
+#: kallithea/templates/tags/tags.html:51
+#: kallithea/templates/tags/tags_data.html:9
+msgid "Date"
+msgstr "Дата"
+
+#: kallithea/templates/admin/admin_log.html:9
+msgid "From IP"
+msgstr "З IP"
+
+#: kallithea/templates/admin/admin_log.html:63
+msgid "No actions yet"
+msgstr "Дзеянні яшчэ не вырабляліся"
+
+#: kallithea/templates/admin/auth/auth_settings.html:5
+msgid "Authentication Settings"
+msgstr "Налады аўтэнтыфікацыі"
+
+#: kallithea/templates/admin/auth/auth_settings.html:11
+#: kallithea/templates/base/base.html:65
+msgid "Authentication"
+msgstr "Аўтэнтыфікацыя"
+
+#: kallithea/templates/admin/auth/auth_settings.html:28
+msgid "Authentication Plugins"
+msgstr "Убудовы аўтэнтыфікацыі"
+
+#: kallithea/templates/admin/auth/auth_settings.html:31
+msgid "Enabled Plugins"
+msgstr "Уключаныя ўбудовы"
+
+#: kallithea/templates/admin/auth/auth_settings.html:33
+msgid ""
+"Comma separated list of plugins. Order of plugins is also order in which "
+"Kallithea will try to authenticate user"
+msgstr ""
+"Спіс убудоў, падзеленых коскі. Kallithea будзе спрабаваць аўтэнтыфікаваць "
+"карыстача ў парадку ўказання ўбудоў"
+
+#: kallithea/templates/admin/auth/auth_settings.html:34
+msgid "Available built-in plugins"
+msgstr "Даступныя ўбудаваныя ўбудовы"
+
+#: kallithea/templates/admin/auth/auth_settings.html:40
+#: kallithea/templates/base/root.html:40
+msgid "enabled"
+msgstr "уключана"
+
+#: kallithea/templates/admin/auth/auth_settings.html:40
+#: kallithea/templates/base/root.html:41
+msgid "disabled"
+msgstr "адключана"
+
+#: kallithea/templates/admin/auth/auth_settings.html:51
+msgid "Plugin"
+msgstr "Убудова"
+
+#: kallithea/templates/admin/auth/auth_settings.html:101
+#: kallithea/templates/admin/defaults/defaults.html:84
+#: kallithea/templates/admin/my_account/my_account_password.html:33
+#: kallithea/templates/admin/my_account/my_account_profile.html:70
+#: kallithea/templates/admin/permissions/permissions_globals.html:108
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:69
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:114
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:42
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:101
+#: kallithea/templates/admin/repos/repo_edit_settings.html:134
+#: kallithea/templates/admin/settings/settings_hooks.html:53
+#: kallithea/templates/admin/user_groups/user_group_add.html:57
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:104
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:60
+#: kallithea/templates/admin/users/user_add.html:96
+#: kallithea/templates/admin/users/user_edit_profile.html:122
+#: kallithea/templates/base/default_perms_box.html:64
+msgid "Save"
+msgstr "Захаваць"
+
+#: kallithea/templates/admin/defaults/defaults.html:5
+#: kallithea/templates/admin/defaults/defaults.html:25
+msgid "Repository Defaults"
+msgstr "Значэнні па змаўчанні"
+
+#: kallithea/templates/admin/defaults/defaults.html:11
+#: kallithea/templates/base/base.html:66
+msgid "Defaults"
+msgstr "Значэнні па змаўчанні"
+
+#: kallithea/templates/admin/defaults/defaults.html:35
+#: kallithea/templates/admin/repos/repo_add_base.html:59
+#: kallithea/templates/admin/repos/repo_edit_fields.html:7
+msgid "Type"
+msgstr "Тып"
+
+#: kallithea/templates/admin/defaults/defaults.html:44
+#: kallithea/templates/admin/repos/repo_add_base.html:77
+#: kallithea/templates/admin/repos/repo_edit_settings.html:82
+#: kallithea/templates/data_table/_dt_elements.html:74
+msgid "Private repository"
+msgstr "Прыватны рэпазітар"
+
+#: kallithea/templates/admin/defaults/defaults.html:48
+#: kallithea/templates/admin/repos/repo_add_base.html:81
+#: kallithea/templates/admin/repos/repo_edit_settings.html:86
+#: kallithea/templates/forks/fork.html:72
+msgid ""
+"Private repositories are only visible to people explicitly added as "
+"collaborators."
+msgstr "Прыватныя рэпазітары бачныя толькі іх удзельнікам."
+
+#: kallithea/templates/admin/defaults/defaults.html:55
+#: kallithea/templates/admin/repos/repo_edit_settings.html:91
+msgid "Enable statistics"
+msgstr "Уключыць статыстыку"
+
+#: kallithea/templates/admin/defaults/defaults.html:59
+#: kallithea/templates/admin/repos/repo_edit_settings.html:95
+msgid "Enable statistics window on summary page."
+msgstr "Уключыць акно статыстыкі на старонцы «Агульныя звесткі»."
+
+#: kallithea/templates/admin/defaults/defaults.html:65
+#: kallithea/templates/admin/repos/repo_edit_settings.html:100
+msgid "Enable downloads"
+msgstr "Уключыць спампоўку"
+
+#: kallithea/templates/admin/defaults/defaults.html:69
+#: kallithea/templates/admin/repos/repo_edit_settings.html:104
+msgid "Enable download menu on summary page."
+msgstr "Уключыць меню спампоўкі на старонцы «Агульныя звесткі»."
+
+#: kallithea/templates/admin/defaults/defaults.html:75
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:34
+#: kallithea/templates/admin/repos/repo_edit_settings.html:109
+msgid "Enable locking"
+msgstr "Уключыць блакаванне"
+
+#: kallithea/templates/admin/defaults/defaults.html:79
+#: kallithea/templates/admin/repos/repo_edit_settings.html:113
+msgid "Enable lock-by-pulling on repository."
+msgstr "Уключыць аўтаблакоўку для рэпазітара."
+
+#: kallithea/templates/admin/gists/edit.html:5
+#: kallithea/templates/admin/gists/edit.html:18
+msgid "Edit Gist"
+msgstr "Праўка gist-запісы"
+
+#: kallithea/templates/admin/gists/edit.html:36
+#, python-format
+msgid ""
+"Gist was update since you started editing. Copy your changes and click "
+"%(here)s to reload new version."
+msgstr ""
+
+#: kallithea/templates/admin/gists/edit.html:55
+#: kallithea/templates/admin/gists/new.html:39
+msgid "Gist description ..."
+msgstr "Апісанне..."
+
+#: kallithea/templates/admin/gists/edit.html:57
+#: kallithea/templates/admin/gists/new.html:41
+msgid "Gist lifetime"
+msgstr ""
+
+#: kallithea/templates/admin/gists/edit.html:61
+#: kallithea/templates/admin/gists/edit.html:63
+#: kallithea/templates/admin/gists/index.html:57
+#: kallithea/templates/admin/gists/index.html:59
+#: kallithea/templates/admin/gists/show.html:47
+#: kallithea/templates/admin/gists/show.html:49
+msgid "Expires"
+msgstr "Мінае"
+
+#: kallithea/templates/admin/gists/edit.html:61
+#: kallithea/templates/admin/gists/index.html:57
+#: kallithea/templates/admin/gists/show.html:47
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:8
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:27
+#: kallithea/templates/admin/users/user_edit_api_keys.html:8
+#: kallithea/templates/admin/users/user_edit_api_keys.html:27
+msgid "never"
+msgstr "ніколі"
+
+#: kallithea/templates/admin/gists/edit.html:145
+msgid "Update Gist"
+msgstr "Абнавіць"
+
+#: kallithea/templates/admin/gists/edit.html:146
+#: kallithea/templates/changeset/changeset_file_comment.html:89
+msgid "Cancel"
+msgstr "Адмена"
+
+#: kallithea/templates/admin/gists/index.html:6
+#: kallithea/templates/admin/gists/index.html:16
+#, python-format
+msgid "Private Gists for User %s"
+msgstr "Прыватная gist-запіс для карыстача %s"
+
+#: kallithea/templates/admin/gists/index.html:8
+#: kallithea/templates/admin/gists/index.html:18
+#, python-format
+msgid "Public Gists for User %s"
+msgstr "Публічная gist-запіс для карыстача %s"
+
+#: kallithea/templates/admin/gists/index.html:10
+#: kallithea/templates/admin/gists/index.html:20
+msgid "Public Gists"
+msgstr "Публічныя gist-запісы"
+
+#: kallithea/templates/admin/gists/index.html:37
+#: kallithea/templates/admin/gists/show.html:25
+#: kallithea/templates/base/base.html:240
+msgid "Create New Gist"
+msgstr "Стварыць новую gist-запіс"
+
+#: kallithea/templates/admin/gists/index.html:54
+#: kallithea/templates/data_table/_dt_elements.html:143
+msgid "Created"
+msgstr "Створана"
+
+#: kallithea/templates/admin/gists/index.html:74
+msgid "There are no gists yet"
+msgstr "Gist-запісы адсутнічаюць"
+
+#: kallithea/templates/admin/gists/new.html:5
+#: kallithea/templates/admin/gists/new.html:18
+msgid "New Gist"
+msgstr ""
+
+#: kallithea/templates/admin/gists/new.html:47
+msgid "name this file..."
+msgstr ""
+
+#: kallithea/templates/admin/gists/new.html:56
+msgid "Create Private Gist"
+msgstr ""
+
+#: kallithea/templates/admin/gists/new.html:57
+msgid "Create Public Gist"
+msgstr ""
+
+#: kallithea/templates/admin/gists/new.html:58
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:70
+#: kallithea/templates/admin/my_account/my_account_emails.html:46
+#: kallithea/templates/admin/my_account/my_account_password.html:34
+#: kallithea/templates/admin/my_account/my_account_profile.html:71
+#: kallithea/templates/admin/permissions/permissions_globals.html:109
+#: kallithea/templates/admin/permissions/permissions_ips.html:41
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:115
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:43
+#: kallithea/templates/admin/repos/repo_edit_fields.html:59
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:102
+#: kallithea/templates/admin/repos/repo_edit_settings.html:135
+#: kallithea/templates/admin/settings/settings_global.html:57
+#: kallithea/templates/admin/settings/settings_vcs.html:81
+#: kallithea/templates/admin/settings/settings_visual.html:117
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:105
+#: kallithea/templates/admin/users/user_edit_api_keys.html:70
+#: kallithea/templates/admin/users/user_edit_emails.html:46
+#: kallithea/templates/admin/users/user_edit_ips.html:50
+#: kallithea/templates/admin/users/user_edit_profile.html:123
+#: kallithea/templates/base/default_perms_box.html:65
+#: kallithea/templates/files/files_add.html:65
+#: kallithea/templates/files/files_delete.html:44
+#: kallithea/templates/files/files_edit.html:68
+#: kallithea/templates/pullrequests/pullrequest.html:89
+msgid "Reset"
+msgstr "Скід"
+
+#: kallithea/templates/admin/gists/show.html:5
+#: kallithea/templates/admin/gists/show.html:9
+msgid "Gist"
+msgstr "Gist"
+
+#: kallithea/templates/admin/gists/show.html:10
+#: kallithea/templates/email_templates/changeset_comment.html:15
+#: kallithea/templates/email_templates/pull_request.html:10
+#: kallithea/templates/email_templates/pull_request_comment.html:15
+msgid "URL"
+msgstr "URL"
+
+#: kallithea/templates/admin/gists/show.html:37
+msgid "Public Gist"
+msgstr ""
+
+#: kallithea/templates/admin/gists/show.html:39
+msgid "Private Gist"
+msgstr ""
+
+#: kallithea/templates/admin/gists/show.html:56
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:76
+#: kallithea/templates/changeset/changeset_file_comment.html:50
+#: kallithea/templates/files/files_source.html:39
+#: kallithea/templates/files/files_source.html:42
+#: kallithea/templates/files/files_source.html:45
+msgid "Delete"
+msgstr "Выдаліць"
+
+#: kallithea/templates/admin/gists/show.html:56
+msgid "Confirm to delete this Gist"
+msgstr "Пацвердзіце выдаленне гэтай gist-запісы"
+
+#: kallithea/templates/admin/gists/show.html:63
+#: kallithea/templates/changeset/changeset_file_comment.html:91
+#: kallithea/templates/changeset/changeset_file_comment.html:207
+#: kallithea/templates/data_table/_dt_elements.html:167
+#: kallithea/templates/data_table/_dt_elements.html:183
+#: kallithea/templates/files/diff_2way.html:56
+#: kallithea/templates/files/files_source.html:41
+#: kallithea/templates/files/files_source.html:44
+#: kallithea/templates/pullrequests/pullrequest_show.html:41
+msgid "Edit"
+msgstr "Рэдагаваць"
+
+#: kallithea/templates/admin/gists/show.html:65
+#: kallithea/templates/files/files_edit.html:49
+#: kallithea/templates/files/files_source.html:34
+msgid "Show as Raw"
+msgstr "Паказаць толькі тэкст"
+
+#: kallithea/templates/admin/gists/show.html:73
+msgid "created"
+msgstr "створана"
+
+#: kallithea/templates/admin/gists/show.html:86
+#: kallithea/templates/files/files_source.html:73
+msgid "Show as raw"
+msgstr "Паказаць толькі тэкст"
+
+#: kallithea/templates/admin/my_account/my_account.html:5
+#: kallithea/templates/admin/my_account/my_account.html:9
+#: kallithea/templates/base/base.html:346
+msgid "My Account"
+msgstr "Мой Акаўнт"
+
+#: kallithea/templates/admin/my_account/my_account.html:35
+#: kallithea/templates/admin/users/user_edit.html:29
+msgid "Profile"
+msgstr "Профіль"
+
+#: kallithea/templates/admin/my_account/my_account.html:37
+#: kallithea/templates/admin/users/user_edit.html:30
+msgid "API Keys"
+msgstr "API-ключы"
+
+#: kallithea/templates/admin/my_account/my_account.html:38
+msgid "My Emails"
+msgstr "Мае адрасы E-mail"
+
+#: kallithea/templates/admin/my_account/my_account.html:39
+msgid "My Repositories"
+msgstr "Мае рэпазітары"
+
+#: kallithea/templates/admin/my_account/my_account.html:40
+#: kallithea/templates/journal/journal.html:53
+msgid "Watched"
+msgstr "Прагледжана"
+
+#: kallithea/templates/admin/my_account/my_account.html:41
+msgid "My Permissions"
+msgstr "Мае прывілеі"
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:6
+#: kallithea/templates/admin/users/user_edit_api_keys.html:6
+msgid "Built-in"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:8
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:27
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:32
+#: kallithea/templates/admin/users/user_edit_api_keys.html:8
+#: kallithea/templates/admin/users/user_edit_api_keys.html:27
+#: kallithea/templates/admin/users/user_edit_api_keys.html:32
+msgid "expires"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:14
+#: kallithea/templates/admin/users/user_edit_api_keys.html:14
+#, python-format
+msgid "Confirm to reset this api key: %s"
+msgstr "Пацвердзіце скід гэтага API-ключа: %s"
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:15
+#: kallithea/templates/admin/users/user_edit_api_keys.html:15
+msgid "reset"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:30
+#: kallithea/templates/admin/users/user_edit_api_keys.html:30
+msgid "expired"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:40
+#: kallithea/templates/admin/users/user_edit_api_keys.html:40
+#, python-format
+msgid "Confirm to remove this api key: %s"
+msgstr "Пацвердзіце выдаленне гэтага API-ключа: %s"
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:42
+#: kallithea/templates/admin/users/user_edit_api_keys.html:42
+msgid "remove"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:49
+#: kallithea/templates/admin/users/user_edit_api_keys.html:49
+msgid "No additional api keys specified"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:61
+#: kallithea/templates/admin/users/user_edit_api_keys.html:61
+msgid "New api key"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_api_keys.html:69
+#: kallithea/templates/admin/my_account/my_account_emails.html:45
+#: kallithea/templates/admin/permissions/permissions_ips.html:40
+#: kallithea/templates/admin/repos/repo_add_base.html:85
+#: kallithea/templates/admin/repos/repo_edit_fields.html:58
+#: kallithea/templates/admin/users/user_edit_api_keys.html:69
+#: kallithea/templates/admin/users/user_edit_emails.html:45
+#: kallithea/templates/admin/users/user_edit_ips.html:49
+msgid "Add"
+msgstr "Дадаць"
+
+#: kallithea/templates/admin/my_account/my_account_emails.html:7
+#: kallithea/templates/admin/users/user_edit_emails.html:7
+msgid "Primary"
+msgstr "Асноўны"
+
+#: kallithea/templates/admin/my_account/my_account_emails.html:19
+#: kallithea/templates/admin/permissions/permissions_ips.html:14
+#: kallithea/templates/admin/repos/repo_edit_fields.html:18
+#: kallithea/templates/admin/settings/settings_hooks.html:36
+#: kallithea/templates/admin/users/user_edit_emails.html:19
+#: kallithea/templates/admin/users/user_edit_ips.html:22
+#: kallithea/templates/data_table/_dt_elements.html:131
+#: kallithea/templates/data_table/_dt_elements.html:159
+#: kallithea/templates/data_table/_dt_elements.html:175
+#: kallithea/templates/data_table/_dt_elements.html:191
+msgid "delete"
+msgstr "выдаліць"
+
+#: kallithea/templates/admin/my_account/my_account_emails.html:20
+#: kallithea/templates/admin/users/user_edit_emails.html:20
+#, python-format
+msgid "Confirm to delete this email: %s"
+msgstr "Пацвердзіце выдаленне E-mail: %s"
+
+#: kallithea/templates/admin/my_account/my_account_emails.html:26
+#: kallithea/templates/admin/users/user_edit_emails.html:26
+msgid "No additional emails specified."
+msgstr "Дадатковыя адрасы e-mail не пазначаны."
+
+#: kallithea/templates/admin/my_account/my_account_emails.html:38
+#: kallithea/templates/admin/users/user_edit_emails.html:38
+msgid "New email address"
+msgstr "Новы E-mail"
+
+#: kallithea/templates/admin/my_account/my_account_password.html:1
+msgid "Change Your Account Password"
+msgstr "Змена пароля"
+
+#: kallithea/templates/admin/my_account/my_account_password.html:7
+msgid "Current password"
+msgstr "Бягучы пароль"
+
+#: kallithea/templates/admin/my_account/my_account_password.html:16
+#: kallithea/templates/admin/users/user_edit_profile.html:69
+msgid "New password"
+msgstr "Новы пароль"
+
+#: kallithea/templates/admin/my_account/my_account_password.html:25
+msgid "Confirm new password"
+msgstr "Пацвердзіце новы пароль"
+
+#: kallithea/templates/admin/my_account/my_account_profile.html:11
+msgid "Change your avatar at"
+msgstr "Зменіце аватар праз сайт"
+
+#: kallithea/templates/admin/my_account/my_account_profile.html:12
+#: kallithea/templates/admin/users/user_edit_profile.html:9
+msgid "Using"
+msgstr "Выкарыстоўваецца"
+
+#: kallithea/templates/admin/my_account/my_account_profile.html:14
+#: kallithea/templates/admin/users/user_edit_profile.html:11
+msgid "Avatars are disabled"
+msgstr "Аватары адключаны"
+
+#: kallithea/templates/admin/my_account/my_account_profile.html:15
+msgid "Missing email, please update your user email address."
+msgstr "Не паказаны email. Калі ласка, абновіце ваш email."
+
+#: kallithea/templates/admin/my_account/my_account_profile.html:16
+#: kallithea/templates/admin/users/user_edit_profile.html:15
+msgid "current IP"
+msgstr "бягучы IP-адрас"
+
+#: kallithea/templates/admin/my_account/my_account_profile.html:28
+msgid ""
+"Your user is in an external Source of Record; some details cannot be managed "
+"here"
+msgstr ""
+
+#: kallithea/templates/admin/my_account/my_account_repos.html:1
+msgid "Repositories You Own"
+msgstr "Рэпазітары, дзе Вы — уладальнік"
+
+#: kallithea/templates/admin/my_account/my_account_repos.html:59
+#: kallithea/templates/admin/my_account/my_account_watched.html:59
+#: kallithea/templates/base/root.html:46
+#: kallithea/templates/bookmarks/bookmarks.html:81
+#: kallithea/templates/branches/branches.html:81
+#: kallithea/templates/journal/journal.html:200
+#: kallithea/templates/journal/journal.html:291
+#: kallithea/templates/tags/tags.html:81
+msgid "No records found."
+msgstr "Запісы не знойдзены."
+
+#: kallithea/templates/admin/my_account/my_account_watched.html:1
+msgid "Repositories You are Watching"
+msgstr "Рэпазітары, за якімі Вы назіраеце"
+
+#: kallithea/templates/admin/notifications/notifications.html:5
+#: kallithea/templates/admin/notifications/notifications.html:9
+msgid "My Notifications"
+msgstr "Мае апавяшчэнні"
+
+#: kallithea/templates/admin/notifications/notifications.html:24
+msgid "All"
+msgstr "Усё"
+
+#: kallithea/templates/admin/notifications/notifications.html:25
+msgid "Comments"
+msgstr "Каментары"
+
+#: kallithea/templates/admin/notifications/notifications.html:26
+#: kallithea/templates/base/base.html:186
+msgid "Pull Requests"
+msgstr "Pull-запыты"
+
+#: kallithea/templates/admin/notifications/notifications.html:30
+msgid "Mark All Read"
+msgstr "Адзначыць усё як прачытаныя"
+
+#: kallithea/templates/admin/notifications/notifications_data.html:40
+msgid "No notifications here yet"
+msgstr "Апавяшчэнняў няма"
+
+#: kallithea/templates/admin/notifications/show_notification.html:5
+#: kallithea/templates/admin/notifications/show_notification.html:11
+msgid "Show Notification"
+msgstr "Паказаць апавяшчэнне"
+
+#: kallithea/templates/admin/notifications/show_notification.html:9
+#: kallithea/templates/base/base.html:345
+msgid "Notifications"
+msgstr "Апавяшчэнні"
+
+#: kallithea/templates/admin/permissions/permissions.html:5
+msgid "Permissions Administration"
+msgstr "Кіраванне прывілеямі"
+
+#: kallithea/templates/admin/permissions/permissions.html:11
+#: kallithea/templates/admin/repo_groups/repo_group_edit.html:42
+#: kallithea/templates/admin/repos/repo_edit.html:43
+#: kallithea/templates/admin/user_groups/user_group_edit.html:32
+#: kallithea/templates/base/base.html:64
+msgid "Permissions"
+msgstr "Прывілеі"
+
+#: kallithea/templates/admin/permissions/permissions.html:28
+#: kallithea/templates/admin/settings/settings.html:29
+msgid "Global"
+msgstr ""
+
+#: kallithea/templates/admin/permissions/permissions.html:29
+#: kallithea/templates/admin/users/user_edit.html:34
+msgid "IP Whitelist"
+msgstr "Белы спіс IP"
+
+#: kallithea/templates/admin/permissions/permissions.html:30
+msgid "Overview"
+msgstr "Агляд"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:7
+msgid "Anonymous access"
+msgstr "Ананімны доступ"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:13
+#, python-format
+msgid ""
+"Allow access to Kallithea without needing to log in. Anonymous users use %s "
+"user permissions."
+msgstr ""
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:26
+msgid ""
+"All default permissions on each repository will be reset to chosen "
+"permission, note that all custom default permission on repositories will be "
+"lost"
+msgstr ""
+"Абраныя прывілеі будуць усталяваны па змаўчанні для кожнага рэпазітара. "
+"Улічыце, што раней усталяваныя прывілеі па змаўчанні будуць скінуты"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:27
+#: kallithea/templates/admin/permissions/permissions_globals.html:40
+#: kallithea/templates/admin/permissions/permissions_globals.html:54
+msgid "Overwrite existing settings"
+msgstr "Перазапісаць існыя налады"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:32
+#: kallithea/templates/admin/repos/repo_add_base.html:41
+#: kallithea/templates/admin/repos/repo_edit_settings.html:42
+#: kallithea/templates/data_table/_dt_elements.html:204
+#: kallithea/templates/forks/fork.html:48
+msgid "Repository group"
+msgstr "Група рэпазітароў"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:39
+msgid ""
+"All default permissions on each repository group will be reset to chosen "
+"permission, note that all custom default permission on repository groups "
+"will be lost"
+msgstr ""
+"Абраныя прывілеі будуць усталяваны па змаўчанні для кожнай групы "
+"рэпазітароў. Улічыце, што раней усталяваныя прывілеі па змаўчанні для груп "
+"рэпазітароў будуць скінуты"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:46
+#: kallithea/templates/data_table/_dt_elements.html:211
+msgid "User group"
+msgstr "Група карыстачоў"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:53
+msgid ""
+"All default permissions on each user group will be reset to chosen "
+"permission, note that all custom default permission on repository groups "
+"will be lost"
+msgstr ""
+"Абраныя прывілеі будуць усталяваны па змаўчанні для кожнай групы карыстачоў. "
+"Улічыце, што раней усталяваныя прывілеі па змаўчанні для груп карыстачоў "
+"будуць скінуты"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:60
+msgid "Repository creation"
+msgstr "Стварэнне рэпазітара"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:68
+msgid "Repository creation with group write access"
+msgstr ""
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:72
+msgid ""
+"Write permission to a repository group allows creating repositories inside "
+"that group."
+msgstr ""
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:77
+msgid "User group creation"
+msgstr "Стварэнне груп карыстачоў"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:85
+msgid "Repository forking"
+msgstr "Стварэнне форка рэпазітара"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:93
+msgid "Registration"
+msgstr "Рэгістрацыя"
+
+#: kallithea/templates/admin/permissions/permissions_globals.html:101
+msgid "External auth account activation"
+msgstr "Актывацыя іншага ўліковага запісу"
+
+#: kallithea/templates/admin/permissions/permissions_ips.html:1
+msgid "Default IP Whitelist for All Users"
+msgstr "Белы спіс IP для ўсіх карыстачоў"
+
+#: kallithea/templates/admin/permissions/permissions_ips.html:15
+#: kallithea/templates/admin/users/user_edit_ips.html:23
+#, python-format
+msgid "Confirm to delete this ip: %s"
+msgstr "Пацвердзіце выдаленне IP %s"
+
+#: kallithea/templates/admin/permissions/permissions_ips.html:21
+#: kallithea/templates/admin/users/user_edit_ips.html:30
+msgid "All IP addresses are allowed."
+msgstr "Дазволены любыя IP-адрасы."
+
+#: kallithea/templates/admin/permissions/permissions_ips.html:32
+#: kallithea/templates/admin/users/user_edit_ips.html:42
+msgid "New IP address"
+msgstr "Новы IP-адрас"
+
+#: kallithea/templates/admin/permissions/permissions_perms.html:1
+msgid "Default User Permissions Overview"
+msgstr "Агляд мае рацыю карыстачоў па змаўчанні"
+
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:11
+#: kallithea/templates/admin/repo_groups/repo_group_edit.html:11
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:105
+#: kallithea/templates/admin/repo_groups/repo_groups.html:10
+#: kallithea/templates/base/base.html:61 kallithea/templates/base/base.html:80
+msgid "Repository Groups"
+msgstr "Групы рэпазітароў"
+
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:33
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:8
+#: kallithea/templates/admin/user_groups/user_group_add.html:32
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:7
+msgid "Group name"
+msgstr "Імя групы"
+
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:51
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:26
+msgid "Group parent"
+msgstr "Бацькоўская група"
+
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:60
+#: kallithea/templates/admin/repos/repo_add_base.html:50
+msgid "Copy parent group permissions"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_add.html:64
+#: kallithea/templates/admin/repos/repo_add_base.html:54
+msgid "Copy permission set from parent repository group."
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit.html:5
+#, python-format
+msgid "%s Repository Group Settings"
+msgstr "Налады групы рэпазітароў %s"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit.html:21
+msgid "Add Child Group"
+msgstr "Дадаць падгрупу"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit.html:40
+#: kallithea/templates/admin/repos/repo_edit.html:12
+#: kallithea/templates/admin/repos/repo_edit.html:40
+#: kallithea/templates/admin/settings/settings.html:11
+#: kallithea/templates/admin/user_groups/user_group_edit.html:29
+#: kallithea/templates/base/base.html:67
+#: kallithea/templates/base/base.html:154
+#: kallithea/templates/data_table/_dt_elements.html:43
+#: kallithea/templates/data_table/_dt_elements.html:47
+msgid "Settings"
+msgstr "Налады"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit.html:41
+#: kallithea/templates/admin/repos/repo_edit.html:46
+#: kallithea/templates/admin/user_groups/user_group_edit.html:30
+#: kallithea/templates/admin/users/user_edit.html:31
+msgid "Advanced"
+msgstr "Дадаткова"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:1
+#, python-format
+msgid "Repository Group: %s"
+msgstr "Група рэпазітароў: %s"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:6
+msgid "Top level repositories"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:7
+msgid "Total repositories"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:8
+msgid "Children groups"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:9
+#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:7
+#: kallithea/templates/admin/users/user_edit_advanced.html:8
+#: kallithea/templates/pullrequests/pullrequest_show.html:147
+msgid "Created on"
+msgstr "Створана"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:21
+#: kallithea/templates/data_table/_dt_elements.html:192
+#, python-format
+msgid "Confirm to delete this group: %s with %s repository"
+msgid_plural "Confirm to delete this group: %s with %s repositories"
+msgstr[0] "Пацвердзіце выдаленне групы %s, утрымоўвалай %s рэпазітар"
+msgstr[1] "Пацвердзіце выдаленне групы %s, утрымоўвалай %s рэпазітара"
+msgstr[2] "Пацвердзіце выдаленне групы %s, утрымоўвалай %s рэпазітароў"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:25
+msgid "Delete this repository group"
+msgstr "Выдаліць гэту групу рэпазітароў"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:7
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:8
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:7
+#: kallithea/templates/base/perms_summary.html:14
+msgid "none"
+msgstr "нічога"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:8
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:9
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:8
+#: kallithea/templates/base/perms_summary.html:15
+msgid "read"
+msgstr "чытаць"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:9
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:10
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:9
+#: kallithea/templates/base/perms_summary.html:16
+msgid "write"
+msgstr "запісваць"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:10
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:11
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:10
+#: kallithea/templates/base/perms_summary.html:17
+msgid "admin"
+msgstr "адміністратар"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:11
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:12
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:11
+msgid "user/user group"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:28
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:45
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:24
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:37
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:28
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:45
+msgid "default"
+msgstr "па змаўчанні"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:34
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:71
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:43
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:68
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:34
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:71
+msgid "revoke"
+msgstr "адклікаць"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:47
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:47
+msgid "delegated admin"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:97
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:94
+#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:97
+msgid "Add new"
+msgstr "Дадаць новы"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:103
+msgid "apply to children"
+msgstr "дастасаваць да даччыным"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:107
+msgid "Both"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:108
+msgid ""
+"Set or revoke permission to all children of that group, including non-"
+"private repositories and other groups if selected."
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:38
+msgid ""
+"Enable lock-by-pulling on group. This option will be applied to all other "
+"groups and repositories inside"
+msgstr ""
+"Уключыць аўтаблакоўку для групы. Гэта опцыя будзе ўжыта да ўсіх даччыных "
+"груп і рэпазітарам"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:53
+msgid "Remove this group"
+msgstr "Выдаліць гэту групу"
+
+#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:53
+msgid "Confirm to delete this group"
+msgstr "Пацвердзіце выдаленне гэтай групы карыстачоў"
+
+#: kallithea/templates/admin/repo_groups/repo_group_show.html:4
+#, python-format
+msgid "%s Repository group dashboard"
+msgstr ""
+
+#: kallithea/templates/admin/repo_groups/repo_group_show.html:9
+msgid "Home"
+msgstr "Дахаты"
+
+#: kallithea/templates/admin/repo_groups/repo_group_show.html:13
+msgid "with"
+msgstr "з"
+
+#: kallithea/templates/admin/repo_groups/repo_groups.html:5
+msgid "Repository Groups Administration"
+msgstr "Адміністраванне груп рэпазітароў"
+
+#: kallithea/templates/admin/repo_groups/repo_groups.html:48
+msgid "Number of Top-level Repositories"
+msgstr "Лік рэпазітароў верхняга ўзроўня"
+
+#: kallithea/templates/admin/repos/repo_add_base.html:14
+msgid "Import existing repository ?"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_add_base.html:23
+#: kallithea/templates/summary/summary.html:29
+msgid "Clone from"
+msgstr "Кланаваць з"
+
+#: kallithea/templates/admin/repos/repo_add_base.html:27
+msgid "Optional URL from which repository should be cloned."
+msgstr "Апцыянальны URL, з якога патрабуецца скланаваць рэпазітар."
+
+#: kallithea/templates/admin/repos/repo_add_base.html:36
+#: kallithea/templates/admin/repos/repo_edit_settings.html:76
+#: kallithea/templates/forks/fork.html:42
+msgid ""
+"Keep it short and to the point. Use a README file for longer descriptions."
+msgstr ""
+"Кароткае і асэнсаванае. Для разгорнутага апісання выкарыстоўвайце файл "
+"README."
+
+#: kallithea/templates/admin/repos/repo_add_base.html:45
+#: kallithea/templates/admin/repos/repo_edit_settings.html:46
+#: kallithea/templates/forks/fork.html:52
+msgid "Optionally select a group to put this repository into."
+msgstr "Апцыянальна абраць групу, у якую змясціць дадзены рэпазітар."
+
+#: kallithea/templates/admin/repos/repo_add_base.html:63
+msgid "Type of repository to create."
+msgstr "Тып стваранага рэпазітара."
+
+#: kallithea/templates/admin/repos/repo_add_base.html:68
+#: kallithea/templates/admin/repos/repo_edit_settings.html:51
+#: kallithea/templates/forks/fork.html:58
+msgid "Landing revision"
+msgstr "Рэвізія для выгрузкі"
+
+#: kallithea/templates/admin/repos/repo_add_base.html:72
+msgid ""
+"Default revision for files page, downloads, full text search index and "
+"readme generation"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_creating.html:9
+#, python-format
+msgid "%s Creating Repository"
+msgstr "Стварэнне рэпазітара %s"
+
+#: kallithea/templates/admin/repos/repo_creating.html:13
+msgid "Creating repository"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_creating.html:27
+#, python-format
+msgid ""
+"Repository \"%(repo_name)s\" is being created, you will be redirected when "
+"this process is finished.repo_name"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_creating.html:39
+msgid ""
+"We're sorry but error occurred during this operation. Please check your "
+"Kallithea server logs, or contact administrator."
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit.html:8
+#, python-format
+msgid "%s Repository Settings"
+msgstr "Налады рэпазітара %s"
+
+#: kallithea/templates/admin/repos/repo_edit.html:49
+msgid "Extra Fields"
+msgstr "Дадатковыя палі"
+
+#: kallithea/templates/admin/repos/repo_edit.html:52
+msgid "Caches"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit.html:55
+msgid "Remote"
+msgstr "Выдалены"
+
+#: kallithea/templates/admin/repos/repo_edit.html:58
+#: kallithea/templates/summary/statistics.html:8
+#: kallithea/templates/summary/summary.html:174
+#: kallithea/templates/summary/summary.html:175
+msgid "Statistics"
+msgstr "Статыстыка"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:1
+msgid "Parent"
+msgstr "Бацькоўская група"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:5
+#: kallithea/templates/admin/repos/repo_edit_fork.html:5
+msgid "Set"
+msgstr "Набор"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:8
+#: kallithea/templates/admin/repos/repo_edit_fork.html:9
+msgid "Manually set this repository as a fork of another from the list."
+msgstr "Уручную зрабіць гэты рэпазітар форкам абранага са спісу."
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:22
+msgid "Public Journal Visibility"
+msgstr "Доступ да публічнага часопіса"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:30
+msgid "Remove from public journal"
+msgstr "Выдаліць з агульнадаступнага часопіса"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:35
+msgid "Add to Public Journal"
+msgstr "Дадаць у публічны часопіс"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:41
+msgid ""
+"All actions done in this repository will be visible to everyone in the "
+"public journal."
+msgstr ""
+"Усе выконваемыя з гэтым рэпазітаром дзеянні будуць адлюстроўвацца ў "
+"публічным часопісе."
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:47
+msgid "Change Locking"
+msgstr "Уключыць блакаванне"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:53
+msgid "Confirm to unlock repository."
+msgstr "Пацвердзіце здыманне блакавання з рэпазітара."
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:55
+msgid "Unlock Repository"
+msgstr "Разблакаваць рэпазітар"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:61
+msgid "Confirm to lock repository."
+msgstr "Пацвердзіце блакаванне рэпазітара."
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:63
+msgid "Lock Repository"
+msgstr "Заблакаваць рэпазітар"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:65
+msgid "Repository is not locked"
+msgstr "Рэпазітар не заблакаваны"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:69
+msgid ""
+"Force locking on the repository. Works only when anonymous access is "
+"disabled. Triggering a pull locks the repository.  The user who is pulling "
+"locks the repository; only the user who pulled and locked it can unlock it "
+"by doing a push."
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:80
+#: kallithea/templates/data_table/_dt_elements.html:132
+#, python-format
+msgid "Confirm to delete this repository: %s"
+msgstr "Пацвердзіце выдаленне гэтага рэпазітара: %s"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:82
+msgid "Delete this Repository"
+msgstr "Выдаліць гэты рэпазітар"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:85
+#, python-format
+msgid "This repository has %s fork"
+msgid_plural "This repository has %s forks"
+msgstr[0] "Дадзены рэпазітар мае %s копію"
+msgstr[1] "Дадзены рэпазітар мае %s копіі"
+msgstr[2] "Дадзены рэпазітар мае %s дзід"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:86
+msgid "Detach forks"
+msgstr "Адлучыць fork'і"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:87
+msgid "Delete forks"
+msgstr "Выдаліць fork'і"
+
+#: kallithea/templates/admin/repos/repo_edit_advanced.html:91
+msgid ""
+"The deleted repository will be moved away and hidden until the administrator "
+"expires it. The administrator can both permanently delete it or restore it."
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_caches.html:4
+msgid "Invalidate Repository Cache"
+msgstr "Скінуць кэш рэпазітара"
+
+#: kallithea/templates/admin/repos/repo_edit_caches.html:4
+msgid "Confirm to invalidate repository cache."
+msgstr "Пацвердзіце скід кэша."
+
+#: kallithea/templates/admin/repos/repo_edit_caches.html:7
+msgid ""
+"Manually invalidate cache for this repository. On first access, the "
+"repository will be cached again."
+msgstr "Ручны скід кэша рэпазітара. Пры першым доступе кэш адновіцца."
+
+#: kallithea/templates/admin/repos/repo_edit_caches.html:12
+msgid "List of Cached Values"
+msgstr "Спіс кэшаваных значэнняў"
+
+#: kallithea/templates/admin/repos/repo_edit_caches.html:15
+msgid "Prefix"
+msgstr "Прэфікс"
+
+#: kallithea/templates/admin/repos/repo_edit_caches.html:16
+#: kallithea/templates/admin/repos/repo_edit_fields.html:6
+msgid "Key"
+msgstr "Ключ"
+
+#: kallithea/templates/admin/repos/repo_edit_caches.html:17
+#: kallithea/templates/admin/user_groups/user_group_add.html:49
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:24
+#: kallithea/templates/admin/user_groups/user_groups.html:49
+#: kallithea/templates/admin/users/user_add.html:88
+#: kallithea/templates/admin/users/user_edit_profile.html:105
+#: kallithea/templates/admin/users/users.html:54
+msgid "Active"
+msgstr "Актыўны"
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:5
+msgid "Label"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:19
+#, python-format
+msgid "Confirm to delete this field: %s"
+msgstr "Пацвердзіце выдаленне гэтага поля: %s"
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:33
+msgid "New field key"
+msgstr "Ключ"
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:41
+msgid "New field label"
+msgstr "Імя поля"
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:44
+msgid "Enter short label"
+msgstr "Увядзіце кароткае імя поля"
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:50
+msgid "New field description"
+msgstr "Апісанне поля"
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:53
+msgid "Enter description of a field"
+msgstr "Увядзіце апісанне поля"
+
+#: kallithea/templates/admin/repos/repo_edit_fields.html:66
+msgid "Extra fields are disabled."
+msgstr "Дадатковыя палі адключаны."
+
+#: kallithea/templates/admin/repos/repo_edit_permissions.html:21
+msgid "private repository"
+msgstr "прыватны рэпазітар"
+
+#: kallithea/templates/admin/repos/repo_edit_remote.html:3
+msgid "Remote URL"
+msgstr "Спасылка для кланавання"
+
+#: kallithea/templates/admin/repos/repo_edit_remote.html:8
+msgid "Pull Changes from Remote Location"
+msgstr "Атрымаць змены з выдаленага боку"
+
+#: kallithea/templates/admin/repos/repo_edit_remote.html:8
+msgid "Confirm to pull changes from remote side."
+msgstr "Пацвердзіце спампоўку змен."
+
+#: kallithea/templates/admin/repos/repo_edit_remote.html:14
+msgid "This repository does not have a remote URL set."
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:11
+msgid "Non-changeable id"
+msgstr "Нязменлівы id"
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:11
+msgid "What is that?"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:13
+msgid "URL by id"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:14
+msgid ""
+"In case this repository is renamed or moved into another group the "
+"repository URL changes.\n"
+"                               Using the above URL guarantees that this "
+"repository will always be accessible under such URL.\n"
+"                               Useful for CI systems, or any other cases "
+"that you need to hardcode the URL into 3rd party service."
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:21
+#: kallithea/templates/summary/summary.html:72
+msgid "Clone URL"
+msgstr "Спасылка для кланавання"
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:27
+#: kallithea/templates/base/perms_summary.html:43
+#: kallithea/templates/base/perms_summary.html:79
+#: kallithea/templates/base/perms_summary.html:81
+#: kallithea/templates/data_table/_dt_elements.html:124
+#: kallithea/templates/data_table/_dt_elements.html:125
+#: kallithea/templates/data_table/_dt_elements.html:152
+#: kallithea/templates/data_table/_dt_elements.html:153
+#: kallithea/templates/data_table/_dt_elements.html:169
+#: kallithea/templates/data_table/_dt_elements.html:185
+msgid "edit"
+msgstr "рэдагаваць"
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:30
+msgid "new value"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:37
+msgid "URL used for doing remote pulls."
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:55
+msgid "Default revision for files page, downloads, whoosh and readme"
+msgstr ""
+"Рэвізія па змаўчанні, з якой будзе вырабляцца выгрузка файлаў пры спампоўцы"
+
+#: kallithea/templates/admin/repos/repo_edit_settings.html:65
+msgid "Change owner of this repository."
+msgstr "Змяніць уладальніка рэпазітара."
+
+#: kallithea/templates/admin/repos/repo_edit_statistics.html:6
+msgid "Processed commits"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_statistics.html:7
+msgid "Processed progress"
+msgstr ""
+
+#: kallithea/templates/admin/repos/repo_edit_statistics.html:10
+msgid "Reset Statistics"
+msgstr "Скід статыстыкі"
+
+#: kallithea/templates/admin/repos/repo_edit_statistics.html:10
+msgid "Confirm to remove current statistics."
+msgstr "Пацвердзіце скід статыстыкі."
+
+#: kallithea/templates/admin/repos/repos.html:5
+msgid "Repositories Administration"
+msgstr "Адміністраванне рэпазітароў"
+
+#: kallithea/templates/admin/repos/repos.html:51
+msgid "State"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings.html:5
+msgid "Settings Administration"
+msgstr "Адміністраванне налад"
+
+#: kallithea/templates/admin/settings/settings.html:27
+msgid "VCS"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings.html:28
+msgid "Remap and Rescan"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings.html:30
+msgid "Visual"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings.html:32
+#: kallithea/templates/admin/settings/settings_vcs.html:19
+msgid "Hooks"
+msgstr "Хукі"
+
+#: kallithea/templates/admin/settings/settings.html:33
+msgid "Full Text Search"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings.html:34
+msgid "System Info"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:4
+msgid "Email prefix"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:5
+msgid "Kallithea email from"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:6
+msgid "Error email from"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:7
+msgid "Error email recipients"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:9
+msgid "SMTP server"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:10
+msgid "SMTP username"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:11
+msgid "SMTP password"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:12
+msgid "SMTP port"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:14
+msgid "SMTP use TLS"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:15
+msgid "SMTP use SSL"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:16
+msgid "SMTP auth"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:31
+msgid "Send test email to"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_email.html:39
+msgid "Send"
+msgstr "Адправіць"
+
+#: kallithea/templates/admin/settings/settings_global.html:8
+msgid "Site branding"
+msgstr "Брэндынг сайта"
+
+#: kallithea/templates/admin/settings/settings_global.html:12
+msgid "Set a custom title for your Kallithea Service."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_global.html:18
+msgid "HTTP authentication realm"
+msgstr "Прывітанне для HTTP-аўтэнтыфікацыі"
+
+#: kallithea/templates/admin/settings/settings_global.html:27
+msgid "Analytics HTML block"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_global.html:31
+msgid ""
+"HTML with JavaScript for web analytics systems like Google Analytics or "
+"Piwik. This will be added at the bottom of every page."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_global.html:37
+msgid "ReCaptcha public key"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_global.html:41
+msgid "Public key for reCaptcha system."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_global.html:47
+msgid "ReCaptcha private key"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_global.html:51
+msgid ""
+"Private key for reCaptcha system. Setting this value will enable captcha on "
+"registration."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_global.html:56
+#: kallithea/templates/admin/settings/settings_vcs.html:80
+#: kallithea/templates/admin/settings/settings_visual.html:116
+msgid "Save Settings"
+msgstr "Захаваць налады"
+
+#: kallithea/templates/admin/settings/settings_hooks.html:1
+msgid "Built-in Mercurial Hooks (Read-Only)"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_hooks.html:15
+msgid ""
+"Hooks can be used to trigger actions on certain events such as push / pull. "
+"They can trigger Python functions or external applications."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_hooks.html:19
+msgid "Custom Hooks"
+msgstr "Карыстацкія хуки"
+
+#: kallithea/templates/admin/settings/settings_hooks.html:68
+msgid "Failed to remove hook"
+msgstr "Не атрымалася выдаліць хук"
+
+#: kallithea/templates/admin/settings/settings_mapping.html:6
+msgid "Rescan option"
+msgstr "Опцыі перасканіравання"
+
+#: kallithea/templates/admin/settings/settings_mapping.html:11
+msgid "Destroy old data"
+msgstr "Знішчыць усе дадзеныя"
+
+#: kallithea/templates/admin/settings/settings_mapping.html:13
+msgid ""
+"Check this option to remove references to repositories that no longer exist "
+"in on the filesystem."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_mapping.html:17
+msgid "Invalidate cache for all repositories"
+msgstr "Скінуць кэш для ўсіх рэпазітароў"
+
+#: kallithea/templates/admin/settings/settings_mapping.html:19
+msgid "Check this to reload data and clear cache keys for all repositories."
+msgstr "Скінуць кэш для ўсіх рэпазітароў."
+
+#: kallithea/templates/admin/settings/settings_mapping.html:23
+msgid "Install Git hooks"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_mapping.html:25
+msgid ""
+"Verify if Kallithea's Git hooks are installed for each repository. Current "
+"hooks will be updated to the latest version."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_mapping.html:32
+msgid "Rescan Repositories"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_search.html:7
+msgid "Index build option"
+msgstr "Опцыі стварэння індэксу"
+
+#: kallithea/templates/admin/settings/settings_search.html:12
+msgid "Build from scratch"
+msgstr "Зборка з нуля"
+
+#: kallithea/templates/admin/settings/settings_search.html:15
+msgid ""
+"This option completely reindexeses all of the repositories for proper "
+"fulltext search capabilities."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_search.html:21
+msgid "Reindex"
+msgstr "Перабудаваць індэкс"
+
+#: kallithea/templates/admin/settings/settings_system.html:4
+msgid "Kallithea version"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:4
+msgid "check for updates"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:5
+msgid "Python version"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:6
+msgid "Platform"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:7
+msgid "Git version"
+msgstr "Версія Git"
+
+#: kallithea/templates/admin/settings/settings_system.html:8
+msgid "Git path"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:9
+msgid "Upgrade info endpoint"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:9
+msgid "Note: please make sure this server can access this URL"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:14
+msgid "Checking for updates..."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_system.html:22
+msgid "Python Packages"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_vcs.html:6
+msgid "Web"
+msgstr "Вэб"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:11
+msgid "Require SSL for vcs operations"
+msgstr "Запытваць SSL для аперацый з VCS"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:13
+msgid ""
+"Activate to require SSL both pushing and pulling. If SSL certificate is "
+"missing, it will return an HTTP Error 406: Not Acceptable."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_vcs.html:24
+msgid "Show repository size after push"
+msgstr "Паказваць памер рэпазітара пасля адпраўкі"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:28
+msgid "Log user push commands"
+msgstr "Лагіраваць карыстацкія каманды адпраўкі"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:32
+msgid "Log user pull commands"
+msgstr "Лагіраваць карыстацкія каманды атрымання"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:36
+msgid "Update repository after push (hg update)"
+msgstr "Абнаўляць рэпазітар пасля адпраўкі (hg update)"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:42
+msgid "Mercurial extensions"
+msgstr "Пашырэнні Mercurial"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:47
+msgid "Enable largefiles extension"
+msgstr "Уключыць падтрымку вялікіх файлаў"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:51
+msgid "Enable hgsubversion extension"
+msgstr "Уключыць падтрымку hgsubversion"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:53
+msgid ""
+"Requires hgsubversion library to be installed. Enables cloning of remote "
+"Subversion repositories while converting them to Mercurial."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_vcs.html:64
+msgid "Location of repositories"
+msgstr "Месцазнаходжанне рэпазітароў"
+
+#: kallithea/templates/admin/settings/settings_vcs.html:69
+msgid ""
+"Click to unlock. You must restart Kallithea in order to make this setting "
+"take effect."
+msgstr ""
+"Націсніце для разблакавання. Змены набудуць моц пасля перазагрузкі Kallithea."
+
+#: kallithea/templates/admin/settings/settings_vcs.html:72
+msgid ""
+"Filesystem location where repositories are stored. After changing this "
+"value, a restart and rescan of the repository folder are both required."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:8
+msgid "General"
+msgstr "Галоўнае"
+
+#: kallithea/templates/admin/settings/settings_visual.html:13
+msgid "Use repository extra fields"
+msgstr "Выкарыстоўваць дадатковыя палі ў рэпазітарах"
+
+#: kallithea/templates/admin/settings/settings_visual.html:15
+msgid "Allows storing additional customized fields per repository."
+msgstr "Дазваляе захоўваць дадатковыя палі ў рэпазітарах."
+
+#: kallithea/templates/admin/settings/settings_visual.html:18
+msgid "Show Kallithea version"
+msgstr "Адлюстроўваць версію Kallithea"
+
+#: kallithea/templates/admin/settings/settings_visual.html:20
+msgid "Shows or hides a version number of Kallithea displayed in the footer."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:24
+msgid "Use Gravatars in Kallithea"
+msgstr "Выкарыстоўваць Gravatars у Kallithea"
+
+#: kallithea/templates/admin/settings/settings_visual.html:30
+msgid ""
+"Gravatar URL allows you to use another avatar server application.\n"
+"                                                        The following "
+"variables of the URL will be replaced accordingly.\n"
+"                                                        {scheme}    'http' "
+"or 'https' sent from running Kallithea server,\n"
+"                                                        {email}     user "
+"email,\n"
+"                                                        {md5email}  md5 hash "
+"of the user email (like at gravatar.com),\n"
+"                                                        {size}      size of "
+"the image that is expected from the server application,\n"
+"                                                        {netloc}    network "
+"location/server host of running Kallithea server"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:42
+msgid ""
+"Schema of clone URL construction eg. '{scheme}://{user}@{netloc}/{repo}'.\n"
+"                                                        The following "
+"variables are available:\n"
+"                                                        {scheme} 'http' or "
+"'https' sent from running Kallithea server,\n"
+"                                                        {user}   current "
+"user username,\n"
+"                                                        {netloc} network "
+"location/server host of running Kallithea server,\n"
+"                                                        {repo}   full "
+"repository name,\n"
+"                                                        {repoid} ID of "
+"repository, can be used to contruct clone-by-id"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:55
+msgid "Dashboard items"
+msgstr "Элементы панэлі"
+
+#: kallithea/templates/admin/settings/settings_visual.html:59
+msgid ""
+"Number of items displayed in the main page dashboard before pagination is "
+"shown."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:65
+msgid "Admin pages items"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:69
+msgid ""
+"Number of items displayed in the admin pages grids before pagination is "
+"shown."
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:75
+msgid "Icons"
+msgstr "Абразкі"
+
+#: kallithea/templates/admin/settings/settings_visual.html:80
+msgid "Show public repo icon on repositories"
+msgstr "Паказваць абразкі публічных рэпазітароў"
+
+#: kallithea/templates/admin/settings/settings_visual.html:84
+msgid "Show private repo icon on repositories"
+msgstr "Паказваць абразкі прыватных рэпазітароў"
+
+#: kallithea/templates/admin/settings/settings_visual.html:86
+msgid "Show public/private icons next to repository names."
+msgstr "Паказваць абразкі публічных рэпазітароў."
+
+#: kallithea/templates/admin/settings/settings_visual.html:92
+msgid "Meta-Tagging"
+msgstr "Метатэгіраванне"
+
+#: kallithea/templates/admin/settings/settings_visual.html:97
+msgid "Stylify recognised meta tags:"
+msgstr ""
+
+#: kallithea/templates/admin/settings/settings_visual.html:111
+msgid ""
+"Parses meta tags from the repository description field and turns them into "
+"colored tags."
+msgstr ""
+
+#: kallithea/templates/admin/user_groups/user_group_add.html:5
+msgid "Add user group"
+msgstr "Дадаць групу карыстачоў"
+
+#: kallithea/templates/admin/user_groups/user_group_add.html:10
+#: kallithea/templates/admin/user_groups/user_group_edit.html:11
+#: kallithea/templates/base/base.html:63 kallithea/templates/base/base.html:83
+msgid "User Groups"
+msgstr "Групы карыстальнікаў"
+
+#: kallithea/templates/admin/user_groups/user_group_add.html:12
+#: kallithea/templates/admin/user_groups/user_groups.html:25
+msgid "Add User Group"
+msgstr "Дадаць групу карыстальнікаў"
+
+#: kallithea/templates/admin/user_groups/user_group_add.html:44
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:19
+msgid "Short, optional description for this user group."
+msgstr "Кароткае дадатковае апісанне для гэтай групы карыстальнікаў."
+
+#: kallithea/templates/admin/user_groups/user_group_edit.html:5
+#, python-format
+msgid "%s user group settings"
+msgstr ""
+
+#: kallithea/templates/admin/user_groups/user_group_edit.html:31
+msgid "Default permissions"
+msgstr "Стандартныя прывілеі"
+
+#: kallithea/templates/admin/user_groups/user_group_edit.html:33
+#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:6
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:32
+#: kallithea/templates/admin/user_groups/user_groups.html:48
+msgid "Members"
+msgstr "Удзельнікі"
+
+#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:1
+#, python-format
+msgid "User Group: %s"
+msgstr ""
+
+#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:19
+#: kallithea/templates/data_table/_dt_elements.html:176
+#, python-format
+msgid "Confirm to delete this user group: %s"
+msgstr "Пацвердзіце выдаленне наступнай групы карыстачоў: %s"
+
+#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:21
+msgid "Delete this user group"
+msgstr "Выдаліць гэтую групу карыстальнікаў"
+
+#: kallithea/templates/admin/user_groups/user_group_edit_members.html:17
+msgid "No members yet"
+msgstr "Няма ўдзельнікаў"
+
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:40
+msgid "Chosen group members"
+msgstr "Абраныя ўдзельнікі групы"
+
+#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:49
+msgid "Available members"
+msgstr "Даступныя ўдзельнікі"
+
+#: kallithea/templates/admin/user_groups/user_groups.html:5
+msgid "User Groups Administration"
+msgstr "Адміністраванне груп карыстачоў"
+
+#: kallithea/templates/admin/user_groups/user_groups.html:10
+msgid "user groups"
+msgstr "групы карыстальнікаў"
+
+#: kallithea/templates/admin/users/user_add.html:5
+msgid "Add user"
+msgstr "Дадаць карыстача"
+
+#: kallithea/templates/admin/users/user_add.html:10
+#: kallithea/templates/admin/users/user_edit.html:11
+#: kallithea/templates/admin/users/users.html:10
+#: kallithea/templates/base/base.html:62
+msgid "Users"
+msgstr "Карыстачы"
+
+#: kallithea/templates/admin/users/user_add.html:12
+#: kallithea/templates/admin/users/users.html:24
+msgid "Add User"
+msgstr "Дадаць карыстача"
+
+#: kallithea/templates/admin/users/user_add.html:50
+msgid "Password confirmation"
+msgstr "Пацверджанне пароля"
+
+#: kallithea/templates/admin/users/user_edit.html:5
+#, python-format
+msgid "%s user settings"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit.html:32
+msgid "Default Permissions"
+msgstr "Стандартныя прывілеі"
+
+#: kallithea/templates/admin/users/user_edit.html:33
+msgid "Emails"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_advanced.html:1
+#, python-format
+msgid "User: %s"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_advanced.html:7
+#: kallithea/templates/admin/users/user_edit_profile.html:51
+msgid "Source of Record"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_advanced.html:9
+#: kallithea/templates/admin/users/users.html:53
+msgid "Last Login"
+msgstr "Апошні ўваход"
+
+#: kallithea/templates/admin/users/user_edit_advanced.html:10
+msgid "Member of User groups"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_advanced.html:21
+#: kallithea/templates/data_table/_dt_elements.html:160
+#, python-format
+msgid "Confirm to delete this user: %s"
+msgstr "Пацвердзіце выдаленне карыстача %s"
+
+#: kallithea/templates/admin/users/user_edit_advanced.html:23
+msgid "Delete this user"
+msgstr "Выдаліць гэтага карыстальніка"
+
+#: kallithea/templates/admin/users/user_edit_ips.html:8
+#, python-format
+msgid "Inherited from %s"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_profile.html:8
+msgid "Change avatar at"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_profile.html:12
+msgid "Missing email, please update this user email address."
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_profile.html:27
+#, python-format
+msgid ""
+"This user is in an external Source of Record (%s); some details cannot be "
+"managed here."
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_profile.html:60
+msgid "Name in Source of Record"
+msgstr ""
+
+#: kallithea/templates/admin/users/user_edit_profile.html:78
+msgid "New password confirmation"
+msgstr "Пацвердзіце новы пароль"
+
+#: kallithea/templates/admin/users/users.html:5
+msgid "Users Administration"
+msgstr "Адміністраванне карыстачоў"
+
+#: kallithea/templates/admin/users/users.html:56
+msgid "Auth Type"
+msgstr ""
+
+#: kallithea/templates/base/base.html:18
+#, python-format
+msgid "Server instance: %s"
+msgstr "Асобнік сервера: %s"
+
+#: kallithea/templates/base/base.html:30
+msgid "Support"
+msgstr "Падтрымка"
+
+#: kallithea/templates/base/base.html:122
+msgid "Create Fork"
+msgstr "Стварыць форк"
+
+#: kallithea/templates/base/base.html:133
+#: kallithea/templates/data_table/_dt_elements.html:11
+#: kallithea/templates/data_table/_dt_elements.html:15
+#: kallithea/templates/summary/summary.html:8
+msgid "Summary"
+msgstr "Агульныя звесткі"
+
+#: kallithea/templates/base/base.html:135
+#: kallithea/templates/base/base.html:137
+#: kallithea/templates/changelog/changelog.html:14
+#: kallithea/templates/data_table/_dt_elements.html:19
+#: kallithea/templates/data_table/_dt_elements.html:23
+msgid "Changelog"
+msgstr "Гісторыя змен"
+
+#: kallithea/templates/base/base.html:139
+#: kallithea/templates/data_table/_dt_elements.html:27
+#: kallithea/templates/data_table/_dt_elements.html:31
+#: kallithea/templates/files/files.html:11
+msgid "Files"
+msgstr "Файлы"
+
+#: kallithea/templates/base/base.html:141
+msgid "Switch To"
+msgstr "Пераключыцца на"
+
+#: kallithea/templates/base/base.html:148
+#: kallithea/templates/base/base.html:150
+msgid "Options"
+msgstr "Опцыі"
+
+#: kallithea/templates/base/base.html:158
+#: kallithea/templates/forks/forks_data.html:21
+msgid "Compare Fork"
+msgstr "Параўнаць форк"
+
+#: kallithea/templates/base/base.html:160
+#: kallithea/templates/bookmarks/bookmarks.html:56
+#: kallithea/templates/bookmarks/bookmarks_data.html:13
+#: kallithea/templates/branches/branches.html:56
+#: kallithea/templates/branches/branches_data.html:13
+#: kallithea/templates/tags/tags.html:56
+#: kallithea/templates/tags/tags_data.html:13
+msgid "Compare"
+msgstr "Параўнаць"
+
+#: kallithea/templates/base/base.html:162
+#: kallithea/templates/base/base.html:250
+#: kallithea/templates/search/search.html:14
+#: kallithea/templates/search/search.html:54
+msgid "Search"
+msgstr "Пошук"
+
+#: kallithea/templates/base/base.html:166
+msgid "Unlock"
+msgstr "Разблакаваць"
+
+#: kallithea/templates/base/base.html:168
+msgid "Lock"
+msgstr "Заблакаваць"
+
+#: kallithea/templates/base/base.html:176
+msgid "Follow"
+msgstr "Назіраць"
+
+#: kallithea/templates/base/base.html:177
+msgid "Unfollow"
+msgstr "Не назіраць"
+
+#: kallithea/templates/base/base.html:180
+#: kallithea/templates/data_table/_dt_elements.html:35
+#: kallithea/templates/data_table/_dt_elements.html:39
+#: kallithea/templates/forks/fork.html:9
+msgid "Fork"
+msgstr "Форк"
+
+#: kallithea/templates/base/base.html:181
+#: kallithea/templates/pullrequests/pullrequest.html:88
+msgid "Create Pull Request"
+msgstr "Стварыць Pull запыт"
+
+#: kallithea/templates/base/base.html:186
+#, python-format
+msgid "Show Pull Requests for %s"
+msgstr "Паказаць pull-запыты для %s"
+
+#: kallithea/templates/base/base.html:224
+msgid "Show recent activity"
+msgstr "Паказаць апошнюю актыўнасць"
+
+#: kallithea/templates/base/base.html:225
+#: kallithea/templates/journal/journal.html:4
+#: kallithea/templates/journal/journal.html:12
+msgid "Journal"
+msgstr "Часопіс"
+
+#: kallithea/templates/base/base.html:230
+#: kallithea/templates/base/base.html:231
+msgid "Public journal"
+msgstr "Агульнадаступны часопіс"
+
+#: kallithea/templates/base/base.html:236
+msgid "Show public gists"
+msgstr "Паказаць публічныя запісы"
+
+#: kallithea/templates/base/base.html:237
+msgid "Gists"
+msgstr "Gist"
+
+#: kallithea/templates/base/base.html:241
+msgid "All Public Gists"
+msgstr "Усе публічныя Gist-запісы"
+
+#: kallithea/templates/base/base.html:243
+msgid "My Public Gists"
+msgstr "Мае публічныя Gist-запісы"
+
+#: kallithea/templates/base/base.html:244
+msgid "My Private Gists"
+msgstr "Мае прыватныя Gist-запісы"
+
+#: kallithea/templates/base/base.html:249
+msgid "Search in repositories"
+msgstr "Пошук па рэпазітарах"
+
+#: kallithea/templates/base/base.html:272
+#: kallithea/templates/base/base.html:273
+#: kallithea/templates/pullrequests/pullrequest_show_my.html:4
+#: kallithea/templates/pullrequests/pullrequest_show_my.html:8
+msgid "My Pull Requests"
+msgstr "Мае Pull-запыты"
+
+#: kallithea/templates/base/base.html:292
+msgid "Not Logged In"
+msgstr "Не аўтарызаваны"
+
+#: kallithea/templates/base/base.html:299
+msgid "Login to Your Account"
+msgstr "Аўтарызавацца"
+
+#: kallithea/templates/base/base.html:322
+msgid "Forgot password ?"
+msgstr "Забыліся пароль?"
+
+#: kallithea/templates/base/base.html:347
+msgid "Log Out"
+msgstr "Выйсце"
+
+#: kallithea/templates/base/base.html:395
+msgid "No matches found"
+msgstr ""
+
+#: kallithea/templates/base/base.html:524
+msgid "Keyboard shortcuts"
+msgstr ""
+
+#: kallithea/templates/base/base.html:533
+msgid "Site-wide shortcuts"
+msgstr ""
+
+#: kallithea/templates/base/default_perms_box.html:14
+msgid "Inherit from defaults"
+msgstr ""
+
+#: kallithea/templates/base/default_perms_box.html:19
+#, python-format
+msgid ""
+"Select to inherit permissions from %s permissions settings, and default IP "
+"address whitelist."
+msgstr ""
+
+#: kallithea/templates/base/default_perms_box.html:28
+msgid "Create repositories"
+msgstr "Стварыць рэпазітары"
+
+#: kallithea/templates/base/default_perms_box.html:33
+msgid "Select this option to allow repository creation for this user"
+msgstr "Опцыя дазваляе карыстачу ствараць рэпазітары"
+
+#: kallithea/templates/base/default_perms_box.html:40
+msgid "Create user groups"
+msgstr "Ствараць групы карыстачоў"
+
+#: kallithea/templates/base/default_perms_box.html:45
+msgid "Select this option to allow user group creation for this user"
+msgstr "Опцыя дазваляе карыстачу ствараць групы карыстачоў"
+
+#: kallithea/templates/base/default_perms_box.html:52
+msgid "Fork repositories"
+msgstr "Ствараць fork ад рэпазітароў"
+
+#: kallithea/templates/base/default_perms_box.html:57
+msgid "Select this option to allow repository forking for this user"
+msgstr ""
+"Абярыце гэту опцыю каб дазволіць дадзенаму карыстачу ствараць fork'і "
+"рэпазітароў"
+
+#: kallithea/templates/base/perms_summary.html:13
+msgid "show"
+msgstr ""
+
+#: kallithea/templates/base/perms_summary.html:22
+msgid "No permissions defined yet"
+msgstr "Прывілеі яшчэ не прызначаны"
+
+#: kallithea/templates/base/perms_summary.html:30
+#: kallithea/templates/base/perms_summary.html:54
+msgid "Permission"
+msgstr "Прывілей"
+
+#: kallithea/templates/base/perms_summary.html:32
+#: kallithea/templates/base/perms_summary.html:56
+msgid "Edit Permission"
+msgstr "Змяніць прывілеі"
+
+#: kallithea/templates/base/perms_summary.html:90
+msgid "No permission defined"
+msgstr ""
+
+#: kallithea/templates/base/root.html:22
+msgid "Add Another Comment"
+msgstr "Дадаць яшчэ адзін каментар"
+
+#: kallithea/templates/base/root.html:23
+#: kallithea/templates/data_table/_dt_elements.html:216
+msgid "Stop following this repository"
+msgstr "Адмяніць назіранне за рэпазітаром"
+
+#: kallithea/templates/base/root.html:24
+msgid "Start following this repository"
+msgstr "Назіраць за рэпазітаром"
+
+#: kallithea/templates/base/root.html:25
+msgid "Group"
+msgstr "Група"
+
+#: kallithea/templates/base/root.html:26
+msgid "members"
+msgstr "удзельнікі"
+
+#: kallithea/templates/base/root.html:27
+msgid "Loading ..."
+msgstr "Загрузка..."
+
+#: kallithea/templates/base/root.html:28
+msgid "loading ..."
+msgstr "загрузка..."
+
+#: kallithea/templates/base/root.html:29
+msgid "Search truncated"
+msgstr "Пошук усечаны"
+
+#: kallithea/templates/base/root.html:30
+msgid "No matching files"
+msgstr "Няма супадзенняў"
+
+#: kallithea/templates/base/root.html:31
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:30
+msgid "Open New Pull Request"
+msgstr "Стварыць новы pull-запыт"
+
+#: kallithea/templates/base/root.html:32
+msgid "Open New Pull Request for Selected Changesets"
+msgstr "Адкрыць новы pull-request для абраных набораў змен"
+
+#: kallithea/templates/base/root.html:33
+msgid "Show Selected Changesets __S &rarr; __E"
+msgstr "Паказаць абраныя наборы змен: __S &rarr; __E"
+
+#: kallithea/templates/base/root.html:34
+msgid "Show Selected Changeset __S"
+msgstr "Паказаць абраны набор змен: __S"
+
+#: kallithea/templates/base/root.html:35
+msgid "Selection Link"
+msgstr "Спасылка выбару"
+
+#: kallithea/templates/base/root.html:36
+#: kallithea/templates/changeset/diff_block.html:8
+msgid "Collapse Diff"
+msgstr "Згарнуць параўнанне"
+
+#: kallithea/templates/base/root.html:37
+msgid "Expand Diff"
+msgstr "Расчыніць параўнанне"
+
+#: kallithea/templates/base/root.html:38
+msgid "Failed to revoke permission"
+msgstr "Не атрымалася адклікаць прывілеі"
+
+#: kallithea/templates/base/root.html:39
+msgid "Confirm to revoke permission for {0}: {1} ?"
+msgstr "Пацвердзіце выдаленне прывілею для {0}: {1} ?"
+
+#: kallithea/templates/base/root.html:43
+msgid "Specify changeset"
+msgstr "Абраць набор змен"
+
+#: kallithea/templates/bookmarks/bookmarks.html:5
+#, python-format
+msgid "%s Bookmarks"
+msgstr "Закладкі %s"
+
+#: kallithea/templates/bookmarks/bookmarks.html:26
+msgid "Compare Bookmarks"
+msgstr ""
+
+#: kallithea/templates/bookmarks/bookmarks.html:53
+#: kallithea/templates/bookmarks/bookmarks_data.html:10
+#: kallithea/templates/branches/branches.html:53
+#: kallithea/templates/branches/branches_data.html:10
+#: kallithea/templates/changelog/changelog_summary_data.html:10
+#: kallithea/templates/pullrequests/pullrequest_data.html:16
+#: kallithea/templates/tags/tags.html:53
+#: kallithea/templates/tags/tags_data.html:10
+msgid "Author"
+msgstr "Аўтар"
+
+#: kallithea/templates/bookmarks/bookmarks.html:54
+#: kallithea/templates/bookmarks/bookmarks_data.html:12
+#: kallithea/templates/branches/branches.html:54
+#: kallithea/templates/branches/branches_data.html:12
+#: kallithea/templates/changelog/changelog_summary_data.html:7
+#: kallithea/templates/pullrequests/pullrequest.html:62
+#: kallithea/templates/pullrequests/pullrequest.html:78
+#: kallithea/templates/tags/tags.html:54
+#: kallithea/templates/tags/tags_data.html:12
+msgid "Revision"
+msgstr "Рэвізія"
+
+#: kallithea/templates/branches/branches.html:5
+#, python-format
+msgid "%s Branches"
+msgstr "Галінкі %s"
+
+#: kallithea/templates/branches/branches.html:26
+msgid "Compare Branches"
+msgstr ""
+
+#: kallithea/templates/changelog/changelog.html:6
+#, python-format
+msgid "%s Changelog"
+msgstr "Логі змен %s"
+
+#: kallithea/templates/changelog/changelog.html:21
+#, python-format
+msgid "showing %d out of %d revision"
+msgid_plural "showing %d out of %d revisions"
+msgstr[0] "Паказана %d з %d рэвізій"
+msgstr[1] "Паказаны %d з %d рэвізій"
+msgstr[2] "Паказаны %d з %d рэвізій"
+
+#: kallithea/templates/changelog/changelog.html:42
+msgid "Show"
+msgstr "Паказаць"
+
+#: kallithea/templates/changelog/changelog.html:52
+msgid "Clear selection"
+msgstr "Ачысціць выбар"
+
+#: kallithea/templates/changelog/changelog.html:55
+msgid "Go to tip of repository"
+msgstr "Перайсці на верхавіну рэпазітара"
+
+#: kallithea/templates/changelog/changelog.html:60
+#: kallithea/templates/forks/forks_data.html:19
+#, python-format
+msgid "Compare fork with %s"
+msgstr "Параўнаць fork з %s"
+
+#: kallithea/templates/changelog/changelog.html:62
+#, python-format
+msgid "Compare fork with parent repo (%s)"
+msgstr "Параўнаць форк з бацькоўскім рэпазітаром (%s)"
+
+#: kallithea/templates/changelog/changelog.html:66
+#: kallithea/templates/files/files.html:29
+msgid "Branch filter:"
+msgstr "Адфільтраваць галінку:"
+
+#: kallithea/templates/changelog/changelog.html:92
+#: kallithea/templates/changelog/changelog_summary_data.html:20
+#, python-format
+msgid ""
+"Changeset status: %s\n"
+"Click to open associated pull request #%s"
+msgstr ""
+"Статут набору змен: %s?\n"
+"Клікніце, каб перайсці да адпаведнага pull-request'у #%s"
+
+#: kallithea/templates/changelog/changelog.html:96
+#: kallithea/templates/compare/compare_cs.html:24
+#, python-format
+msgid "Changeset status: %s"
+msgstr "Статут набору змен: %s"
+
+#: kallithea/templates/changelog/changelog.html:115
+#: kallithea/templates/compare/compare_cs.html:48
+msgid "Expand commit message"
+msgstr ""
+
+#: kallithea/templates/changelog/changelog.html:124
+#: kallithea/templates/compare/compare_cs.html:30
+msgid "Changeset has comments"
+msgstr "Каментары адсутнічаюць"
+
+#: kallithea/templates/changelog/changelog.html:134
+#: kallithea/templates/changelog/changelog_summary_data.html:54
+#: kallithea/templates/changeset/changeset.html:94
+#: kallithea/templates/changeset/changeset_range.html:92
+#, python-format
+msgid "Bookmark %s"
+msgstr "Закладка %s"
+
+#: kallithea/templates/changelog/changelog.html:140
+#: kallithea/templates/changelog/changelog_summary_data.html:60
+#: kallithea/templates/changeset/changeset.html:101
+#: kallithea/templates/changeset/changeset_range.html:98
+#, python-format
+msgid "Tag %s"
+msgstr "Пазнака %s"
+
+#: kallithea/templates/changelog/changelog.html:145
+#: kallithea/templates/changelog/changelog_summary_data.html:65
+#: kallithea/templates/changeset/changeset.html:106
+#: kallithea/templates/changeset/changeset_range.html:102
+#, python-format
+msgid "Branch %s"
+msgstr "Галінка %s"
+
+#: kallithea/templates/changelog/changelog.html:290
+msgid "There are no changes yet"
+msgstr "Змен яшчэ няма"
+
+#: kallithea/templates/changelog/changelog_details.html:4
+#: kallithea/templates/changeset/changeset.html:77
+msgid "Removed"
+msgstr "Выдалена"
+
+#: kallithea/templates/changelog/changelog_details.html:5
+#: kallithea/templates/changeset/changeset.html:78
+msgid "Changed"
+msgstr "Зменена"
+
+#: kallithea/templates/changelog/changelog_details.html:6
+#: kallithea/templates/changeset/changeset.html:79
+#: kallithea/templates/changeset/diff_block.html:80
+msgid "Added"
+msgstr "Дададзена"
+
+#: kallithea/templates/changelog/changelog_details.html:8
+#: kallithea/templates/changelog/changelog_details.html:9
+#: kallithea/templates/changelog/changelog_details.html:10
+#: kallithea/templates/changeset/changeset.html:81
+#: kallithea/templates/changeset/changeset.html:82
+#: kallithea/templates/changeset/changeset.html:83
+#, python-format
+msgid "Affected %s files"
+msgstr "Закранае %s файлаў"
+
+#: kallithea/templates/changelog/changelog_summary_data.html:8
+#: kallithea/templates/files/files_add.html:60
+#: kallithea/templates/files/files_delete.html:39
+#: kallithea/templates/files/files_edit.html:63
+msgid "Commit Message"
+msgstr ""
+
+#: kallithea/templates/changelog/changelog_summary_data.html:9
+#: kallithea/templates/pullrequests/pullrequest_data.html:17
+msgid "Age"
+msgstr "Узрост"
+
+#: kallithea/templates/changelog/changelog_summary_data.html:11
+msgid "Refs"
+msgstr "Спасылкі"
+
+#: kallithea/templates/changelog/changelog_summary_data.html:91
+msgid "Add or upload files directly via Kallithea"
+msgstr "Дадаць ці загрузіць файлы праз Kallithea"
+
+#: kallithea/templates/changelog/changelog_summary_data.html:94
+#: kallithea/templates/files/files_add.html:21
+#: kallithea/templates/files/files_ypjax.html:9
+msgid "Add New File"
+msgstr ""
+
+#: kallithea/templates/changelog/changelog_summary_data.html:100
+msgid "Push new repo"
+msgstr "Адправіць новы рэпазітар"
+
+#: kallithea/templates/changelog/changelog_summary_data.html:108
+msgid "Existing repository?"
+msgstr "Існы рэпазітар?"
+
+#: kallithea/templates/changeset/changeset.html:8
+#, python-format
+msgid "%s Changeset"
+msgstr "%s Змены"
+
+#: kallithea/templates/changeset/changeset.html:36
+msgid "parent rev."
+msgstr ""
+
+#: kallithea/templates/changeset/changeset.html:42
+msgid "child rev."
+msgstr ""
+
+#: kallithea/templates/changeset/changeset.html:50
+#: kallithea/templates/changeset/changeset_file_comment.html:43
+#: kallithea/templates/changeset/changeset_range.html:48
+msgid "Changeset status"
+msgstr "Статут змен"
+
+#: kallithea/templates/changeset/changeset.html:54
+#: kallithea/templates/changeset/diff_block.html:27
+#: kallithea/templates/files/diff_2way.html:49
+msgid "Raw diff"
+msgstr "Адлюстраваць у фармаце diff"
+
+#: kallithea/templates/changeset/changeset.html:57
+msgid "Patch diff"
+msgstr "Ужыць рознаснае выпраўленне (Patch diff)"
+
+#: kallithea/templates/changeset/changeset.html:60
+#: kallithea/templates/changeset/diff_block.html:30
+#: kallithea/templates/files/diff_2way.html:52
+msgid "Download diff"
+msgstr "Запампаваць diff"
+
+#: kallithea/templates/changeset/changeset.html:89
+#: kallithea/templates/changeset/changeset_range.html:88
+msgid "merge"
+msgstr "звесці"
+
+#: kallithea/templates/changeset/changeset.html:123
+msgid "Grafted from:"
+msgstr "Перанесена з:"
+
+#: kallithea/templates/changeset/changeset.html:129
+msgid "Transplanted from:"
+msgstr ""
+
+#: kallithea/templates/changeset/changeset.html:137
+#: kallithea/templates/compare/compare_diff.html:54
+#: kallithea/templates/pullrequests/pullrequest_show.html:307
+#, python-format
+msgid "%s file changed"
+msgid_plural "%s files changed"
+msgstr[0] "%s файл зменены"
+msgstr[1] "%s файлаў зменена"
+msgstr[2] "%s файла зменена"
+
+#: kallithea/templates/changeset/changeset.html:139
+#: kallithea/templates/compare/compare_diff.html:56
+#: kallithea/templates/pullrequests/pullrequest_show.html:309
+#, python-format
+msgid "%s file changed with %s insertions and %s deletions"
+msgid_plural "%s files changed with %s insertions and %s deletions"
+msgstr[0] "%s файл зменены: %s даданне, %s выдаленне"
+msgstr[1] "%s файла зменена: %s даданні, %s выдаленні"
+msgstr[2] "%s файлаў зменена: %s даданняў, %s выдаленняў"
+
+#: kallithea/templates/changeset/changeset.html:153
+#: kallithea/templates/changeset/changeset.html:166
+#: kallithea/templates/pullrequests/pullrequest_show.html:328
+#: kallithea/templates/pullrequests/pullrequest_show.html:351
+msgid "Show full diff anyway"
+msgstr "Паказаць поўны diff"
+
+#: kallithea/templates/changeset/changeset.html:224
+#: kallithea/templates/changeset/changeset.html:261
+msgid "no revisions"
+msgstr ""
+
+#: kallithea/templates/changeset/changeset_file_comment.html:24
+msgid "Status change from pull request"
+msgstr "Змена статуту"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:25
+#: kallithea/templates/changeset/changeset_file_comment.html:28
+msgid "No title"
+msgstr "Няма загалоўка"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:27
+msgid "Comment from pull request"
+msgstr "Каментар у pull-запыце"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:32
+msgid "Status change on changeset"
+msgstr ""
+
+#: kallithea/templates/changeset/changeset_file_comment.html:34
+msgid "Comment on changeset"
+msgstr ""
+
+#: kallithea/templates/changeset/changeset_file_comment.html:50
+msgid "Delete comment?"
+msgstr "Выдаліць каментар?"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:67
+msgid "Commenting on line {1}."
+msgstr "Каментар да радка {1}."
+
+#: kallithea/templates/changeset/changeset_file_comment.html:68
+#: kallithea/templates/changeset/changeset_file_comment.html:163
+#, python-format
+msgid "Comments parsed using %s syntax with %s support."
+msgstr ""
+"Парсінг каментароў выкананы з выкарыстаннем сінтаксісу %s з падтрымкай %s."
+
+#: kallithea/templates/changeset/changeset_file_comment.html:70
+#: kallithea/templates/changeset/changeset_file_comment.html:165
+msgid "Use @username inside this text to notify another user"
+msgstr ""
+"Выкарыстоўвайце @імя_карыстача ў тэксце, каб адправіць абвестку пэўнаму "
+"карыстачу"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:80
+#: kallithea/templates/changeset/changeset_file_comment.html:199
+msgid "Comment preview"
+msgstr "Папярэдні прагляд каментара"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:85
+msgid "Submitting ..."
+msgstr "Ужыванне..."
+
+#: kallithea/templates/changeset/changeset_file_comment.html:88
+#: kallithea/templates/changeset/changeset_file_comment.html:205
+msgid "Comment"
+msgstr "Каментаваць"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:90
+#: kallithea/templates/changeset/changeset_file_comment.html:206
+msgid "Preview"
+msgstr "Прадпрагляд"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:98
+msgid "You need to be logged in to comment."
+msgstr "Вам неабходна аўтарызавацца, каб пакідаць каментары."
+
+#: kallithea/templates/changeset/changeset_file_comment.html:98
+msgid "Login now"
+msgstr "Аўтарызавацца цяпер"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:102
+msgid "Hide"
+msgstr "Схаваць"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:114
+#, python-format
+msgid "%d comment"
+msgid_plural "%d comments"
+msgstr[0] "%d каментар"
+msgstr[1] "%d каментара"
+msgstr[2] "%d каментароў"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:115
+#, python-format
+msgid "%d inline"
+msgid_plural "%d inline"
+msgstr[0] "%d да радка"
+msgstr[1] "%d да радкоў"
+msgstr[2] "%d да радкоў"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:116
+#, python-format
+msgid "%d general"
+msgid_plural "%d general"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: kallithea/templates/changeset/changeset_file_comment.html:172
+msgid "Vote for pull request status"
+msgstr ""
+
+#: kallithea/templates/changeset/changeset_file_comment.html:174
+msgid "Set changeset status"
+msgstr "Змяніць статут рэвізіі"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:178
+msgid "No change"
+msgstr "Без змен"
+
+#: kallithea/templates/changeset/changeset_file_comment.html:191
+msgid "Close"
+msgstr "Зачыніць"
+
+#: kallithea/templates/changeset/changeset_range.html:5
+#, python-format
+msgid "%s Changesets"
+msgstr "%s Змены"
+
+#: kallithea/templates/changeset/changeset_range.html:56
+msgid "Files affected"
+msgstr "Закранутыя файлы"
+
+#: kallithea/templates/changeset/diff_block.html:21
+#: kallithea/templates/files/diff_2way.html:43
+msgid "Show full diff for this file"
+msgstr "Паказаць поўны diff для гэтага файла"
+
+#: kallithea/templates/changeset/diff_block.html:24
+#: kallithea/templates/changeset/diff_block.html:99
+#: kallithea/templates/files/diff_2way.html:46
+msgid "Show full side-by-side diff for this file"
+msgstr "Паказаць поўны diff для гэтага файла"
+
+#: kallithea/templates/changeset/diff_block.html:38
+msgid "Show inline comments"
+msgstr "Паказаць каментары ў радках"
+
+#: kallithea/templates/changeset/diff_block.html:87
+msgid "Deleted"
+msgstr "Выдалены"
+
+#: kallithea/templates/changeset/diff_block.html:90
+msgid "Renamed"
+msgstr "Пераназваны"
+
+#: kallithea/templates/compare/compare_cs.html:4
+msgid "No changesets"
+msgstr "Няма змен"
+
+#: kallithea/templates/compare/compare_cs.html:8
+msgid "Ancestor"
+msgstr "Продак"
+
+#: kallithea/templates/compare/compare_cs.html:61
+msgid "Show merge diff"
+msgstr "Паказаць merge diff"
+
+#: kallithea/templates/compare/compare_cs.html:71
+#: kallithea/templates/pullrequests/pullrequest_show.html:299
+msgid "Common ancestor"
+msgstr "Агульны продак"
+
+#: kallithea/templates/compare/compare_cs.html:75
+msgid "No common ancestor found - repositories are unrelated"
+msgstr ""
+
+#: kallithea/templates/compare/compare_cs.html:83
+msgid "is"
+msgstr "адстае на"
+
+#: kallithea/templates/compare/compare_cs.html:84
+#, python-format
+msgid "%s changesets"
+msgstr "%s змен"
+
+#: kallithea/templates/compare/compare_cs.html:85
+msgid "behind"
+msgstr "ад"
+
+#: kallithea/templates/compare/compare_diff.html:6
+#: kallithea/templates/compare/compare_diff.html:8
+#, python-format
+msgid "%s Compare"
+msgstr "%s Параўнаць"
+
+#: kallithea/templates/compare/compare_diff.html:13
+#: kallithea/templates/compare/compare_diff.html:35
+msgid "Compare Revisions"
+msgstr ""
+
+#: kallithea/templates/compare/compare_diff.html:33
+msgid "Swap"
+msgstr ""
+
+#: kallithea/templates/compare/compare_diff.html:42
+msgid "Compare revisions, branches, bookmarks, or tags."
+msgstr ""
+
+#: kallithea/templates/compare/compare_diff.html:47
+#: kallithea/templates/pullrequests/pullrequest_show.html:294
+#, python-format
+msgid "Showing %s commit"
+msgid_plural "Showing %s commits"
+msgstr[0] "Паказаць %s commit"
+msgstr[1] "Паказаць %s commit'а"
+msgstr[2] "Паказаць %s commit'аў"
+
+#: kallithea/templates/compare/compare_diff.html:65
+#: kallithea/templates/pullrequests/pullrequest_show.html:315
+msgid "No files"
+msgstr "Няма файлаў"
+
+#: kallithea/templates/compare/compare_diff.html:78
+#: kallithea/templates/compare/compare_diff.html:89
+msgid "Show full diff"
+msgstr "Паказаць поўны diff"
+
+#: kallithea/templates/data_table/_dt_elements.html:67
+msgid "Mercurial repository"
+msgstr "Рэпазітар Mercurial"
+
+#: kallithea/templates/data_table/_dt_elements.html:69
+msgid "Git repository"
+msgstr "Git рэпазітар"
+
+#: kallithea/templates/data_table/_dt_elements.html:76
+msgid "Public repository"
+msgstr "Публічны рэпазітар"
+
+#: kallithea/templates/data_table/_dt_elements.html:86
+msgid "Repository creation in progress..."
+msgstr ""
+
+#: kallithea/templates/data_table/_dt_elements.html:100
+msgid "No changesets yet"
+msgstr "Змен яшчэ не было"
+
+#: kallithea/templates/data_table/_dt_elements.html:107
+#: kallithea/templates/data_table/_dt_elements.html:109
+#, python-format
+msgid "Subscribe to %s rss feed"
+msgstr "Падпісацца на стужку RSS %s"
+
+#: kallithea/templates/data_table/_dt_elements.html:115
+#: kallithea/templates/data_table/_dt_elements.html:117
+#, python-format
+msgid "Subscribe to %s atom feed"
+msgstr "Падпісацца на стужку Atom %s"
+
+#: kallithea/templates/data_table/_dt_elements.html:141
+msgid "Creating"
+msgstr ""
+
+#: kallithea/templates/email_templates/changeset_comment.html:5
+#, python-format
+msgid "Comment from %s on %s changeset %s mentioned you"
+msgstr ""
+
+#: kallithea/templates/email_templates/changeset_comment.html:7
+#, python-format
+msgid "Comment from %s on %s changeset %s"
+msgstr "Каментар ад %s да набору змен %s %s"
+
+#: kallithea/templates/email_templates/changeset_comment.html:12
+msgid "The changeset status was changed to"
+msgstr "Стан набору змен зменена на"
+
+#: kallithea/templates/email_templates/main.html:6
+msgid "This is an automatic notification. Don't reply to this mail."
+msgstr ""
+
+#: kallithea/templates/email_templates/password_reset.html:4
+#, python-format
+msgid "Hello %s"
+msgstr "Дабрыдзень, %s"
+
+#: kallithea/templates/email_templates/password_reset.html:6
+msgid "We received a request to create a new password for your account."
+msgstr "Мы адправілі запыт на стварэнне новага пароля для вашага акаўнта."
+
+#: kallithea/templates/email_templates/password_reset.html:7
+msgid "You can generate it by clicking following URL"
+msgstr "Вы можаце нанова згенераваць яго, пяройдучы па наступнай спасылцы"
+
+#: kallithea/templates/email_templates/password_reset.html:10
+msgid "Please ignore this email if you did not request a new password ."
+msgstr ""
+"Калі ласка, праігнаруйце дадзенае паведамленне, калі вы не запытвалі новы "
+"пароль."
+
+#: kallithea/templates/email_templates/pull_request.html:5
+#, python-format
+msgid "%s mentioned you on %s pull request \"%s\""
+msgstr "%s згадаў Вас у каментары да pull-запыту %s \"%s\""
+
+#: kallithea/templates/email_templates/pull_request.html:7
+#, python-format
+msgid "%s requested your review of %s pull request \"%s\""
+msgstr "%s запытаў рэцэнзаванне pull-запыту %s \"%s\""
+
+#: kallithea/templates/email_templates/pull_request_comment.html:4
+#, python-format
+msgid "Comment from %s on %s pull request \"%s\""
+msgstr ""
+
+#: kallithea/templates/email_templates/pull_request_comment.html:9
+msgid "The comment closed the pull request with status"
+msgstr "Каментар зачыніў pull-запыт са статутам"
+
+#: kallithea/templates/email_templates/pull_request_comment.html:11
+msgid "The comment was made with status"
+msgstr "Каментар пакінуты са статутам"
+
+#: kallithea/templates/email_templates/registration.html:6
+msgid "View this user here"
+msgstr "Падрабязней пра карыстача"
+
+#: kallithea/templates/files/diff_2way.html:15
+#, python-format
+msgid "%s File side-by-side diff"
+msgstr ""
+
+#: kallithea/templates/files/diff_2way.html:19
+#: kallithea/templates/files/file_diff.html:8
+msgid "File diff"
+msgstr "Параўнанне файлаў"
+
+#: kallithea/templates/files/file_diff.html:4
+#, python-format
+msgid "%s File Diff"
+msgstr "Параўнанне файла %s"
+
+#: kallithea/templates/files/files.html:4
+#: kallithea/templates/files/files.html:80
+#, python-format
+msgid "%s Files"
+msgstr "%s Файлы"
+
+#: kallithea/templates/files/files_add.html:4
+#, python-format
+msgid "%s Files Add"
+msgstr "%s Файлаў дададзена"
+
+#: kallithea/templates/files/files_add.html:40
+#: kallithea/templates/files/files_edit.html:38
+#: kallithea/templates/files/files_ypjax.html:3
+msgid "Location"
+msgstr "Размяшчэнне"
+
+#: kallithea/templates/files/files_add.html:42
+msgid "Enter filename..."
+msgstr "Увядзіце імя файла..."
+
+#: kallithea/templates/files/files_add.html:44
+#: kallithea/templates/files/files_add.html:48
+msgid "or"
+msgstr "ці"
+
+#: kallithea/templates/files/files_add.html:44
+msgid "Upload File"
+msgstr "Адаслаць файл"
+
+#: kallithea/templates/files/files_add.html:48
+msgid "Create New File"
+msgstr "Стварыць новы файл"
+
+#: kallithea/templates/files/files_add.html:53
+msgid "New file mode"
+msgstr "Рэжым новага файла"
+
+#: kallithea/templates/files/files_add.html:64
+#: kallithea/templates/files/files_delete.html:43
+#: kallithea/templates/files/files_edit.html:67
+msgid "Commit Changes"
+msgstr "Ужыць змены"
+
+#: kallithea/templates/files/files_browser.html:32
+msgid "revision"
+msgstr ""
+
+#: kallithea/templates/files/files_browser.html:33
+msgid "Previous revision"
+msgstr "Папярэдняя рэвізія"
+
+#: kallithea/templates/files/files_browser.html:35
+msgid "Next revision"
+msgstr "Наступная рэвізія"
+
+#: kallithea/templates/files/files_browser.html:41
+msgid "Follow current branch"
+msgstr "Адсочваць дадзеную галінку"
+
+#: kallithea/templates/files/files_browser.html:44
+msgid "Search File List"
+msgstr ""
+
+#: kallithea/templates/files/files_browser.html:48
+msgid "Loading file list..."
+msgstr "Загружаецца спіс файлаў..."
+
+#: kallithea/templates/files/files_browser.html:61
+msgid "Size"
+msgstr "Памер"
+
+#: kallithea/templates/files/files_browser.html:62
+msgid "Mimetype"
+msgstr "Тып файла"
+
+#: kallithea/templates/files/files_browser.html:63
+msgid "Last Revision"
+msgstr "Апошняя версія"
+
+#: kallithea/templates/files/files_browser.html:64
+msgid "Last Modified"
+msgstr "Апошняя змена"
+
+#: kallithea/templates/files/files_browser.html:65
+msgid "Last Committer"
+msgstr "Аўтар апошняй рэвізіі"
+
+#: kallithea/templates/files/files_delete.html:4
+#, python-format
+msgid "%s Files Delete"
+msgstr ""
+
+#: kallithea/templates/files/files_delete.html:12
+#: kallithea/templates/files/files_delete.html:31
+msgid "Delete file"
+msgstr "Выдаліць файл"
+
+#: kallithea/templates/files/files_edit.html:4
+#, python-format
+msgid "%s File Edit"
+msgstr ""
+
+#: kallithea/templates/files/files_edit.html:21
+msgid "Edit file"
+msgstr "Рэдагаваць файл"
+
+#: kallithea/templates/files/files_edit.html:48
+#: kallithea/templates/files/files_source.html:32
+msgid "Show Annotation"
+msgstr ""
+
+#: kallithea/templates/files/files_edit.html:50
+#: kallithea/templates/files/files_source.html:35
+msgid "Download as Raw"
+msgstr ""
+
+#: kallithea/templates/files/files_edit.html:53
+msgid "Source"
+msgstr "Зыходны код"
+
+#: kallithea/templates/files/files_edit.html:58
+msgid "Editing file"
+msgstr "Рэдагаванне файла"
+
+#: kallithea/templates/files/files_history_box.html:2
+#, python-format
+msgid "%s author"
+msgid_plural "%s authors"
+msgstr[0] "%s аўтар"
+msgstr[1] "%s аўтараў"
+msgstr[2] "%s аўтара"
+
+#: kallithea/templates/files/files_source.html:7
+msgid "Diff to Revision"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:8
+msgid "Show at Revision"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:10
+msgid "Show Full History"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:11
+msgid "Show Authors"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:30
+msgid "Show Source"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:38
+#, python-format
+msgid "Edit on Branch:%s"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:41
+msgid "Editing binary files not allowed"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:44
+msgid "Editing files allowed only when on branch head revision"
+msgstr "Рэдагаванне файлаў дазволена толькі ў HEAD-рэвізіі дадзенай галінкі"
+
+#: kallithea/templates/files/files_source.html:45
+msgid "Deleting files allowed only when on branch head revision"
+msgstr ""
+
+#: kallithea/templates/files/files_source.html:63
+#, python-format
+msgid "Binary file (%s)"
+msgstr "Бінарны файл (%s)"
+
+#: kallithea/templates/files/files_source.html:73
+msgid "File is too big to display"
+msgstr "Файл занадта вялікай для адлюстравання"
+
+#: kallithea/templates/files/files_ypjax.html:5
+msgid "annotation"
+msgstr "анатацыя"
+
+#: kallithea/templates/files/files_ypjax.html:23
+msgid "Go Back"
+msgstr ""
+
+#: kallithea/templates/files/files_ypjax.html:24
+msgid "No files at given path"
+msgstr "Па зададзеным шляху файлы адсутнічаюць"
+
+#: kallithea/templates/followers/followers.html:5
+#, python-format
+msgid "%s Followers"
+msgstr "%s Назіральнікі"
+
+#: kallithea/templates/followers/followers.html:9
+#: kallithea/templates/summary/summary.html:145
+#: kallithea/templates/summary/summary.html:146
+msgid "Followers"
+msgstr "Назіральнікі"
+
+#: kallithea/templates/followers/followers_data.html:12
+msgid "Started following -"
+msgstr "Назіраць за рэпазітаром"
+
+#: kallithea/templates/forks/fork.html:5
+#, python-format
+msgid "Fork repository %s"
+msgstr ""
+
+#: kallithea/templates/forks/fork.html:27
+msgid "Fork name"
+msgstr "Імя форка"
+
+#: kallithea/templates/forks/fork.html:62
+msgid "Default revision for files page, downloads, whoosh, and readme."
+msgstr ""
+"Рэвізія па змаўчанні, з якой будзе вырабляцца выгрузка файлаў пры спампоўцы."
+
+#: kallithea/templates/forks/fork.html:68
+msgid "Private"
+msgstr "Прыватны"
+
+#: kallithea/templates/forks/fork.html:77
+msgid "Copy permissions"
+msgstr "Скапіяваць прывілеі"
+
+#: kallithea/templates/forks/fork.html:81
+msgid "Copy permissions from forked repository"
+msgstr "Скапіяваць прывілеі з форкнутага рэпазітара"
+
+#: kallithea/templates/forks/fork.html:87
+msgid "Update after clone"
+msgstr "Абнаўляць пасля кланавання"
+
+#: kallithea/templates/forks/fork.html:91
+msgid "Checkout source after making a clone"
+msgstr "Спампоўваць зыходнікі пасля стварэння клона"
+
+#: kallithea/templates/forks/fork.html:96
+msgid "Fork this Repository"
+msgstr ""
+
+#: kallithea/templates/forks/forks.html:5
+#, python-format
+msgid "%s Forks"
+msgstr "Форкі %s"
+
+#: kallithea/templates/forks/forks.html:9
+#: kallithea/templates/summary/summary.html:151
+#: kallithea/templates/summary/summary.html:152
+msgid "Forks"
+msgstr "Адгалінаванні"
+
+#: kallithea/templates/forks/forks_data.html:17
+msgid "Forked"
+msgstr "Форкнута"
+
+#: kallithea/templates/forks/forks_data.html:43
+msgid "There are no forks yet"
+msgstr "Форкі яшчэ не створаны"
+
+#: kallithea/templates/journal/journal.html:21
+msgid "ATOM journal feed"
+msgstr "Стужка часопіса ATOM"
+
+#: kallithea/templates/journal/journal.html:22
+msgid "RSS journal feed"
+msgstr "Стужка часопіса RSS"
+
+#: kallithea/templates/journal/journal.html:56
+msgid "My Repos"
+msgstr "Мае рэпазітары"
+
+#: kallithea/templates/journal/journal_data.html:61
+msgid "No entries yet"
+msgstr "Запісы адсутнічаюць"
+
+#: kallithea/templates/journal/public_journal.html:4
+#: kallithea/templates/journal/public_journal.html:21
+msgid "Public Journal"
+msgstr "Публічны часопіс"
+
+#: kallithea/templates/journal/public_journal.html:13
+msgid "ATOM public journal feed"
+msgstr "Агульная стужка часопіса ATOM"
+
+#: kallithea/templates/journal/public_journal.html:14
+msgid "RSS public journal feed"
+msgstr "Агульная стужка часопіса RSS"
+
+#: kallithea/templates/pullrequests/pullrequest.html:4
+#: kallithea/templates/pullrequests/pullrequest.html:8
+msgid "New Pull Request"
+msgstr "Новы pull-запыт"
+
+#: kallithea/templates/pullrequests/pullrequest.html:31
+#: kallithea/templates/pullrequests/pullrequest_data.html:15
+#: kallithea/templates/pullrequests/pullrequest_show.html:29
+#: kallithea/templates/pullrequests/pullrequest_show.html:54
+msgid "Title"
+msgstr "Загаловак"
+
+#: kallithea/templates/pullrequests/pullrequest.html:34
+msgid "Summarize the changes - or leave empty"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest.html:43
+#: kallithea/templates/pullrequests/pullrequest_show.html:66
+msgid "Write a short description on this pull request"
+msgstr "Напісаць кароткае пісанне па гэтым запыце"
+
+#: kallithea/templates/pullrequests/pullrequest.html:49
+msgid "Changeset flow"
+msgstr "Струмень змен"
+
+#: kallithea/templates/pullrequests/pullrequest.html:56
+msgid "Origin repository"
+msgstr "Першапачатковы рэпазітар"
+
+#: kallithea/templates/pullrequests/pullrequest.html:72
+msgid "Destination repository"
+msgstr "Рэпазітар прызначэння"
+
+#: kallithea/templates/pullrequests/pullrequest.html:97
+#: kallithea/templates/pullrequests/pullrequest_show.html:210
+msgid "Pull Request Reviewers"
+msgstr "Рэцэнзенты pull-запытаў"
+
+#: kallithea/templates/pullrequests/pullrequest.html:107
+#: kallithea/templates/pullrequests/pullrequest_show.html:239
+msgid "Type name of reviewer to add"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:6
+msgid "No entries"
+msgstr "Запісы отсуствуют"
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:18
+msgid "From"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:19
+msgid "To"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:27
+#, python-format
+msgid "Latest vote: %s"
+msgstr "Апошняя адзнака: %s"
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:29
+msgid "Nobody voted"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:34
+#, python-format
+msgid "You voted: %s"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:36
+msgid "You didn't vote"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:45
+msgid "Delete Pull Request"
+msgstr "Выдаліць pull-запыт"
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:46
+msgid "Confirm to delete this pull request"
+msgstr "Пацвердзіце выдаленне гэтага pull-request'а"
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:54
+msgid "(no title)"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_data.html:56
+#: kallithea/templates/pullrequests/pullrequest_show.html:31
+#: kallithea/templates/pullrequests/pullrequest_show.html:83
+msgid "Closed"
+msgstr "Зачынена"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:6
+#, python-format
+msgid "%s Pull Request #%s"
+msgstr "%s Pull-запыт #%s"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:10
+#, python-format
+msgid "Pull request #%s from %s#%s"
+msgstr "Pull-запыты №%s ад %s#%s"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:57
+msgid "Summarize the changes"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:74
+msgid "Reviewer voting result"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:80
+#: kallithea/templates/pullrequests/pullrequest_show.html:81
+msgid "Pull request status calculated from votes"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:94
+msgid "Still not reviewed by"
+msgstr "Яшчэ не разгледжаны"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:98
+#, python-format
+msgid "%d reviewer"
+msgid_plural "%d reviewers"
+msgstr[0] "%d рэцэнзент"
+msgstr[1] "%d рэцэнзента"
+msgstr[2] "%d рэцэнзентаў"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:100
+msgid "Pull request was reviewed by all reviewers"
+msgstr "Запыт на занясенне змен быў разгледжаны ўсімі рэцэнзентамі"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:102
+msgid "There are no reviewers"
+msgstr "Няма рэцэнзентаў"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:108
+msgid "Origin"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:114
+msgid "on"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:121
+msgid "Target"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:132
+msgid "Pull changes"
+msgstr "Прыняць змены"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:155
+msgid "Created by"
+msgstr "Створана"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:170
+msgid "Update"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:188
+msgid "Current revision - no change"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:224
+msgid "owner"
+msgstr "уладальнік"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:224
+msgid "reviewer"
+msgstr "рэцэнзент"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:227
+msgid "Remove reviewer"
+msgstr "Выдаліць рэцэнзента"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:247
+msgid "Potential Reviewers"
+msgstr "Патэнцыйныя рэцэнзенты"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:250
+msgid "Click to add the repository owner as reviewer:"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:273
+msgid "Save Changes"
+msgstr "Захаваць змены"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:274
+msgid "Save as New Pull Request"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:275
+msgid "Cancel Changes"
+msgstr "Адмяніць змены"
+
+#: kallithea/templates/pullrequests/pullrequest_show.html:285
+msgid "Pull Request Content"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:4
+#, python-format
+msgid "%s Pull Requests"
+msgstr "%s Запыты на занясенне змен"
+
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:9
+#, python-format
+msgid "Pull Requests from %s'"
+msgstr "Pull-запыты ад %s"
+
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:11
+#, python-format
+msgid "Pull Requests to '%s'"
+msgstr "Pull-запыты для %s"
+
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:35
+#, python-format
+msgid "Show Pull Requests to %s"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:37
+#, python-format
+msgid "Show Pull Requests from '%s'"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:47
+#: kallithea/templates/pullrequests/pullrequest_show_my.html:26
+msgid "Hide closed pull requests (only show open pull requests)"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show_all.html:49
+#: kallithea/templates/pullrequests/pullrequest_show_my.html:28
+msgid "Show closed pull requests (in addition to open pull requests)"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show_my_data.html:3
+msgid "Pull Requests Created by Me"
+msgstr ""
+
+#: kallithea/templates/pullrequests/pullrequest_show_my_data.html:6
+msgid "Pull Requests I Participate In"
+msgstr ""
+
+#: kallithea/templates/search/search.html:6
+#, python-format
+msgid "%s Search"
+msgstr ""
+
+#: kallithea/templates/search/search.html:8
+#: kallithea/templates/search/search.html:16
+msgid "Search in All Repositories"
+msgstr "Пошук па ўсіх рэпазітарах"
+
+#: kallithea/templates/search/search.html:50
+msgid "Search term"
+msgstr "Фраза для пошуку"
+
+#: kallithea/templates/search/search.html:62
+msgid "Search in"
+msgstr "Крытэр пошуку"
+
+#: kallithea/templates/search/search.html:65
+msgid "File contents"
+msgstr "Змесціва файлаў"
+
+#: kallithea/templates/search/search.html:66
+msgid "Commit messages"
+msgstr "Паведамленні камітаў"
+
+#: kallithea/templates/search/search.html:67
+msgid "File names"
+msgstr "Імя файла"
+
+#: kallithea/templates/search/search_commit.html:35
+#: kallithea/templates/search/search_content.html:21
+#: kallithea/templates/search/search_path.html:15
+msgid "Permission denied"
+msgstr "Недастаткова мае рацыю"
+
+#: kallithea/templates/summary/statistics.html:4
+#, python-format
+msgid "%s Statistics"
+msgstr ""
+
+#: kallithea/templates/summary/statistics.html:16
+#: kallithea/templates/summary/summary.html:39
+#, python-format
+msgid "%s ATOM feed"
+msgstr "ATOM стужка рэпазітара %s"
+
+#: kallithea/templates/summary/statistics.html:17
+#: kallithea/templates/summary/summary.html:40
+#, python-format
+msgid "%s RSS feed"
+msgstr "RSS стужка рэпазітара %s"
+
+#: kallithea/templates/summary/statistics.html:36
+#: kallithea/templates/summary/summary.html:103
+#: kallithea/templates/summary/summary.html:119
+msgid "Enable"
+msgstr "Уключана"
+
+#: kallithea/templates/summary/statistics.html:39
+msgid "Stats gathered: "
+msgstr "Атрыманая статыстыка: "
+
+#: kallithea/templates/summary/statistics.html:88
+#: kallithea/templates/summary/summary.html:352
+msgid "files"
+msgstr "файлы"
+
+#: kallithea/templates/summary/statistics.html:112
+#: kallithea/templates/summary/summary.html:376
+msgid "Show more"
+msgstr "Паказаць яшчэ"
+
+#: kallithea/templates/summary/statistics.html:389
+msgid "commits"
+msgstr "commit'ы"
+
+#: kallithea/templates/summary/statistics.html:390
+msgid "files added"
+msgstr "файлы дададзены"
+
+#: kallithea/templates/summary/statistics.html:391
+msgid "files changed"
+msgstr "файлы зменены"
+
+#: kallithea/templates/summary/statistics.html:392
+msgid "files removed"
+msgstr "файлы выдалены"
+
+#: kallithea/templates/summary/statistics.html:394
+msgid "commit"
+msgstr "commit"
+
+#: kallithea/templates/summary/statistics.html:395
+msgid "file added"
+msgstr "файл выдалены"
+
+#: kallithea/templates/summary/statistics.html:396
+msgid "file changed"
+msgstr "файл зменены"
+
+#: kallithea/templates/summary/statistics.html:397
+msgid "file removed"
+msgstr "файл выдалены"
+
+#: kallithea/templates/summary/summary.html:4
+#, python-format
+msgid "%s Summary"
+msgstr "%s агульныя звесткі"
+
+#: kallithea/templates/summary/summary.html:13
+#, python-format
+msgid "Repository locked by %s"
+msgstr "Рэпазітар заблакаваны %s"
+
+#: kallithea/templates/summary/summary.html:15
+msgid "Repository unlocked"
+msgstr "Рэпазітар разблакаваны"
+
+#: kallithea/templates/summary/summary.html:22
+msgid "Fork of"
+msgstr "Форк ад"
+
+#: kallithea/templates/summary/summary.html:77
+msgid "Show by Name"
+msgstr "Паказаць па імі"
+
+#: kallithea/templates/summary/summary.html:78
+msgid "Show by ID"
+msgstr "Паказаць па ID"
+
+#: kallithea/templates/summary/summary.html:95
+msgid "Trending files"
+msgstr "Папулярныя файлы"
+
+#: kallithea/templates/summary/summary.html:111
+msgid "Download"
+msgstr "Запампаваць"
+
+#: kallithea/templates/summary/summary.html:115
+msgid "There are no downloads yet"
+msgstr "Спамповак яшчэ няма"
+
+#: kallithea/templates/summary/summary.html:117
+msgid "Downloads are disabled for this repository"
+msgstr "Спампоўка адключана ў гэтым рэпазітары"
+
+#: kallithea/templates/summary/summary.html:123
+msgid "Download as zip"
+msgstr "Запампаваць у zip"
+
+#: kallithea/templates/summary/summary.html:128
+msgid "Check this to download archive with subrepos"
+msgstr "Адзначце для спампоўкі архіва з даччынымі рэпазітарамі"
+
+#: kallithea/templates/summary/summary.html:128
+msgid "with subrepos"
+msgstr "з даччынымі рэпазітарамі"
+
+#: kallithea/templates/summary/summary.html:159
+msgid "Repository Size"
+msgstr "Памер рэпазітара"
+
+#: kallithea/templates/summary/summary.html:166
+#: kallithea/templates/summary/summary.html:168
+msgid "Feed"
+msgstr "Стужка навін"
+
+#: kallithea/templates/summary/summary.html:189
+msgid "Latest Changes"
+msgstr "Апошнія змены"
+
+#: kallithea/templates/summary/summary.html:191
+msgid "Quick Start"
+msgstr "Хуткі старт"
+
+#: kallithea/templates/summary/summary.html:205
+#, python-format
+msgid "Readme file from revision %s:%s"
+msgstr ""
+
+#: kallithea/templates/summary/summary.html:296
+#, python-format
+msgid "Download %s as %s"
+msgstr "Запампаваць %s як %s"
+
+#: kallithea/templates/tags/tags.html:5
+#, python-format
+msgid "%s Tags"
+msgstr "%s Пазнак"
+
+#: kallithea/templates/tags/tags.html:26
+msgid "Compare Tags"
+msgstr "Параўнаць тэгі"
--- a/kallithea/i18n/cs/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/cs/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -998,7 +998,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -1006,7 +1006,7 @@
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -2005,7 +2005,7 @@
 msgstr ""
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr ""
 
 #: kallithea/model/validators.py:818
@@ -3070,7 +3070,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr ""
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/de/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/de/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -8,8 +8,8 @@
 "Project-Id-Version: Kallithea\n"
 "Report-Msgid-Bugs-To: translations@kallithea-scm.org\n"
 "POT-Creation-Date: 2015-04-01 03:17+0200\n"
-"PO-Revision-Date: 2015-04-01 12:15+0200\n"
-"Last-Translator: Peter Vitt <petervitt@web.de>\n"
+"PO-Revision-Date: 2015-05-13 15:13+0200\n"
+"Last-Translator: Peter Vitt <peter.vitt2@uni-siegen.de>\n"
 "Language-Team: German "
 "<https://hosted.weblate.org/projects/kallithea/kallithea/de/>\n"
 "Language: de\n"
@@ -75,6 +75,8 @@
 #: kallithea/controllers/compare.py:255
 msgid "Cannot compare repositories without using common ancestor"
 msgstr ""
+"Ohne einen gemeinsamen Vorfahren ist ein Vergleich der Repositories nicht "
+"möglich"
 
 #: kallithea/controllers/error.py:96
 msgid "The request could not be understood by the server due to malformed syntax."
@@ -137,9 +139,9 @@
 msgstr "Es gibt hier noch keine Dateien. %s"
 
 #: kallithea/controllers/files.py:194
-#, fuzzy, python-format
+#, python-format
 msgid "%s at %s"
-msgstr "in %s und %s"
+msgstr "%s auf %s"
 
 #: kallithea/controllers/files.py:306 kallithea/controllers/files.py:366
 #: kallithea/controllers/files.py:433
@@ -354,7 +356,7 @@
 #: kallithea/controllers/pullrequests.py:405
 #, python-format
 msgid "New changesets on %s %s since the previous pull request:"
-msgstr ""
+msgstr "Neue Changesets in %s %s seit dem letzten Pull Request:"
 
 #: kallithea/controllers/pullrequests.py:412
 msgid "Ancestor didn't change - show diff since previous version:"
@@ -366,25 +368,26 @@
 "This pull request is based on another %s revision and there is no simple "
 "diff."
 msgstr ""
+"Dieser Pull Request basiert auf einer anderen %s Revision. Daher ist kein "
+"Simple Diff verfügbar."
 
 #: kallithea/controllers/pullrequests.py:421
 #, python-format
 msgid "No changes found on %s %s since previous version."
-msgstr ""
+msgstr "Keine Änderungen seit der letzten Version gefunden in %s %s."
 
 #: kallithea/controllers/pullrequests.py:456
 #, python-format
 msgid "Closed, replaced by %s ."
-msgstr ""
+msgstr "Geschlossen, ersetzt durch %s."
 
 #: kallithea/controllers/pullrequests.py:464
 msgid "Pull request update created"
-msgstr ""
+msgstr "Pull Request Update erstellt"
 
 #: kallithea/controllers/pullrequests.py:503
-#, fuzzy
 msgid "Pull request updated"
-msgstr "Pull Request"
+msgstr "Pull Request aktualisiert"
 
 #: kallithea/controllers/pullrequests.py:518
 msgid "Successfully deleted pull request"
@@ -393,34 +396,35 @@
 #: kallithea/controllers/pullrequests.py:577
 #, python-format
 msgid "This pull request has already been merged to %s."
-msgstr ""
+msgstr "Dieser Pull Request wurde bereits in %s integriert."
 
 #: kallithea/controllers/pullrequests.py:579
 msgid "This pull request has been closed and can not be updated."
 msgstr ""
+"Dieser Pull Request wurde geschlossen und kann daher nicht aktualisiert "
+"werden."
 
 #: kallithea/controllers/pullrequests.py:597
 #, python-format
 msgid "This pull request can be updated with changes on %s:"
-msgstr ""
+msgstr "Dieser Pull Request kann mit Änderungen in %s aktualisiert werden:"
 
 #: kallithea/controllers/pullrequests.py:600
 msgid "No changesets found for updating this pull request."
-msgstr ""
+msgstr "Keine Changesets gefunden, um den Pull Request zu aktualisieren."
 
 #: kallithea/controllers/pullrequests.py:608
 #, python-format
 msgid "Note: Branch %s has another head: %s."
-msgstr ""
+msgstr "Hinweis: Branch %s hat einen anderen Head: %s."
 
 #: kallithea/controllers/pullrequests.py:614
 msgid "Git pull requests don't support updates yet."
-msgstr ""
+msgstr "Git Pull Request unterstützen bisher keine Updates."
 
 #: kallithea/controllers/pullrequests.py:701
-#, fuzzy
 msgid "Closing."
-msgstr "Schließen mit"
+msgstr "Schließen."
 
 #: kallithea/controllers/search.py:135
 msgid "Invalid search query. Try quoting it."
@@ -436,9 +440,8 @@
 
 #: kallithea/controllers/summary.py:199
 #: kallithea/templates/summary/summary.html:387
-#, fuzzy
 msgid "No data ready yet"
-msgstr "Es wurden bisher keine Daten geladen"
+msgstr "Es stehen noch keine Daten zur Verfügung"
 
 #: kallithea/controllers/summary.py:202
 #: kallithea/templates/summary/summary.html:101
@@ -897,19 +900,18 @@
 "aufgetreten"
 
 #: kallithea/controllers/admin/settings.py:213
-#, fuzzy, python-format
+#, python-format
 msgid "Repositories successfully rescanned. Added: %s. Removed: %s."
 msgstr ""
-"Die Repositories wurden erfolgreich erneut überprüft hinzugefügt: %s ; "
-"entfernt: %s"
+"Die Repositories wurden erfolgreich überprüft. Hinzugefügt: %s. Entfernt: %s."
 
 #: kallithea/controllers/admin/settings.py:270
 msgid "Updated application settings"
-msgstr "Aktualisiere Applikations Einstellungen"
+msgstr "Anwendungseinstellungen aktualisiert"
 
 #: kallithea/controllers/admin/settings.py:327
 msgid "Updated visualisation settings"
-msgstr "Aktualisierte Layouteinstellungen"
+msgstr "Visualisierungseinstellungen aktualisiert"
 
 #: kallithea/controllers/admin/settings.py:332
 msgid "Error occurred during updating visualisation settings"
@@ -923,7 +925,7 @@
 
 #: kallithea/controllers/admin/settings.py:373
 msgid "Send email task created"
-msgstr ""
+msgstr "Task zum Versenden von E-Mails erstellt"
 
 #: kallithea/controllers/admin/settings.py:404
 msgid "Added new hook"
@@ -971,7 +973,7 @@
 
 #: kallithea/controllers/admin/user_groups.py:314
 msgid "Target group cannot be the same"
-msgstr ""
+msgstr "Zielgruppe kann nicht die gleiche Gruppe sein"
 
 #: kallithea/controllers/admin/user_groups.py:320
 msgid "User Group permissions updated"
@@ -1022,21 +1024,21 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
-msgstr "Die IP %s wurde zur Nutzerwhitelist hinzugefügt"
+msgid "Added IP address %s to user whitelist"
+msgstr "Die IP-Adresse %s wurde zur Nutzerwhitelist hinzugefügt"
 
 #: kallithea/controllers/admin/users.py:488
 msgid "An error occurred during ip saving"
-msgstr ""
+msgstr "Während des Speicherns der IP-Adresse ist ein Fehler aufgetreten"
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
-msgstr "IP wurde von der Nutzerwhitelist entfernt"
+msgid "Removed IP address from user whitelist"
+msgstr "IP-Adresse wurde von der Nutzerwhitelist entfernt"
 
 #: kallithea/lib/auth.py:745
 #, python-format
 msgid "IP %s not allowed"
-msgstr "IP %s ist nicht erlaubt"
+msgstr "IP-Adresse %s ist nicht erlaubt"
 
 #: kallithea/lib/auth.py:806
 msgid "You need to be a registered user to perform this action"
@@ -1048,7 +1050,7 @@
 
 #: kallithea/lib/base.py:427
 msgid "Repository not found in the filesystem"
-msgstr ""
+msgstr "Das Repository konnte nicht im Filesystem gefunden werden"
 
 #: kallithea/lib/base.py:453 kallithea/lib/helpers.py:643
 msgid "Changeset not found"
@@ -1108,7 +1110,7 @@
 #: kallithea/lib/helpers.py:761
 #, python-format
 msgid "Pull request #%s"
-msgstr ""
+msgstr "Pull Request #%s"
 
 #: kallithea/lib/helpers.py:771
 msgid "[deleted] repository"
@@ -1132,63 +1134,63 @@
 
 #: kallithea/lib/helpers.py:781
 msgid "[downloaded] archive from repository"
-msgstr ""
+msgstr "Archiv von Repository [heruntergeladen]"
 
 #: kallithea/lib/helpers.py:783
 msgid "[delete] repository"
-msgstr "[gelöscht] Repository"
+msgstr "Repository [gelöscht]"
 
 #: kallithea/lib/helpers.py:791
 msgid "[created] user"
-msgstr "[erstellt] Benutzer"
+msgstr "Benutzer [erstellt]"
 
 #: kallithea/lib/helpers.py:793
 msgid "[updated] user"
-msgstr "[akutalisiert] Benutzer"
+msgstr "Benutzer [akutalisiert]"
 
 #: kallithea/lib/helpers.py:795
 msgid "[created] user group"
-msgstr "[erstellt] Nutzergruppe"
+msgstr "Benutzergruppe [erstellt]"
 
 #: kallithea/lib/helpers.py:797
 msgid "[updated] user group"
-msgstr "[aktualisiert] Nutzergruppe"
+msgstr "Benutzergruppe [aktualisiert]"
 
 #: kallithea/lib/helpers.py:799
 msgid "[commented] on revision in repository"
-msgstr "[kommentiert]  revision in Repository"
+msgstr "Revision [kommentiert] in Repository"
 
 #: kallithea/lib/helpers.py:801
 msgid "[commented] on pull request for"
-msgstr ""
+msgstr "Pull Request [kommentiert] für"
 
 #: kallithea/lib/helpers.py:803
 msgid "[closed] pull request for"
-msgstr "[geschlossen] Pull Request für"
+msgstr "Pull Request [geschlossen] für"
 
 #: kallithea/lib/helpers.py:805
 msgid "[pushed] into"
-msgstr "[übermittelt] in"
+msgstr "[Pushed] in"
 
 #: kallithea/lib/helpers.py:807
 msgid "[committed via Kallithea] into repository"
-msgstr ""
+msgstr "[via Kallithea] in Repository [committed]"
 
 #: kallithea/lib/helpers.py:809
 msgid "[pulled from remote] into repository"
-msgstr ""
+msgstr "[Pulled von Remote] in Repository"
 
 #: kallithea/lib/helpers.py:811
 msgid "[pulled] from"
-msgstr "[gezogen] von"
+msgstr "[Pulled] von"
 
 #: kallithea/lib/helpers.py:813
 msgid "[started following] repository"
-msgstr ""
+msgstr "[Following gestartet] für Repository"
 
 #: kallithea/lib/helpers.py:815
 msgid "[stopped following] repository"
-msgstr ""
+msgstr "[Following gestoppt] für Repository"
 
 #: kallithea/lib/helpers.py:1144
 #, python-format
@@ -1205,7 +1207,7 @@
 
 #: kallithea/lib/helpers.py:1217
 msgid "mod"
-msgstr ""
+msgstr "mod"
 
 #: kallithea/lib/helpers.py:1220
 msgid "del"
@@ -1408,7 +1410,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1643
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1670 kallithea/model/db.py:1672
 msgid "Repository creation disabled"
-msgstr "Repository erstelllung deaktiviert"
+msgstr "Erstellung eines Repositorys deaktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1175
 #: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1194
@@ -1423,7 +1425,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1644
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1671 kallithea/model/db.py:1673
 msgid "Repository creation enabled"
-msgstr "Repository erstellung aktiviert"
+msgstr "Erstellung eines Repositorys aktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1176
 #: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1195
@@ -1438,7 +1440,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1648
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1675 kallithea/model/db.py:1677
 msgid "Repository forking disabled"
-msgstr ""
+msgstr "Forking eines Repositorys deaktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1177
 #: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1196
@@ -1453,7 +1455,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1649
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1676 kallithea/model/db.py:1678
 msgid "Repository forking enabled"
-msgstr ""
+msgstr "Forking eines Repositorys aktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_4_0.py:1178
 #: kallithea/lib/dbmigrate/schema/db_1_5_0.py:1197
@@ -1558,7 +1560,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1627
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1654 kallithea/model/db.py:1656
 msgid "Repository group no access"
-msgstr ""
+msgstr "Kein Zugriff für Repositorygruppe"
 
 #: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1394
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1414
@@ -1570,7 +1572,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1628
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1655 kallithea/model/db.py:1657
 msgid "Repository group read access"
-msgstr ""
+msgstr "Lesezugriff für Repositorygruppe"
 
 #: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1395
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1415
@@ -1582,7 +1584,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1629
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1656 kallithea/model/db.py:1658
 msgid "Repository group write access"
-msgstr ""
+msgstr "Schreibzugriff für Repositorygruppe"
 
 #: kallithea/lib/dbmigrate/schema/db_1_6_0.py:1396
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1416
@@ -1594,7 +1596,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1630
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1657 kallithea/model/db.py:1659
 msgid "Repository group admin access"
-msgstr ""
+msgstr "Administrativer Zugriff für Repositorygruppe"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1418
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1464
@@ -1605,7 +1607,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1632
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1659 kallithea/model/db.py:1661
 msgid "User group no access"
-msgstr ""
+msgstr "Kein Zugriff für Benutzergruppe"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1419
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1465
@@ -1616,7 +1618,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1633
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1660 kallithea/model/db.py:1662
 msgid "User group read access"
-msgstr ""
+msgstr "Lesezugriff für Benutzergruppe"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1420
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1466
@@ -1638,7 +1640,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1635
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1662 kallithea/model/db.py:1664
 msgid "User group admin access"
-msgstr ""
+msgstr "Administrativer Zugriff für Benutzergruppe"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1423
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1469
@@ -1649,7 +1651,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1637
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1664 kallithea/model/db.py:1666
 msgid "Repository Group creation disabled"
-msgstr ""
+msgstr "Erstellung von Repositorygruppen deaktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1424
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1470
@@ -1660,7 +1662,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1638
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1665 kallithea/model/db.py:1667
 msgid "Repository Group creation enabled"
-msgstr ""
+msgstr "Erstellung von Repositorygruppen aktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1426
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1472
@@ -1671,7 +1673,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1640
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1667 kallithea/model/db.py:1669
 msgid "User Group creation disabled"
-msgstr ""
+msgstr "Erstellung von Benutzergruppen deaktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1427
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1473
@@ -1682,7 +1684,7 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1641
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1668 kallithea/model/db.py:1670
 msgid "User Group creation enabled"
-msgstr ""
+msgstr "Erstellung von Benutzergruppen aktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_1_7_0.py:1435
 #: kallithea/lib/dbmigrate/schema/db_1_8_0.py:1481
@@ -1721,11 +1723,14 @@
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1672 kallithea/model/db.py:1674
 msgid "Repository creation enabled with write permission to a repository group"
 msgstr ""
+"Erstellung von Repositories mit Schreibzugriff für Repositorygruppe aktiviert"
 
 #: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1646
 #: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1673 kallithea/model/db.py:1675
 msgid "Repository creation disabled with write permission to a repository group"
 msgstr ""
+"Erstellung von Repositories mit Schreibzugriff für Repositorygruppe "
+"deaktiviert"
 
 #: kallithea/model/comment.py:76
 #, python-format
@@ -1761,32 +1766,32 @@
 #: kallithea/model/notification.py:252
 #, python-format
 msgid "%(user)s commented on changeset at %(when)s"
-msgstr ""
+msgstr "%(user)s hat am %(when)s ein Changeset kommentiert"
 
 #: kallithea/model/notification.py:253
 #, python-format
 msgid "%(user)s sent message at %(when)s"
-msgstr ""
+msgstr "%(user)s hat am %(when)s eine Nachricht gesendet"
 
 #: kallithea/model/notification.py:254
 #, python-format
 msgid "%(user)s mentioned you at %(when)s"
-msgstr ""
+msgstr "%(user)s hat Sie am %(when)s erwähnt"
 
 #: kallithea/model/notification.py:255
 #, python-format
 msgid "%(user)s registered in Kallithea at %(when)s"
-msgstr ""
+msgstr "%(user)s hat sich am %(when)s bei Kallithea registriert"
 
 #: kallithea/model/notification.py:256
 #, python-format
 msgid "%(user)s opened new pull request at %(when)s"
-msgstr ""
+msgstr "%(user)s hat am %(when)s einen neuen Pull Request eröffnet"
 
 #: kallithea/model/notification.py:257
 #, python-format
 msgid "%(user)s commented on pull request at %(when)s"
-msgstr ""
+msgstr "%(user)s hat am %(when)s einen Pull Request kommentiert"
 
 #: kallithea/model/notification.py:296
 #, python-format
@@ -1794,6 +1799,8 @@
 "Comment on %(repo_name)s changeset %(short_id)s on %(branch)s by "
 "%(comment_username)s"
 msgstr ""
+"Kommentar für %(repo_name)s Changeset %(short_id)s in %(branch)s erstellt "
+"von %(comment_username)s"
 
 #: kallithea/model/notification.py:299
 #, python-format
@@ -1806,6 +1813,8 @@
 "Review request on %(repo_name)s pull request #%(pr_id)s from %(ref)s by "
 "%(pr_username)s"
 msgstr ""
+"Review Request für %(repo_name)s Pull Request #%(pr_id)s von %(ref)s "
+"erstellt von %(pr_username)s"
 
 #: kallithea/model/notification.py:302
 #, python-format
@@ -1813,36 +1822,37 @@
 "Comment on %(repo_name)s pull request #%(pr_id)s from %(ref)s by "
 "%(comment_username)s"
 msgstr ""
+"Kommentar von %(comment_username)s für %(repo_name)s Pull Request #%(pr_id)s "
+"von %(ref)s"
 
 #: kallithea/model/notification.py:315
-#, fuzzy
 msgid "Closing"
-msgstr "Schließen mit"
+msgstr "Schließen"
 
 #: kallithea/model/pull_request.py:132
 #, python-format
 msgid "%(user)s wants you to review pull request #%(pr_id)s: %(pr_title)s"
-msgstr ""
+msgstr "%(user)s möchte ein Review des Pull Request #%(pr_id)s: %(pr_title)s"
 
 #: kallithea/model/scm.py:808
 msgid "latest tip"
-msgstr ""
+msgstr "Letzter Tip"
 
 #: kallithea/model/user.py:194
 msgid "New user registration"
-msgstr ""
+msgstr "Neue Benutzerregistrierung"
 
 #: kallithea/model/user.py:214 kallithea/model/user.py:236
 msgid "You can't Edit this user since it's crucial for entire application"
 msgstr ""
 "Sie können diesen Benutzer nicht editieren, da er von entscheidender "
-"Bedeutung für die ganze Applikation ist"
+"Bedeutung für die gesamte Applikation ist"
 
 #: kallithea/model/user.py:255
 msgid "You can't remove this user since it's crucial for entire application"
 msgstr ""
-"Sie können diesen Benutzer nicht löschen, da er von entscheidender "
-"Bedeutung für die ganze Applikation ist"
+"Sie können diesen Benutzer nicht löschen, da er von entscheidender Bedeutung "
+"für die gesamte Applikation ist"
 
 #: kallithea/model/user.py:261
 #, python-format
@@ -1850,6 +1860,9 @@
 "User \"%s\" still owns %s repositories and cannot be removed. Switch "
 "owners or remove those repositories: %s"
 msgstr ""
+"Der Benutzer \"%s\" besitzt noch immer %s Repositories und kann daher nicht "
+"entfernt werden. Entweder muss der Besitzer geändert oder das Repository "
+"entfernt werden: %s"
 
 #: kallithea/model/user.py:268
 #, python-format
@@ -1857,6 +1870,9 @@
 "User \"%s\" still owns %s repository groups and cannot be removed. Switch"
 " owners or remove those repository groups: %s"
 msgstr ""
+"Der Benutzer \"%s\" ist noch der Besitzer von %s Repositorygruppen und kann "
+"daher nicht entfernt werden. Entweder muss der Besitzer geändert oder die "
+"Repositorygruppen müssen entfernt werden: %s"
 
 #: kallithea/model/user.py:275
 #, python-format
@@ -1864,10 +1880,13 @@
 "User \"%s\" still owns %s user groups and cannot be removed. Switch "
 "owners or remove those user groups: %s"
 msgstr ""
+"Der Benutzer \"%s\" besitzt noch immer %s Benutzergruppen und kann daher "
+"nicht entfernt werden. Entweder muss der Besitzer geändert oder die "
+"Benutzergruppen müssen gelöscht werden: %s"
 
 #: kallithea/model/user.py:305
 msgid "Password reset link"
-msgstr ""
+msgstr "Link zum Zurücksetzen des Passworts"
 
 #: kallithea/model/user.py:328
 msgid "Your new password"
@@ -1876,11 +1895,11 @@
 #: kallithea/model/user.py:329
 #, python-format
 msgid "Your new Kallithea password:%s"
-msgstr "Dein neues Kallithea-Passwort: %s"
+msgstr "Ihr neues Kallithea-Passwort: %s"
 
 #: kallithea/model/validators.py:83 kallithea/model/validators.py:84
 msgid "Value cannot be an empty list"
-msgstr ""
+msgstr "Eine leere Liste ist kein gültiger Wert"
 
 #: kallithea/model/validators.py:101
 #, python-format
@@ -1948,7 +1967,7 @@
 
 #: kallithea/model/validators.py:275
 msgid "Invalid old password"
-msgstr ""
+msgstr "Ungültiges altes Passwort"
 
 #: kallithea/model/validators.py:291
 msgid "Passwords do not match"
@@ -1986,16 +2005,16 @@
 #: kallithea/model/validators.py:359
 #, python-format
 msgid "Repository group with name \"%(repo)s\" already exists"
-msgstr ""
+msgstr "Eine Repositorygruppe mit dem Namen \"%(repo)s\" existiert bereits"
 
 #: kallithea/model/validators.py:474
-#, fuzzy
 msgid "invalid clone URL"
-msgstr "ungültige Clone Adresse"
+msgstr "ungültige Clone-URL"
 
 #: kallithea/model/validators.py:475
 msgid "Invalid clone URL, provide a valid clone http(s)/svn+http(s)/ssh URL"
 msgstr ""
+"Ungültige Clone-URL, gültige Clone-URL (http(s)/svn+http(s)/ssh) angeben"
 
 #: kallithea/model/validators.py:500
 msgid "Fork has to be the same type as parent"
@@ -2009,11 +2028,11 @@
 
 #: kallithea/model/validators.py:517
 msgid "no permission to create repository in root location"
-msgstr ""
+msgstr "keine Berechtigung, um ein Repository auf höchster Ebene anzulegen"
 
 #: kallithea/model/validators.py:566
 msgid "You don't have permissions to create a group in this location"
-msgstr ""
+msgstr "Sie haben keine Berechtigung, um an diesem Ort ein Repository anzulegen"
 
 #: kallithea/model/validators.py:607
 msgid "This username or user group name is not valid"
@@ -2025,38 +2044,44 @@
 
 #: kallithea/model/validators.py:715
 msgid "This e-mail address is already taken"
-msgstr "Diese EMail Addresse ist schon in Benutzung"
+msgstr "Diese E-Mailaddresse ist bereits in Benutzung"
 
 #: kallithea/model/validators.py:735
 #, python-format
 msgid "e-mail \"%(email)s\" does not exist."
-msgstr "EMail Addresse \"%(email)s\" existiert nicht."
+msgstr "E-MailAddresse \"%(email)s\" existiert nicht."
 
 #: kallithea/model/validators.py:772
 msgid ""
 "The LDAP Login attribute of the CN must be specified - this is the name "
 "of the attribute that is equivalent to \"username\""
 msgstr ""
-"Das LDAP Login Attribut des CN muss angeben werden - Es ist der Name des "
-"Attributes welches das Equivalent zum \"Benutzername\" ist"
+"Das LDAP-Login-Attribut des CN muss angeben werden - Es ist der Name des "
+"Attributes äquivalent zu \"Benutzername\""
 
 #: kallithea/model/validators.py:785
 #, python-format
 msgid "Revisions %(revs)s are already part of pull request or have set status"
 msgstr ""
+"Die Revisionen %(revs)s sind bereits Bestandteil des Pull Requests oder "
+"haben den Status"
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
-msgstr "Bitte gib eine gültige IPv4- oder IPv6-Adresse an"
+msgid "Please enter a valid IPv4 or IPv6 address"
+msgstr "Bitte eine gültige IPv4- oder IPv6-Adresse angeben"
 
 #: kallithea/model/validators.py:818
 #, python-format
 msgid "The network size (bits) must be within the range of 0-32 (not %(bits)r)"
 msgstr ""
+"Die Größe (in Bits) des Netzwerks muss im Bereich 0-32 liegen (nicht "
+"%(bits)r)"
 
 #: kallithea/model/validators.py:851
 msgid "Key name can only consist of letters, underscore, dash or numbers"
 msgstr ""
+"Der Name eines Schlüssels darf nur aus Buchstaben, Ziffern, Unterstrich und "
+"Bindestrich bestehen"
 
 #: kallithea/model/validators.py:865
 msgid "Filename cannot be inside a directory"
@@ -2066,6 +2091,8 @@
 #, python-format
 msgid "Plugins %(loaded)s and %(next_to_load)s both export the same name"
 msgstr ""
+"Die Plug-Ins %(loaded)s und %(next_to_load)s exportieren beide den selben "
+"Namen"
 
 #: kallithea/templates/about.html:4 kallithea/templates/about.html:17
 msgid "About"
@@ -2109,7 +2136,7 @@
 #: kallithea/templates/admin/repo_groups/repo_group_add.html:13
 #: kallithea/templates/admin/repo_groups/repo_groups.html:26
 msgid "Add Repository Group"
-msgstr ""
+msgstr "Repositorygruppe hinzufügen"
 
 #: kallithea/templates/index_base.html:32
 msgid "You have admin right to this group, and can edit it"
@@ -2117,7 +2144,7 @@
 
 #: kallithea/templates/index_base.html:32
 msgid "Edit Repository Group"
-msgstr ""
+msgstr "Repositorygruppe bearbeiten"
 
 #: kallithea/templates/index_base.html:45
 msgid "Group Name"
@@ -2246,12 +2273,12 @@
 #: kallithea/templates/login.html:5 kallithea/templates/login.html:15
 #: kallithea/templates/base/base.html:329
 msgid "Log In"
-msgstr ""
+msgstr "Log In"
 
 #: kallithea/templates/login.html:13
 #, python-format
 msgid "Log In to %s"
-msgstr ""
+msgstr "Log In in %s"
 
 #: kallithea/templates/login.html:27 kallithea/templates/register.html:24
 #: kallithea/templates/admin/admin_log.html:5
@@ -2309,16 +2336,16 @@
 msgstr "Captcha"
 
 #: kallithea/templates/password_reset.html:46
-#, fuzzy
 msgid "Send Password Reset Email"
-msgstr "Passwort zurücksetzen"
+msgstr "E-Mail zum Zurücksetzen des Passworts anfordern"
 
 #: kallithea/templates/password_reset.html:47
-#, fuzzy
 msgid ""
 "Password reset link will be sent to the email address matching your "
 "username."
-msgstr "Der Passwort Reset LInk wird an die passende EMail Addresse gesendet"
+msgstr ""
+"Der Link zum Zurücksetzen des Passworts wird an die zum Benutzernamen "
+"zugehörige E-Mailaddresse gesendet."
 
 #: kallithea/templates/register.html:5 kallithea/templates/register.html:14
 #: kallithea/templates/register.html:90
@@ -2328,7 +2355,7 @@
 #: kallithea/templates/register.html:12
 #, python-format
 msgid "Sign Up to %s"
-msgstr ""
+msgstr "Registrieren für %s"
 
 #: kallithea/templates/register.html:42
 msgid "Re-enter password"
@@ -2356,15 +2383,17 @@
 #: kallithea/templates/admin/users/user_add.html:77
 #: kallithea/templates/admin/users/user_edit_profile.html:42
 msgid "Email"
-msgstr "EMail"
+msgstr "E-Mail"
 
 #: kallithea/templates/register.html:92
 msgid "Registered accounts are ready to use and need no further action."
-msgstr ""
+msgstr "Registrierte Konten können ohne weitere Aktion genutzt werden."
 
 #: kallithea/templates/register.html:94
 msgid "Please wait for an administrator to activate your account."
 msgstr ""
+"Bitte warten Sie auf die Aktivierung Ihres Benutzerkontos durch einen "
+"Administrator."
 
 #: kallithea/templates/switch_to_list.html:10
 #: kallithea/templates/branches/branches_data.html:69
@@ -2373,7 +2402,7 @@
 
 #: kallithea/templates/switch_to_list.html:16
 msgid "Closed Branches"
-msgstr ""
+msgstr "Geschlossene Branches"
 
 #: kallithea/templates/switch_to_list.html:32
 #: kallithea/templates/tags/tags_data.html:44
@@ -2388,9 +2417,8 @@
 #: kallithea/templates/admin/admin.html:5
 #: kallithea/templates/admin/admin.html:13
 #: kallithea/templates/base/base.html:59
-#, fuzzy
 msgid "Admin Journal"
-msgstr "Admin Logbuch"
+msgstr "Admin-Logbuch"
 
 #: kallithea/templates/admin/admin.html:10
 msgid "journal filter..."
@@ -2398,9 +2426,8 @@
 
 #: kallithea/templates/admin/admin.html:12
 #: kallithea/templates/journal/journal.html:11
-#, fuzzy
 msgid "Filter"
-msgstr "Profil"
+msgstr "Filter"
 
 #: kallithea/templates/admin/admin.html:13
 #: kallithea/templates/journal/journal.html:12
@@ -2448,16 +2475,16 @@
 
 #: kallithea/templates/admin/auth/auth_settings.html:5
 msgid "Authentication Settings"
-msgstr ""
+msgstr "Authentifizierungseinstellungen"
 
 #: kallithea/templates/admin/auth/auth_settings.html:11
 #: kallithea/templates/base/base.html:65
 msgid "Authentication"
-msgstr ""
+msgstr "Authentifizierung"
 
 #: kallithea/templates/admin/auth/auth_settings.html:28
 msgid "Authentication Plugins"
-msgstr ""
+msgstr "Plug-Ins zur Authentifizierung"
 
 #: kallithea/templates/admin/auth/auth_settings.html:31
 msgid "Enabled Plugins"
@@ -2468,10 +2495,13 @@
 "Comma separated list of plugins. Order of plugins is also order in which "
 "Kallithea will try to authenticate user"
 msgstr ""
+"Kommaseparierte Liste der Plug-Ins. Reihenfolge der Plug-Ins entspricht der "
+"Reihenfolge, in der Kallithea die Plug-Ins zur Authentifizierung des "
+"Benutzers verwendet"
 
 #: kallithea/templates/admin/auth/auth_settings.html:34
 msgid "Available built-in plugins"
-msgstr ""
+msgstr "Verfügbare mitgelieferte Plug-Ins"
 
 #: kallithea/templates/admin/auth/auth_settings.html:40
 #: kallithea/templates/base/root.html:40
@@ -2509,9 +2539,8 @@
 
 #: kallithea/templates/admin/defaults/defaults.html:5
 #: kallithea/templates/admin/defaults/defaults.html:25
-#, fuzzy
 msgid "Repository Defaults"
-msgstr "Repositories"
+msgstr "Repositorystandards"
 
 #: kallithea/templates/admin/defaults/defaults.html:11
 #: kallithea/templates/base/base.html:66
@@ -2539,6 +2568,7 @@
 "Private repositories are only visible to people explicitly added as "
 "collaborators."
 msgstr ""
+"Private Repositories sind nur für explizit hinzugefügte Mitarbeiter sichtbar."
 
 #: kallithea/templates/admin/defaults/defaults.html:55
 #: kallithea/templates/admin/repos/repo_edit_settings.html:91
@@ -2548,7 +2578,7 @@
 #: kallithea/templates/admin/defaults/defaults.html:59
 #: kallithea/templates/admin/repos/repo_edit_settings.html:95
 msgid "Enable statistics window on summary page."
-msgstr ""
+msgstr "Statistik-Fenster in der Zusammenfassungsseite aktivieren."
 
 #: kallithea/templates/admin/defaults/defaults.html:65
 #: kallithea/templates/admin/repos/repo_edit_settings.html:100
@@ -2558,13 +2588,13 @@
 #: kallithea/templates/admin/defaults/defaults.html:69
 #: kallithea/templates/admin/repos/repo_edit_settings.html:104
 msgid "Enable download menu on summary page."
-msgstr ""
+msgstr "Download-Menü auf der Zusammenfassungsseite aktivieren."
 
 #: kallithea/templates/admin/defaults/defaults.html:75
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:34
 #: kallithea/templates/admin/repos/repo_edit_settings.html:109
 msgid "Enable locking"
-msgstr ""
+msgstr "Locking aktivieren"
 
 #: kallithea/templates/admin/defaults/defaults.html:79
 #: kallithea/templates/admin/repos/repo_edit_settings.html:113
@@ -2574,7 +2604,7 @@
 #: kallithea/templates/admin/gists/edit.html:5
 #: kallithea/templates/admin/gists/edit.html:18
 msgid "Edit Gist"
-msgstr ""
+msgstr "Gist editieren"
 
 #: kallithea/templates/admin/gists/edit.html:36
 #, python-format
@@ -2600,7 +2630,7 @@
 #: kallithea/templates/admin/gists/show.html:47
 #: kallithea/templates/admin/gists/show.html:49
 msgid "Expires"
-msgstr ""
+msgstr "Verfällt"
 
 #: kallithea/templates/admin/gists/edit.html:61
 #: kallithea/templates/admin/gists/index.html:57
@@ -2614,7 +2644,7 @@
 
 #: kallithea/templates/admin/gists/edit.html:145
 msgid "Update Gist"
-msgstr ""
+msgstr "Gist aktualisieren"
 
 #: kallithea/templates/admin/gists/edit.html:146
 #: kallithea/templates/changeset/changeset_file_comment.html:89
@@ -2623,52 +2653,52 @@
 
 #: kallithea/templates/admin/gists/index.html:6
 #: kallithea/templates/admin/gists/index.html:16
-#, fuzzy, python-format
+#, python-format
 msgid "Private Gists for User %s"
-msgstr "Nutzer %s erstellt"
+msgstr "Privater Gist für Benutzer %s"
 
 #: kallithea/templates/admin/gists/index.html:8
 #: kallithea/templates/admin/gists/index.html:18
 #, python-format
 msgid "Public Gists for User %s"
-msgstr ""
+msgstr "Öffentlicher Gist für Benutzer %s"
 
 #: kallithea/templates/admin/gists/index.html:10
 #: kallithea/templates/admin/gists/index.html:20
 msgid "Public Gists"
-msgstr ""
+msgstr "Öffentliche Gists"
 
 #: kallithea/templates/admin/gists/index.html:37
 #: kallithea/templates/admin/gists/show.html:25
 #: kallithea/templates/base/base.html:240
 msgid "Create New Gist"
-msgstr ""
+msgstr "Neuen Gist erstellen"
 
 #: kallithea/templates/admin/gists/index.html:54
 #: kallithea/templates/data_table/_dt_elements.html:143
 msgid "Created"
-msgstr ""
+msgstr "Erstellt"
 
 #: kallithea/templates/admin/gists/index.html:74
 msgid "There are no gists yet"
-msgstr ""
+msgstr "Bisher sind keine Gists vorhanden"
 
 #: kallithea/templates/admin/gists/new.html:5
 #: kallithea/templates/admin/gists/new.html:18
 msgid "New Gist"
-msgstr ""
+msgstr "Neuer Gist"
 
 #: kallithea/templates/admin/gists/new.html:47
 msgid "name this file..."
-msgstr ""
+msgstr "benenne diese Datei..."
 
 #: kallithea/templates/admin/gists/new.html:56
 msgid "Create Private Gist"
-msgstr ""
+msgstr "Privaten Gist erstellen"
 
 #: kallithea/templates/admin/gists/new.html:57
 msgid "Create Public Gist"
-msgstr ""
+msgstr "Öffentlichen Gist erstellen"
 
 #: kallithea/templates/admin/gists/new.html:58
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:70
@@ -2701,7 +2731,7 @@
 #: kallithea/templates/admin/gists/show.html:5
 #: kallithea/templates/admin/gists/show.html:9
 msgid "Gist"
-msgstr ""
+msgstr "Gist"
 
 #: kallithea/templates/admin/gists/show.html:10
 #: kallithea/templates/email_templates/changeset_comment.html:15
@@ -2712,11 +2742,11 @@
 
 #: kallithea/templates/admin/gists/show.html:37
 msgid "Public Gist"
-msgstr ""
+msgstr "Öffentlicher Gist"
 
 #: kallithea/templates/admin/gists/show.html:39
 msgid "Private Gist"
-msgstr ""
+msgstr "Privater Gist"
 
 #: kallithea/templates/admin/gists/show.html:56
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:76
@@ -2729,7 +2759,7 @@
 
 #: kallithea/templates/admin/gists/show.html:56
 msgid "Confirm to delete this Gist"
-msgstr ""
+msgstr "Löschen des Gists bestätigen"
 
 #: kallithea/templates/admin/gists/show.html:63
 #: kallithea/templates/changeset/changeset_file_comment.html:91
@@ -2751,7 +2781,7 @@
 
 #: kallithea/templates/admin/gists/show.html:73
 msgid "created"
-msgstr ""
+msgstr "erstellt"
 
 #: kallithea/templates/admin/gists/show.html:86
 #: kallithea/templates/files/files_source.html:73
@@ -2772,7 +2802,7 @@
 #: kallithea/templates/admin/my_account/my_account.html:37
 #: kallithea/templates/admin/users/user_edit.html:30
 msgid "API Keys"
-msgstr ""
+msgstr "API Keys"
 
 #: kallithea/templates/admin/my_account/my_account.html:38
 msgid "My Emails"
@@ -2785,17 +2815,16 @@
 #: kallithea/templates/admin/my_account/my_account.html:40
 #: kallithea/templates/journal/journal.html:53
 msgid "Watched"
-msgstr ""
+msgstr "Beobachtet"
 
 #: kallithea/templates/admin/my_account/my_account.html:41
-#, fuzzy
 msgid "My Permissions"
-msgstr "Meine Rechte"
+msgstr "Meine Erlaubnisse"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:6
 #: kallithea/templates/admin/users/user_edit_api_keys.html:6
 msgid "Built-in"
-msgstr ""
+msgstr "Mitgeliefert"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:8
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:27
@@ -2804,44 +2833,44 @@
 #: kallithea/templates/admin/users/user_edit_api_keys.html:27
 #: kallithea/templates/admin/users/user_edit_api_keys.html:32
 msgid "expires"
-msgstr ""
+msgstr "verfällt"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:14
 #: kallithea/templates/admin/users/user_edit_api_keys.html:14
 #, python-format
 msgid "Confirm to reset this api key: %s"
-msgstr ""
+msgstr "Zurücksetzen des API Keys \"%s\" bestätigen"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:15
 #: kallithea/templates/admin/users/user_edit_api_keys.html:15
 msgid "reset"
-msgstr ""
+msgstr "Zurücksetzen"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:30
 #: kallithea/templates/admin/users/user_edit_api_keys.html:30
 msgid "expired"
-msgstr ""
+msgstr "verfallen"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:40
 #: kallithea/templates/admin/users/user_edit_api_keys.html:40
 #, python-format
 msgid "Confirm to remove this api key: %s"
-msgstr ""
+msgstr "Entfernen des API Keys \"%s\" bestätigen"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:42
 #: kallithea/templates/admin/users/user_edit_api_keys.html:42
 msgid "remove"
-msgstr ""
+msgstr "entfernen"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:49
 #: kallithea/templates/admin/users/user_edit_api_keys.html:49
 msgid "No additional api keys specified"
-msgstr ""
+msgstr "Keine weiteren API Keys spezifiziert"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:61
 #: kallithea/templates/admin/users/user_edit_api_keys.html:61
 msgid "New api key"
-msgstr ""
+msgstr "Neuer API Key"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:69
 #: kallithea/templates/admin/my_account/my_account_emails.html:45
@@ -2857,7 +2886,7 @@
 #: kallithea/templates/admin/my_account/my_account_emails.html:7
 #: kallithea/templates/admin/users/user_edit_emails.html:7
 msgid "Primary"
-msgstr ""
+msgstr "Primär"
 
 #: kallithea/templates/admin/my_account/my_account_emails.html:19
 #: kallithea/templates/admin/permissions/permissions_ips.html:14
@@ -2876,12 +2905,12 @@
 #: kallithea/templates/admin/users/user_edit_emails.html:20
 #, python-format
 msgid "Confirm to delete this email: %s"
-msgstr ""
+msgstr "Löschen der E-Mail \"%s\" bestätigen"
 
 #: kallithea/templates/admin/my_account/my_account_emails.html:26
 #: kallithea/templates/admin/users/user_edit_emails.html:26
 msgid "No additional emails specified."
-msgstr ""
+msgstr "Keine weiteren E-Mails spezifiziert."
 
 #: kallithea/templates/admin/my_account/my_account_emails.html:38
 #: kallithea/templates/admin/users/user_edit_emails.html:38
@@ -2889,9 +2918,8 @@
 msgstr "Neue E-Mailadresse"
 
 #: kallithea/templates/admin/my_account/my_account_password.html:1
-#, fuzzy
 msgid "Change Your Account Password"
-msgstr "Dein neues Passwort"
+msgstr "Passwort des Benutzerkontos ändern"
 
 #: kallithea/templates/admin/my_account/my_account_password.html:7
 msgid "Current password"
@@ -2922,7 +2950,7 @@
 
 #: kallithea/templates/admin/my_account/my_account_profile.html:15
 msgid "Missing email, please update your user email address."
-msgstr ""
+msgstr "E-Mailadresse fehlt, bitte aktualisieren."
 
 #: kallithea/templates/admin/my_account/my_account_profile.html:16
 #: kallithea/templates/admin/users/user_edit_profile.html:15
@@ -2936,9 +2964,8 @@
 msgstr ""
 
 #: kallithea/templates/admin/my_account/my_account_repos.html:1
-#, fuzzy
 msgid "Repositories You Own"
-msgstr "Keine Repositories gefunden."
+msgstr "Repositories in Ihrem Besitz"
 
 #: kallithea/templates/admin/my_account/my_account_repos.html:59
 #: kallithea/templates/admin/my_account/my_account_watched.html:59
@@ -2952,9 +2979,8 @@
 msgstr "Keine Datensätze gefunden."
 
 #: kallithea/templates/admin/my_account/my_account_watched.html:1
-#, fuzzy
 msgid "Repositories You are Watching"
-msgstr "Repository erstellung"
+msgstr "Repositories, denen Sie folgen"
 
 #: kallithea/templates/admin/notifications/notifications.html:5
 #: kallithea/templates/admin/notifications/notifications.html:9
@@ -2993,9 +3019,8 @@
 msgstr "Benachrichtigungen"
 
 #: kallithea/templates/admin/permissions/permissions.html:5
-#, fuzzy
 msgid "Permissions Administration"
-msgstr "Rechte Administration"
+msgstr "Rechteverwaltung"
 
 #: kallithea/templates/admin/permissions/permissions.html:11
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:42
@@ -3013,7 +3038,7 @@
 #: kallithea/templates/admin/permissions/permissions.html:29
 #: kallithea/templates/admin/users/user_edit.html:34
 msgid "IP Whitelist"
-msgstr ""
+msgstr "IP Whitelist"
 
 #: kallithea/templates/admin/permissions/permissions.html:30
 msgid "Overview"
@@ -3029,6 +3054,8 @@
 "Allow access to Kallithea without needing to log in. Anonymous users use "
 "%s user permissions."
 msgstr ""
+"Unauthentifizierten Zugriff auf Kallithea erlauben. Anonyme Benutzer "
+"verwenden %s Benutzerrechte."
 
 #: kallithea/templates/admin/permissions/permissions_globals.html:26
 msgid ""
@@ -3036,6 +3063,9 @@
 "permission, note that all custom default permission on repositories will "
 "be lost"
 msgstr ""
+"Alle Standardrechte jedes Repositorys werden auf die gewählten Rechte "
+"gesetzt. Beachten Sie, dass alle spezifischen Standardrechte der "
+"Repositories verloren gehen"
 
 #: kallithea/templates/admin/permissions/permissions_globals.html:27
 #: kallithea/templates/admin/permissions/permissions_globals.html:40
@@ -3057,6 +3087,9 @@
 "permission, note that all custom default permission on repository groups "
 "will be lost"
 msgstr ""
+"Alle Standardrechte jeder Repositorygruppe werden auf die gewählten Rechte "
+"gesetzt. Beachten Sie, dass all spezifischen Standardrechte der "
+"Repositorygruppen verloren gehen"
 
 #: kallithea/templates/admin/permissions/permissions_globals.html:46
 #: kallithea/templates/data_table/_dt_elements.html:211
@@ -3069,6 +3102,9 @@
 "permission, note that all custom default permission on repository groups "
 "will be lost"
 msgstr ""
+"Alle Standardrechte jeder Benutzergruppe werden auf die gewählten Rechte "
+"gesetzt. Beachten Sie, dass alle spezifischen Standardrechte der "
+"Benutzergruppen verloren gehen"
 
 #: kallithea/templates/admin/permissions/permissions_globals.html:60
 msgid "Repository creation"
@@ -3117,13 +3153,12 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr "Neue IP-Adresse"
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
-#, fuzzy
 msgid "Default User Permissions Overview"
-msgstr "Standart Rechte"
+msgstr "Übersicht der Standardbenutzerrechte"
 
 #: kallithea/templates/admin/repo_groups/repo_group_add.html:11
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:11
@@ -3131,7 +3166,7 @@
 #: kallithea/templates/admin/repo_groups/repo_groups.html:10
 #: kallithea/templates/base/base.html:61 kallithea/templates/base/base.html:80
 msgid "Repository Groups"
-msgstr ""
+msgstr "Repositorygruppen"
 
 #: kallithea/templates/admin/repo_groups/repo_group_add.html:33
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:8
@@ -3143,26 +3178,26 @@
 #: kallithea/templates/admin/repo_groups/repo_group_add.html:51
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:26
 msgid "Group parent"
-msgstr ""
+msgstr "Übergeordnete Gruppe"
 
 #: kallithea/templates/admin/repo_groups/repo_group_add.html:60
 #: kallithea/templates/admin/repos/repo_add_base.html:50
 msgid "Copy parent group permissions"
-msgstr ""
+msgstr "Rechte der übergeordneten Gruppe kopieren"
 
 #: kallithea/templates/admin/repo_groups/repo_group_add.html:64
 #: kallithea/templates/admin/repos/repo_add_base.html:54
 msgid "Copy permission set from parent repository group."
-msgstr ""
+msgstr "Rechte der übergeordneten Repositorygruppe kopieren."
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:5
-#, fuzzy, python-format
+#, python-format
 msgid "%s Repository Group Settings"
-msgstr "Repositoriumsgruppe %s aktualisiert"
+msgstr "%s Einstellungen für Repositorygruppen"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:21
 msgid "Add Child Group"
-msgstr ""
+msgstr "Untergruppe hinzufügen"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:40
 #: kallithea/templates/admin/repos/repo_edit.html:12
@@ -3185,11 +3220,11 @@
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:1
 #, python-format
 msgid "Repository Group: %s"
-msgstr ""
+msgstr "Repositorygruppe: %s"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:6
 msgid "Top level repositories"
-msgstr ""
+msgstr "Repositories oberster Ebene"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:7
 msgid "Total repositories"
@@ -3197,26 +3232,26 @@
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:8
 msgid "Children groups"
-msgstr ""
+msgstr "Untergruppen"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:9
 #: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:7
 #: kallithea/templates/admin/users/user_edit_advanced.html:8
 #: kallithea/templates/pullrequests/pullrequest_show.html:147
 msgid "Created on"
-msgstr ""
+msgstr "Erstellt am"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:21
 #: kallithea/templates/data_table/_dt_elements.html:192
 #, python-format
 msgid "Confirm to delete this group: %s with %s repository"
 msgid_plural "Confirm to delete this group: %s with %s repositories"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Löschen der Gruppe bestätigen: %s mit %s Repository"
+msgstr[1] "Löschen der Gruppe bestätigen: %s mit %s Repositories"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:25
 msgid "Delete this repository group"
-msgstr ""
+msgstr "Diese Repositorygruppe löschen"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:7
 #: kallithea/templates/admin/repos/repo_edit_permissions.html:8
@@ -3287,7 +3322,7 @@
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:107
 msgid "Both"
-msgstr ""
+msgstr "Beide"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:108
 msgid ""
@@ -3302,14 +3337,12 @@
 msgstr ""
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:53
-#, fuzzy
 msgid "Remove this group"
-msgstr "Diese Benutzergruppe löschen"
+msgstr "Diese Gruppe löschen"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:53
-#, fuzzy
 msgid "Confirm to delete this group"
-msgstr ""
+msgstr "Löschen der Gruppe bestätigen"
 
 #: kallithea/templates/admin/repo_groups/repo_group_show.html:4
 #, python-format
@@ -3325,17 +3358,16 @@
 msgstr "mit"
 
 #: kallithea/templates/admin/repo_groups/repo_groups.html:5
-#, fuzzy
 msgid "Repository Groups Administration"
-msgstr "Benutzergruppenverwaltung"
+msgstr "Repositorygruppenverwaltung"
 
 #: kallithea/templates/admin/repo_groups/repo_groups.html:48
 msgid "Number of Top-level Repositories"
-msgstr ""
+msgstr "Anzahl der Repositories oberster Ebene"
 
 #: kallithea/templates/admin/repos/repo_add_base.html:14
 msgid "Import existing repository ?"
-msgstr ""
+msgstr "Bestehendes Repository importieren?"
 
 #: kallithea/templates/admin/repos/repo_add_base.html:23
 #: kallithea/templates/summary/summary.html:29
@@ -3343,15 +3375,16 @@
 msgstr "Clone von"
 
 #: kallithea/templates/admin/repos/repo_add_base.html:27
-#, fuzzy
 msgid "Optional URL from which repository should be cloned."
-msgstr "Optionale http[s] URL von diesem das Repository geclont werden soll."
+msgstr "Optionale http[s] URL, von welcher das Repository geclont werden soll."
 
 #: kallithea/templates/admin/repos/repo_add_base.html:36
 #: kallithea/templates/admin/repos/repo_edit_settings.html:76
 #: kallithea/templates/forks/fork.html:42
 msgid "Keep it short and to the point. Use a README file for longer descriptions."
 msgstr ""
+"Halten Sie es kurz und prägnant. Benutzen Sie eine README-Datei für längere "
+"Beschreibungen."
 
 #: kallithea/templates/admin/repos/repo_add_base.html:45
 #: kallithea/templates/admin/repos/repo_edit_settings.html:46
@@ -3376,9 +3409,9 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_creating.html:9
-#, fuzzy, python-format
+#, python-format
 msgid "%s Creating Repository"
-msgstr "Fehler beim Erstellen des Repositoriums %s"
+msgstr "%s Erstelle Repository"
 
 #: kallithea/templates/admin/repos/repo_creating.html:13
 msgid "Creating repository"
@@ -3398,9 +3431,9 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit.html:8
-#, fuzzy, python-format
+#, python-format
 msgid "%s Repository Settings"
-msgstr ""
+msgstr "%s Repositoryeinstellungen"
 
 #: kallithea/templates/admin/repos/repo_edit.html:49
 msgid "Extra Fields"
@@ -3423,7 +3456,7 @@
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:1
 msgid "Parent"
-msgstr ""
+msgstr "Übergeordnet"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:5
 #: kallithea/templates/admin/repos/repo_edit_fork.html:5
@@ -3436,55 +3469,48 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:22
-#, fuzzy
 msgid "Public Journal Visibility"
-msgstr "Sichtbarkeit des Öffentlichen Logbuches"
+msgstr "Sichtbarkeit des öffentlichen Logbuches"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:30
 msgid "Remove from public journal"
 msgstr "Entferne aus dem Öffentlichen Logbuch"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:35
-#, fuzzy
 msgid "Add to Public Journal"
-msgstr "Zum Öffentlichen Logbuch hinzufügen"
+msgstr "Zum öffentlichen Logbuch hinzufügen"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:41
-#, fuzzy
 msgid ""
 "All actions done in this repository will be visible to everyone in the "
 "public journal."
 msgstr ""
-"Alle Aktionen die in diesem Repository durchgeführt wurden sind für jeden"
-" Zugänglich im Öffentlichen Logbuch"
+"Alle Aktionen, die in diesem Repository ausgeführt wurden, sind im "
+"öffentlichen Logbuch für jeden einsehbar."
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:47
 msgid "Change Locking"
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:53
-#, fuzzy
 msgid "Confirm to unlock repository."
-msgstr "Entsperrtes Repositorium"
+msgstr "Entsperren des Repositorys bestätigen."
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:55
-#, fuzzy
 msgid "Unlock Repository"
-msgstr "Entsperrtes Repositorium"
+msgstr "Repository entsperren"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:61
-#, fuzzy
 msgid "Confirm to lock repository."
-msgstr "Entsperrtes Repositorium"
+msgstr "Sperren des Repositorys bestätigen."
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:63
-#, fuzzy
 msgid "Lock Repository"
-msgstr "Entsperrtes Repositorium"
+msgstr "Repository sperren"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:65
 msgid "Repository is not locked"
-msgstr ""
+msgstr "Repository ist nicht gesperrt"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:69
 msgid ""
@@ -3498,27 +3524,26 @@
 #: kallithea/templates/data_table/_dt_elements.html:132
 #, python-format
 msgid "Confirm to delete this repository: %s"
-msgstr ""
+msgstr "Löschen des Repositorys bestätigen: %s"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:82
-#, fuzzy
 msgid "Delete this Repository"
 msgstr "Dieses Repository löschen"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:85
-#, fuzzy, python-format
+#, python-format
 msgid "This repository has %s fork"
 msgid_plural "This repository has %s forks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Dieses Repository hat %s Fork"
+msgstr[1] "Dieses Repository hat %s Forks"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:86
 msgid "Detach forks"
-msgstr ""
+msgstr "Fork abtrennen"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:87
 msgid "Delete forks"
-msgstr ""
+msgstr "Forks löschen"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:91
 msgid ""
@@ -3528,9 +3553,8 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit_caches.html:4
-#, fuzzy
 msgid "Invalidate Repository Cache"
-msgstr "privates Repository"
+msgstr "Ungültiger Repositorycache"
 
 #: kallithea/templates/admin/repos/repo_edit_caches.html:4
 msgid "Confirm to invalidate repository cache."
@@ -3572,7 +3596,7 @@
 #: kallithea/templates/admin/repos/repo_edit_fields.html:19
 #, python-format
 msgid "Confirm to delete this field: %s"
-msgstr ""
+msgstr "Löschen des Felds bestätigen: %s"
 
 #: kallithea/templates/admin/repos/repo_edit_fields.html:33
 msgid "New field key"
@@ -3595,23 +3619,20 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit_fields.html:66
-#, fuzzy
 msgid "Extra fields are disabled."
-msgstr "Avatare sind deaktiviert"
+msgstr "Zusatzfelder sind deaktiviert."
 
 #: kallithea/templates/admin/repos/repo_edit_permissions.html:21
 msgid "private repository"
 msgstr "privates Repository"
 
 #: kallithea/templates/admin/repos/repo_edit_remote.html:3
-#, fuzzy
 msgid "Remote URL"
-msgstr "Entfernt"
+msgstr "Remote URL"
 
 #: kallithea/templates/admin/repos/repo_edit_remote.html:8
-#, fuzzy
 msgid "Pull Changes from Remote Location"
-msgstr "Von entferntem Ort übertragen"
+msgstr "Änderungen von entferntem Ort übertragen"
 
 #: kallithea/templates/admin/repos/repo_edit_remote.html:8
 msgid "Confirm to pull changes from remote side."
@@ -3645,9 +3666,8 @@
 
 #: kallithea/templates/admin/repos/repo_edit_settings.html:21
 #: kallithea/templates/summary/summary.html:72
-#, fuzzy
 msgid "Clone URL"
-msgstr "ungültige Clone Adresse"
+msgstr "Clone-URL"
 
 #: kallithea/templates/admin/repos/repo_edit_settings.html:27
 #: kallithea/templates/base/perms_summary.html:43
@@ -3676,7 +3696,7 @@
 
 #: kallithea/templates/admin/repos/repo_edit_settings.html:65
 msgid "Change owner of this repository."
-msgstr ""
+msgstr "Besitzer des Repositorys ändern."
 
 #: kallithea/templates/admin/repos/repo_edit_statistics.html:6
 msgid "Processed commits"
@@ -3687,7 +3707,6 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit_statistics.html:10
-#, fuzzy
 msgid "Reset Statistics"
 msgstr "Statistiken zurücksetzen"
 
@@ -3696,22 +3715,20 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repos.html:5
-#, fuzzy
 msgid "Repositories Administration"
-msgstr "Benutzerverwaltung"
+msgstr "Repositoryverwaltung"
 
 #: kallithea/templates/admin/repos/repos.html:51
 msgid "State"
 msgstr ""
 
 #: kallithea/templates/admin/settings/settings.html:5
-#, fuzzy
 msgid "Settings Administration"
-msgstr "Benutzerverwaltung"
+msgstr "Einstellungsverwaltung"
 
 #: kallithea/templates/admin/settings/settings.html:27
 msgid "VCS"
-msgstr ""
+msgstr "VCS"
 
 #: kallithea/templates/admin/settings/settings.html:28
 msgid "Remap and Rescan"
@@ -3727,7 +3744,6 @@
 msgstr "Hooks"
 
 #: kallithea/templates/admin/settings/settings.html:33
-#, fuzzy
 msgid "Full Text Search"
 msgstr "Volltextsuche"
 
@@ -3830,7 +3846,6 @@
 #: kallithea/templates/admin/settings/settings_global.html:56
 #: kallithea/templates/admin/settings/settings_vcs.html:80
 #: kallithea/templates/admin/settings/settings_visual.html:116
-#, fuzzy
 msgid "Save Settings"
 msgstr "Einstellungen speichern"
 
@@ -3923,9 +3938,8 @@
 msgstr "Plattform"
 
 #: kallithea/templates/admin/settings/settings_system.html:7
-#, fuzzy
 msgid "Git version"
-msgstr "Python-Version"
+msgstr "Git-Version"
 
 #: kallithea/templates/admin/settings/settings_system.html:8
 msgid "Git path"
@@ -3936,9 +3950,9 @@
 msgstr ""
 
 #: kallithea/templates/admin/settings/settings_system.html:9
-#, fuzzy
 msgid "Note: please make sure this server can access this URL"
-msgstr "Hinweis: Bitte stelle sicher, dass der Server auf die URL zugreifen kann"
+msgstr ""
+"Hinweis: Bitte stellen Sie sicher, dass der Server auf die URL zugreifen kann"
 
 #: kallithea/templates/admin/settings/settings_system.html:14
 msgid "Checking for updates..."
@@ -3979,7 +3993,6 @@
 msgstr ""
 
 #: kallithea/templates/admin/settings/settings_vcs.html:42
-#, fuzzy
 msgid "Mercurial extensions"
 msgstr "Mercurial-Erweiterungen"
 
@@ -3998,9 +4011,8 @@
 msgstr ""
 
 #: kallithea/templates/admin/settings/settings_vcs.html:64
-#, fuzzy
 msgid "Location of repositories"
-msgstr "Repositories"
+msgstr "Ort der Repositories"
 
 #: kallithea/templates/admin/settings/settings_vcs.html:69
 msgid ""
@@ -4187,7 +4199,6 @@
 msgstr "Verfügbare Mitglieder"
 
 #: kallithea/templates/admin/user_groups/user_groups.html:5
-#, fuzzy
 msgid "User Groups Administration"
 msgstr "Benutzergruppenverwaltung"
 
@@ -4221,9 +4232,8 @@
 msgstr ""
 
 #: kallithea/templates/admin/users/user_edit.html:32
-#, fuzzy
 msgid "Default Permissions"
-msgstr "Standart Rechte"
+msgstr "Standardrechte"
 
 #: kallithea/templates/admin/users/user_edit.html:33
 msgid "Emails"
@@ -4287,12 +4297,10 @@
 msgstr ""
 
 #: kallithea/templates/admin/users/users.html:5
-#, fuzzy
 msgid "Users Administration"
 msgstr "Benutzerverwaltung"
 
 #: kallithea/templates/admin/users/users.html:56
-#, fuzzy
 msgid "Auth Type"
 msgstr "Authentifizierungsart"
 
@@ -4306,9 +4314,8 @@
 msgstr "Support"
 
 #: kallithea/templates/base/base.html:122
-#, fuzzy
 msgid "Create Fork"
-msgstr "[erstellt] Benutzer"
+msgstr "Fork erstellen"
 
 #: kallithea/templates/base/base.html:133
 #: kallithea/templates/data_table/_dt_elements.html:11
@@ -4343,9 +4350,8 @@
 
 #: kallithea/templates/base/base.html:158
 #: kallithea/templates/forks/forks_data.html:21
-#, fuzzy
 msgid "Compare Fork"
-msgstr "vergleichsansicht"
+msgstr "Fork vergleichen"
 
 #: kallithea/templates/base/base.html:160
 #: kallithea/templates/bookmarks/bookmarks.html:56
@@ -4440,14 +4446,12 @@
 #: kallithea/templates/base/base.html:273
 #: kallithea/templates/pullrequests/pullrequest_show_my.html:4
 #: kallithea/templates/pullrequests/pullrequest_show_my.html:8
-#, fuzzy
 msgid "My Pull Requests"
-msgstr "Pull Request"
+msgstr "Meine Pull Requests"
 
 #: kallithea/templates/base/base.html:292
-#, fuzzy
 msgid "Not Logged In"
-msgstr "Letzter Login"
+msgstr "Nicht eingeloggt"
 
 #: kallithea/templates/base/base.html:299
 msgid "Login to Your Account"
@@ -4531,9 +4535,8 @@
 msgstr ""
 
 #: kallithea/templates/base/root.html:22
-#, fuzzy
 msgid "Add Another Comment"
-msgstr "%d Kommentar"
+msgstr "Einen weiteren Kommentar hinzufügen"
 
 #: kallithea/templates/base/root.html:23
 #: kallithea/templates/data_table/_dt_elements.html:216
@@ -4570,9 +4573,8 @@
 
 #: kallithea/templates/base/root.html:31
 #: kallithea/templates/pullrequests/pullrequest_show_all.html:30
-#, fuzzy
 msgid "Open New Pull Request"
-msgstr "Es wurde erfolgreich ein neuer Pullrequest eröffnet"
+msgstr "Einen neuen Pull Request eröffnen"
 
 #: kallithea/templates/base/root.html:32
 msgid "Open New Pull Request for Selected Changesets"
@@ -4583,9 +4585,8 @@
 msgstr ""
 
 #: kallithea/templates/base/root.html:34
-#, fuzzy
 msgid "Show Selected Changeset __S"
-msgstr "Änderungssätze auswählen"
+msgstr "Ausgewähltes Changeset anzeigen __S"
 
 #: kallithea/templates/base/root.html:35
 msgid "Selection Link"
@@ -4605,14 +4606,12 @@
 msgstr ""
 
 #: kallithea/templates/base/root.html:39
-#, fuzzy
 msgid "Confirm to revoke permission for {0}: {1} ?"
-msgstr "Als Administrator kann man sich keine Berechtigungen entziehen"
+msgstr "Widerruf der Rechte für {0}: {1} bestätigen?"
 
 #: kallithea/templates/base/root.html:43
-#, fuzzy
 msgid "Specify changeset"
-msgstr "Änderungssätze auswählen"
+msgstr "Changeset angeben"
 
 #: kallithea/templates/bookmarks/bookmarks.html:5
 #, python-format
@@ -4676,9 +4675,8 @@
 msgstr ""
 
 #: kallithea/templates/changelog/changelog.html:55
-#, fuzzy
 msgid "Go to tip of repository"
-msgstr "Git Repository"
+msgstr "Gehe zum Tip des Repositorys"
 
 #: kallithea/templates/changelog/changelog.html:60
 #: kallithea/templates/forks/forks_data.html:19
@@ -4887,20 +4885,17 @@
 msgstr ""
 
 #: kallithea/templates/changeset/changeset_file_comment.html:24
-#, fuzzy
 msgid "Status change from pull request"
-msgstr "Statusänderung -> %s"
+msgstr "Statusänderung durch Pull Request"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:25
 #: kallithea/templates/changeset/changeset_file_comment.html:28
-#, fuzzy
 msgid "No title"
-msgstr "neue Datei"
+msgstr "Kein Titel"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:27
-#, fuzzy
 msgid "Comment from pull request"
-msgstr "[geschlossen] Pull Request für"
+msgstr "Kommentar von Pull Request"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:32
 msgid "Status change on changeset"
@@ -4911,9 +4906,8 @@
 msgstr ""
 
 #: kallithea/templates/changeset/changeset_file_comment.html:50
-#, fuzzy
 msgid "Delete comment?"
-msgstr "%d Kommentar"
+msgstr "Kommentar löschen?"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:67
 msgid "Commenting on line {1}."
@@ -4968,18 +4962,18 @@
 msgstr[1] "%d Kommentare"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:115
-#, fuzzy, python-format
+#, python-format
 msgid "%d inline"
 msgid_plural "%d inline"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d inline"
+msgstr[1] "%d inline"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:116
-#, fuzzy, python-format
+#, python-format
 msgid "%d general"
 msgid_plural "%d general"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d generell"
+msgstr[1] "%d generell"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:165
 msgid "Use @username inside this text to send notification to another local user."
@@ -4990,19 +4984,16 @@
 msgstr ""
 
 #: kallithea/templates/changeset/changeset_file_comment.html:174
-#, fuzzy
 msgid "Set changeset status"
-msgstr "Änderungssätze auswählen"
+msgstr "Setze Changesetstatus"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:178
-#, fuzzy
 msgid "No change"
 msgstr "Keine Änderungen"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:191
-#, fuzzy
 msgid "Close"
-msgstr "(geschlossen)"
+msgstr "Schließen"
 
 #: kallithea/templates/changeset/changeset_range.html:5
 #, python-format
@@ -5029,14 +5020,12 @@
 msgstr ""
 
 #: kallithea/templates/changeset/diff_block.html:87
-#, fuzzy
 msgid "Deleted"
-msgstr "löschen"
+msgstr "Gelöscht"
 
 #: kallithea/templates/changeset/diff_block.html:90
-#, fuzzy
 msgid "Renamed"
-msgstr "umbenennen"
+msgstr "Umbenannt"
 
 #: kallithea/templates/compare/compare_cs.html:4
 msgid "No changesets"
@@ -5064,14 +5053,13 @@
 msgstr ""
 
 #: kallithea/templates/compare/compare_cs.html:84
-#, fuzzy, python-format
+#, python-format
 msgid "%s changesets"
-msgstr ""
+msgstr "%s Changesets"
 
 #: kallithea/templates/compare/compare_cs.html:85
-#, fuzzy
 msgid "behind"
-msgstr "Erneut Indizieren"
+msgstr "zurück"
 
 #: kallithea/templates/compare/compare_diff.html:6
 #: kallithea/templates/compare/compare_diff.html:8
@@ -5268,9 +5256,8 @@
 #: kallithea/templates/files/files_add.html:64
 #: kallithea/templates/files/files_delete.html:43
 #: kallithea/templates/files/files_edit.html:67
-#, fuzzy
 msgid "Commit Changes"
-msgstr "Keine Änderungen"
+msgstr "Änderungen einchecken"
 
 #: kallithea/templates/files/files_browser.html:32
 msgid "revision"
@@ -5309,7 +5296,6 @@
 msgstr ""
 
 #: kallithea/templates/files/files_browser.html:64
-#, fuzzy
 msgid "Last Modified"
 msgstr "Zuletzt geändert"
 
@@ -5499,9 +5485,8 @@
 msgstr "RSS Logbuch Feed"
 
 #: kallithea/templates/journal/journal.html:56
-#, fuzzy
 msgid "My Repos"
-msgstr "Leeres Repository"
+msgstr "Meine Repositories"
 
 #: kallithea/templates/journal/journal_data.html:61
 msgid "No entries yet"
@@ -5522,9 +5507,8 @@
 
 #: kallithea/templates/pullrequests/pullrequest.html:4
 #: kallithea/templates/pullrequests/pullrequest.html:8
-#, fuzzy
 msgid "New Pull Request"
-msgstr "Pull Request"
+msgstr "Neuer Pull Request"
 
 #: kallithea/templates/pullrequests/pullrequest.html:31
 #: kallithea/templates/pullrequests/pullrequest_data.html:15
@@ -5556,9 +5540,8 @@
 
 #: kallithea/templates/pullrequests/pullrequest.html:97
 #: kallithea/templates/pullrequests/pullrequest_show.html:210
-#, fuzzy
 msgid "Pull Request Reviewers"
-msgstr "Pull Request"
+msgstr "Pull Request Reviewers"
 
 #: kallithea/templates/pullrequests/pullrequest.html:107
 #: kallithea/templates/pullrequests/pullrequest_show.html:239
@@ -5578,9 +5561,9 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_data.html:27
-#, fuzzy, python-format
+#, python-format
 msgid "Latest vote: %s"
-msgstr "Tag %s erstellt"
+msgstr "Letzte Stimmabgabe: %s"
 
 #: kallithea/templates/pullrequests/pullrequest_data.html:29
 msgid "Nobody voted"
@@ -5596,9 +5579,8 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_data.html:45
-#, fuzzy
 msgid "Delete Pull Request"
-msgstr "Erfolgreich Pull-Request gelöscht"
+msgstr "Pull Request löschen"
 
 #: kallithea/templates/pullrequests/pullrequest_data.html:46
 msgid "Confirm to delete this pull request"
@@ -5620,14 +5602,13 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:10
-#, fuzzy, python-format
+#, python-format
 msgid "Pull request #%s from %s#%s"
-msgstr ""
+msgstr "Pull Request #%s von %s#%s"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:57
-#, fuzzy
 msgid "Summarize the changes"
-msgstr "Letzte Änderungen"
+msgstr "Zusammenfassung der Änderungen"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:74
 msgid "Reviewer voting result"
@@ -5654,18 +5635,16 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:102
-#, fuzzy
 msgid "There are no reviewers"
-msgstr "Es gibt bisher keine Branches"
+msgstr "Es gibt keine Reviewers"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:108
 msgid "Origin"
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:114
-#, fuzzy
 msgid "on"
-msgstr "keine"
+msgstr "in"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:121
 msgid "Target"
@@ -5676,14 +5655,12 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:155
-#, fuzzy
 msgid "Created by"
-msgstr "[erstellt] Benutzer"
+msgstr "Erstellt von"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:170
-#, fuzzy
 msgid "Update"
-msgstr "[akutalisiert] Benutzer"
+msgstr "Aktualisierung"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:188
 msgid "Current revision - no change"
@@ -5698,14 +5675,12 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:227
-#, fuzzy
 msgid "Remove reviewer"
-msgstr ""
+msgstr "Reviewer entfernen"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:247
-#, fuzzy
 msgid "Potential Reviewers"
-msgstr "Kommentarvorschau"
+msgstr "Potentielle Reviewer"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:250
 msgid "Click to add the repository owner as reviewer:"
@@ -5716,19 +5691,16 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:274
-#, fuzzy
 msgid "Save as New Pull Request"
-msgstr "Es wurde erfolgreich ein neuer Pullrequest eröffnet"
+msgstr "Als neuen Pull Request speichern"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:275
-#, fuzzy
 msgid "Cancel Changes"
-msgstr "Letzte Änderungen"
+msgstr "Änderungen verwerfen"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:285
-#, fuzzy
 msgid "Pull Request Content"
-msgstr "Pull Request"
+msgstr "Inhalt des Pull Requests"
 
 #: kallithea/templates/pullrequests/pullrequest_show_all.html:4
 #, python-format
@@ -5736,24 +5708,24 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show_all.html:9
-#, fuzzy, python-format
+#, python-format
 msgid "Pull Requests from %s'"
-msgstr ""
+msgstr "Pull Requests von '%s'"
 
 #: kallithea/templates/pullrequests/pullrequest_show_all.html:11
-#, fuzzy, python-format
+#, python-format
 msgid "Pull Requests to '%s'"
-msgstr ""
+msgstr "Pull Requests für '%s'"
 
 #: kallithea/templates/pullrequests/pullrequest_show_all.html:35
-#, fuzzy, python-format
+#, python-format
 msgid "Show Pull Requests to %s"
-msgstr ""
+msgstr "Zeige Pull Requests für '%s'"
 
 #: kallithea/templates/pullrequests/pullrequest_show_all.html:37
-#, fuzzy, python-format
+#, python-format
 msgid "Show Pull Requests from '%s'"
-msgstr ""
+msgstr "Zeige Pull Requests von '%s'"
 
 #: kallithea/templates/pullrequests/pullrequest_show_all.html:47
 #: kallithea/templates/pullrequests/pullrequest_show_my.html:26
@@ -5766,9 +5738,8 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show_my_data.html:3
-#, fuzzy
 msgid "Pull Requests Created by Me"
-msgstr "Pull Request"
+msgstr "Von mir erstellte Pull Requests"
 
 #: kallithea/templates/pullrequests/pullrequest_show_my_data.html:6
 msgid "Pull Requests I Participate In"
@@ -5781,9 +5752,8 @@
 
 #: kallithea/templates/search/search.html:8
 #: kallithea/templates/search/search.html:16
-#, fuzzy
 msgid "Search in All Repositories"
-msgstr "Mercurial Repository"
+msgstr "Suche in allen Repositories"
 
 #: kallithea/templates/search/search.html:50
 msgid "Search term"
@@ -5944,14 +5914,12 @@
 msgstr ""
 
 #: kallithea/templates/summary/summary.html:189
-#, fuzzy
 msgid "Latest Changes"
 msgstr "Letzte Änderungen"
 
 #: kallithea/templates/summary/summary.html:191
-#, fuzzy
 msgid "Quick Start"
-msgstr "Schnellfilter..."
+msgstr "Schnelleinstieg"
 
 #: kallithea/templates/summary/summary.html:205
 #, python-format
@@ -5969,6 +5937,5 @@
 msgstr "%s Tags"
 
 #: kallithea/templates/tags/tags.html:26
-#, fuzzy
 msgid "Compare Tags"
-msgstr "vergleichsansicht"
+msgstr "Tags vergleichen"
--- a/kallithea/i18n/fr/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/fr/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -8,8 +8,8 @@
 "Project-Id-Version: Kallithea\n"
 "Report-Msgid-Bugs-To: translations@kallithea-scm.org\n"
 "POT-Creation-Date: 2015-04-01 03:17+0200\n"
-"PO-Revision-Date: 2015-03-08 23:31+0200\n"
-"Last-Translator: Tuux <tuxa@galaxie.eu.org>\n"
+"PO-Revision-Date: 2015-05-11 23:05+0200\n"
+"Last-Translator: David Avigni <david.avigni@ankapi.com>\n"
 "Language-Team: French "
 "<https://hosted.weblate.org/projects/kallithea/kallithea/fr/>\n"
 "Language: fr\n"
@@ -17,6 +17,7 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 2.3-dev\n"
 
 #: kallithea/controllers/changelog.py:86
 #: kallithea/controllers/pullrequests.py:247 kallithea/lib/base.py:449
@@ -56,15 +57,16 @@
 
 #: kallithea/controllers/changeset.py:352
 #: kallithea/controllers/pullrequests.py:699
-#, fuzzy
 msgid "No comments."
-msgstr "%d commentaire"
+msgstr "Aucun commentaire."
 
 #: kallithea/controllers/changeset.py:382
 msgid ""
 "Changing status on a changeset associated with a closed pull request is "
 "not allowed"
 msgstr ""
+"La modification de l'état sur un ensemble de modifications associé à une "
+"demande de tirage fermé n'est pas autorisé"
 
 #: kallithea/controllers/compare.py:158 kallithea/templates/base/root.html:42
 msgid "Select changeset"
@@ -82,7 +84,7 @@
 
 #: kallithea/controllers/error.py:99
 msgid "Unauthorized access to resource"
-msgstr "Accès interdit à cet ressource"
+msgstr "Accès interdit à cette ressource"
 
 #: kallithea/controllers/error.py:101
 msgid "You don't have permission to view this page"
@@ -135,15 +137,15 @@
 msgstr "Il n'y a actuellement pas de fichiers. %s"
 
 #: kallithea/controllers/files.py:194
-#, fuzzy, python-format
+#, python-format
 msgid "%s at %s"
-msgstr "dans %s et %s"
+msgstr "%s à %s"
 
 #: kallithea/controllers/files.py:306 kallithea/controllers/files.py:366
 #: kallithea/controllers/files.py:433
 #, python-format
 msgid "This repository has been locked by %s on %s"
-msgstr "Ce dépôt a été verrouillé par %s sur %s."
+msgstr "Ce dépôt a été verrouillé par %s sur %s"
 
 #: kallithea/controllers/files.py:318
 msgid "You can only delete files with revision being a valid branch "
@@ -306,9 +308,9 @@
 "été envoyé par e-mail"
 
 #: kallithea/controllers/pullrequests.py:130
-#, fuzzy, python-format
+#, python-format
 msgid "%s (closed)"
-msgstr ""
+msgstr "%s (fermé)"
 
 #: kallithea/controllers/pullrequests.py:158
 #: kallithea/templates/changeset/changeset.html:12
@@ -337,9 +339,8 @@
 
 #: kallithea/controllers/pullrequests.py:356
 #: kallithea/controllers/pullrequests.py:497
-#, fuzzy
 msgid "No description"
-msgstr "Description"
+msgstr "Aucune description"
 
 #: kallithea/controllers/pullrequests.py:363
 msgid "Successfully opened new pull request"
@@ -347,18 +348,17 @@
 
 #: kallithea/controllers/pullrequests.py:366
 #: kallithea/controllers/pullrequests.py:450
-#, fuzzy
 msgid "Error occurred while creating pull request"
-msgstr "Une erreur est survenue durant l’envoi de la requête de pull"
+msgstr "Une erreur est survenue durant la création de la pull request"
 
 #: kallithea/controllers/pullrequests.py:398
 msgid "Missing changesets since the previous pull request:"
-msgstr ""
+msgstr "Changeset manquant depuis la précédente pull request :"
 
 #: kallithea/controllers/pullrequests.py:405
 #, python-format
 msgid "New changesets on %s %s since the previous pull request:"
-msgstr ""
+msgstr "Nouveau changeset sur %s %s depuis la précédente pull request :"
 
 #: kallithea/controllers/pullrequests.py:412
 msgid "Ancestor didn't change - show diff since previous version:"
@@ -374,22 +374,20 @@
 #: kallithea/controllers/pullrequests.py:421
 #, python-format
 msgid "No changes found on %s %s since previous version."
-msgstr ""
+msgstr "Aucun changement constaté sur %s %s depuis la version précédente."
 
 #: kallithea/controllers/pullrequests.py:456
 #, python-format
 msgid "Closed, replaced by %s ."
-msgstr ""
+msgstr "Fermé, remplacé par %s."
 
 #: kallithea/controllers/pullrequests.py:464
-#, fuzzy
 msgid "Pull request update created"
-msgstr "Relecteurs de la requête de pull"
+msgstr "Mise à jour de la pull request créée"
 
 #: kallithea/controllers/pullrequests.py:503
-#, fuzzy
 msgid "Pull request updated"
-msgstr "Requêtes de pull"
+msgstr "Pull request mise à jour"
 
 #: kallithea/controllers/pullrequests.py:518
 msgid "Successfully deleted pull request"
@@ -398,11 +396,11 @@
 #: kallithea/controllers/pullrequests.py:577
 #, python-format
 msgid "This pull request has already been merged to %s."
-msgstr ""
+msgstr "Cette pull request a déjà été fusionnée à %s."
 
 #: kallithea/controllers/pullrequests.py:579
 msgid "This pull request has been closed and can not be updated."
-msgstr ""
+msgstr "Cette pull request a été fermée et ne peut pas être mise à jour."
 
 #: kallithea/controllers/pullrequests.py:597
 #, python-format
@@ -423,9 +421,8 @@
 msgstr ""
 
 #: kallithea/controllers/pullrequests.py:701
-#, fuzzy
 msgid "Closing."
-msgstr "en utilisant l’adresse"
+msgstr "Fermeture."
 
 #: kallithea/controllers/search.py:135
 msgid "Invalid search query. Try quoting it."
@@ -438,13 +435,11 @@
 "code Whoosh"
 
 #: kallithea/controllers/search.py:144
-#, fuzzy
 msgid "An error occurred during search operation."
-msgstr "Une erreur est survenue durant l’opération de recherche"
+msgstr "Une erreur est survenue pendant la recherche."
 
 #: kallithea/controllers/summary.py:199
 #: kallithea/templates/summary/summary.html:387
-#, fuzzy
 msgid "No data ready yet"
 msgstr "Aucune donnée actuellement disponible"
 
@@ -907,9 +902,9 @@
 "l'application"
 
 #: kallithea/controllers/admin/settings.py:213
-#, fuzzy, python-format
+#, python-format
 msgid "Repositories successfully rescanned. Added: %s. Removed: %s."
-msgstr "Dépôts ré-analysés avec succès ajouté : %s ; supprimé : %s"
+msgstr "Dépôts ré-analysés avec succès. Ajouté : %s. Supprimé : %s."
 
 #: kallithea/controllers/admin/settings.py:270
 msgid "Updated application settings"
@@ -1030,7 +1025,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr "L'adresse IP %s a été ajoutée à la liste blanche"
 
 #: kallithea/controllers/admin/users.py:488
@@ -1038,7 +1033,7 @@
 msgstr "Une erreur est survenue durant la sauvegarde d'IP"
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr "L'adresse IP a été supprimée de la liste blanche"
 
 #: kallithea/lib/auth.py:745
@@ -1808,9 +1803,9 @@
 msgstr ""
 
 #: kallithea/model/notification.py:299
-#, fuzzy, python-format
+#, python-format
 msgid "New user %(new_username)s registered"
-msgstr "Le nom d’utilisateur « %(new_username)s » n’est pas valide"
+msgstr "Nouvel utilisateur %(new_username)s enregistré"
 
 #: kallithea/model/notification.py:301
 #, python-format
@@ -1827,9 +1822,8 @@
 msgstr ""
 
 #: kallithea/model/notification.py:315
-#, fuzzy
 msgid "Closing"
-msgstr "en utilisant l’adresse"
+msgstr "Fermeture"
 
 #: kallithea/model/pull_request.py:132
 #, python-format
@@ -1859,22 +1853,22 @@
 "bon fonctionnement de l’application"
 
 #: kallithea/model/user.py:261
-#, fuzzy, python-format
+#, python-format
 msgid ""
 "User \"%s\" still owns %s repositories and cannot be removed. Switch "
 "owners or remove those repositories: %s"
 msgstr ""
-"L’utilisateur « %s » possède %s dépôts et ne peut être supprimé. Changez "
-"les propriétaires de ces dépôts. %s"
+"L’utilisateur \"%s\" possède %s dépôts et ne peut être supprimé. Changez les "
+"propriétaires ou supprimez ces dépôts : %s"
 
 #: kallithea/model/user.py:268
-#, fuzzy, python-format
+#, python-format
 msgid ""
 "User \"%s\" still owns %s repository groups and cannot be removed. Switch"
 " owners or remove those repository groups: %s"
 msgstr ""
-"L’utilisateur « %s » possède %s dépôts et ne peut être supprimé. Changez "
-"les propriétaires de ces dépôts. %s"
+"L’utilisateur \"%s\" possède %s groupes de dépôt et ne peut être supprimé. "
+"Changez les propriétaires ou supprimez ces dépôts : %s"
 
 #: kallithea/model/user.py:275
 #, fuzzy, python-format
@@ -2007,16 +2001,14 @@
 msgstr "Un groupe de dépôts avec le nom « %(repo)s » existe déjà"
 
 #: kallithea/model/validators.py:474
-#, fuzzy
 msgid "invalid clone URL"
 msgstr "URL de clonage invalide"
 
 #: kallithea/model/validators.py:475
-#, fuzzy
 msgid "Invalid clone URL, provide a valid clone http(s)/svn+http(s)/ssh URL"
 msgstr ""
-"URL à cloner invalide. Veuillez fournir une URL valide en http(s) ou "
-"svn+http(s)"
+"URL à cloner invalide, veuillez fournir une URL à cloner valide "
+"http(s)/svn+http(s)/ssh"
 
 #: kallithea/model/validators.py:500
 msgid "Fork has to be the same type as parent"
@@ -2067,7 +2059,7 @@
 "statuts définis"
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr "Veuillez entrer une adresse IPv4 ou IPv6 valide"
 
 #: kallithea/model/validators.py:818
@@ -2316,14 +2308,13 @@
 msgstr "Remettre le mot de passe à zéro"
 
 #: kallithea/templates/password_reset.html:12
-#, fuzzy, python-format
+#, python-format
 msgid "Reset Your Password to %s"
-msgstr "Remettre votre mot de passe à %s"
+msgstr "Réinitialiser votre mot de passe à %s"
 
 #: kallithea/templates/password_reset.html:14
-#, fuzzy
 msgid "Reset Your Password"
-msgstr "Remettre votre mot de passe à zéro"
+msgstr "Réinitialiser votre mot de passe"
 
 #: kallithea/templates/password_reset.html:25
 msgid "Email Address"
@@ -2335,16 +2326,16 @@
 msgstr "Captcha"
 
 #: kallithea/templates/password_reset.html:46
-#, fuzzy
 msgid "Send Password Reset Email"
-msgstr "Envoyer le courriel de remise à zéro du mot de passe"
+msgstr "Envoyer l'E-mail de réinitialisation du mot de passe"
 
 #: kallithea/templates/password_reset.html:47
-#, fuzzy
 msgid ""
 "Password reset link will be sent to the email address matching your "
 "username."
-msgstr "Votre nouveau mot de passe sera envoyé à l’adresse correspondante"
+msgstr ""
+"Le lien de réinitialisation du mot de passe sera envoyé à l'adresse e-mail "
+"correspondant à votre nom d'utilisateur."
 
 #: kallithea/templates/register.html:5 kallithea/templates/register.html:14
 #: kallithea/templates/register.html:90
@@ -2414,7 +2405,6 @@
 #: kallithea/templates/admin/admin.html:5
 #: kallithea/templates/admin/admin.html:13
 #: kallithea/templates/base/base.html:59
-#, fuzzy
 msgid "Admin Journal"
 msgstr "Historique d’administration"
 
@@ -2424,13 +2414,12 @@
 
 #: kallithea/templates/admin/admin.html:12
 #: kallithea/templates/journal/journal.html:11
-#, fuzzy
 msgid "Filter"
-msgstr "filtre"
+msgstr "Filtre"
 
 #: kallithea/templates/admin/admin.html:13
 #: kallithea/templates/journal/journal.html:12
-#, fuzzy, python-format
+#, python-format
 msgid "%s Entry"
 msgid_plural "%s Entries"
 msgstr[0] "%s entrée"
@@ -2538,9 +2527,8 @@
 
 #: kallithea/templates/admin/defaults/defaults.html:5
 #: kallithea/templates/admin/defaults/defaults.html:25
-#, fuzzy
 msgid "Repository Defaults"
-msgstr "Réglages par défaut des dépôts"
+msgstr "Réglages par défaut du dépôt"
 
 #: kallithea/templates/admin/defaults/defaults.html:11
 #: kallithea/templates/base/base.html:66
@@ -2656,15 +2644,15 @@
 
 #: kallithea/templates/admin/gists/index.html:6
 #: kallithea/templates/admin/gists/index.html:16
-#, fuzzy, python-format
+#, python-format
 msgid "Private Gists for User %s"
 msgstr "Gists privés de l'utilisateur %s"
 
 #: kallithea/templates/admin/gists/index.html:8
 #: kallithea/templates/admin/gists/index.html:18
-#, fuzzy, python-format
+#, python-format
 msgid "Public Gists for User %s"
-msgstr "Gists publics de l'utilisateur %s"
+msgstr "Gists publiques de l'utilisateur %s"
 
 #: kallithea/templates/admin/gists/index.html:10
 #: kallithea/templates/admin/gists/index.html:20
@@ -2804,9 +2792,8 @@
 
 #: kallithea/templates/admin/my_account/my_account.html:37
 #: kallithea/templates/admin/users/user_edit.html:30
-#, fuzzy
 msgid "API Keys"
-msgstr "Nouvelle clé d'API"
+msgstr "Clés de l'API"
 
 #: kallithea/templates/admin/my_account/my_account.html:38
 msgid "My Emails"
@@ -2822,7 +2809,6 @@
 msgstr "Surveillé"
 
 #: kallithea/templates/admin/my_account/my_account.html:41
-#, fuzzy
 msgid "My Permissions"
 msgstr "Mes permissions"
 
@@ -2914,9 +2900,8 @@
 
 #: kallithea/templates/admin/my_account/my_account_emails.html:26
 #: kallithea/templates/admin/users/user_edit_emails.html:26
-#, fuzzy
 msgid "No additional emails specified."
-msgstr "Pas d'adresses courriel supplémentaires spécifiées"
+msgstr "Pas d'adresse email supplémentaires spécifiées."
 
 #: kallithea/templates/admin/my_account/my_account_emails.html:38
 #: kallithea/templates/admin/users/user_edit_emails.html:38
@@ -2924,7 +2909,6 @@
 msgstr "Nouvelle adrese"
 
 #: kallithea/templates/admin/my_account/my_account_password.html:1
-#, fuzzy
 msgid "Change Your Account Password"
 msgstr "Changer le mot de passe de votre compte"
 
@@ -2971,7 +2955,6 @@
 msgstr ""
 
 #: kallithea/templates/admin/my_account/my_account_repos.html:1
-#, fuzzy
 msgid "Repositories You Own"
 msgstr "Dépôts dont vous êtes le propriétaire"
 
@@ -2987,7 +2970,6 @@
 msgstr "Aucun élément n’a été trouvé."
 
 #: kallithea/templates/admin/my_account/my_account_watched.html:1
-#, fuzzy
 msgid "Repositories You are Watching"
 msgstr "Dépôts que vous surveillez"
 
@@ -3010,7 +2992,6 @@
 msgstr "Demandes de pull"
 
 #: kallithea/templates/admin/notifications/notifications.html:30
-#, fuzzy
 msgid "Mark All Read"
 msgstr "Tout marquer comme lu"
 
@@ -3020,9 +3001,8 @@
 
 #: kallithea/templates/admin/notifications/show_notification.html:5
 #: kallithea/templates/admin/notifications/show_notification.html:11
-#, fuzzy
 msgid "Show Notification"
-msgstr "Notification"
+msgstr "Montrer Notification"
 
 #: kallithea/templates/admin/notifications/show_notification.html:9
 #: kallithea/templates/base/base.html:345
@@ -3030,9 +3010,8 @@
 msgstr "Notifications"
 
 #: kallithea/templates/admin/permissions/permissions.html:5
-#, fuzzy
 msgid "Permissions Administration"
-msgstr "Gestion des permissions"
+msgstr "Administration des permissions"
 
 #: kallithea/templates/admin/permissions/permissions.html:11
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:42
@@ -3049,7 +3028,6 @@
 
 #: kallithea/templates/admin/permissions/permissions.html:29
 #: kallithea/templates/admin/users/user_edit.html:34
-#, fuzzy
 msgid "IP Whitelist"
 msgstr "Liste blanche d'adresses IP"
 
@@ -3159,7 +3137,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr "Nouvelle adresse IP"
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
@@ -6068,4 +6046,3 @@
 #, fuzzy
 msgid "Compare Tags"
 msgstr "vue de comparaison"
-
--- a/kallithea/i18n/hu/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/hu/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -8,14 +8,16 @@
 "Project-Id-Version: Kallithea\n"
 "Report-Msgid-Bugs-To: translations@kallithea-scm.org\n"
 "POT-Creation-Date: 2015-04-01 03:17+0200\n"
-"PO-Revision-Date: 2014-07-02 19:08-0400\n"
-"Last-Translator: Automatically generated\n"
-"Language-Team: none\n"
+"PO-Revision-Date: 2015-04-11 00:59+0200\n"
+"Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
+"Language-Team: Hungarian "
+"<https://hosted.weblate.org/projects/kallithea/kallithea/hu/>\n"
+"Language: hu\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Language: hu\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 2.3-dev\n"
 
 #: kallithea/controllers/changelog.py:86
 #: kallithea/controllers/pullrequests.py:247 kallithea/lib/base.py:449
@@ -55,9 +57,8 @@
 
 #: kallithea/controllers/changeset.py:352
 #: kallithea/controllers/pullrequests.py:699
-#, fuzzy
 msgid "No comments."
-msgstr ""
+msgstr "Nincsenek hozzászólások."
 
 #: kallithea/controllers/changeset.py:382
 msgid ""
@@ -996,7 +997,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -1004,7 +1005,7 @@
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -1997,7 +1998,7 @@
 msgstr ""
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr ""
 
 #: kallithea/model/validators.py:818
@@ -2351,11 +2352,11 @@
 
 #: kallithea/templates/admin/admin.html:13
 #: kallithea/templates/journal/journal.html:12
-#, fuzzy, python-format
+#, python-format
 msgid "%s Entry"
 msgid_plural "%s Entries"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%s bejegyzés"
+msgstr[1] "%s bejegyzés"
 
 #: kallithea/templates/admin/admin_log.html:6
 #: kallithea/templates/admin/my_account/my_account_repos.html:50
@@ -3058,7 +3059,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr ""
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
@@ -3246,9 +3247,8 @@
 msgstr ""
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:53
-#, fuzzy
 msgid "Confirm to delete this group"
-msgstr ""
+msgstr "A csoport törlésének megerősítése"
 
 #: kallithea/templates/admin/repo_groups/repo_group_show.html:4
 #, python-format
@@ -3335,9 +3335,9 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit.html:8
-#, fuzzy, python-format
+#, python-format
 msgid "%s Repository Settings"
-msgstr ""
+msgstr "%s tároló beállítások"
 
 #: kallithea/templates/admin/repos/repo_edit.html:49
 msgid "Extra Fields"
@@ -3429,16 +3429,15 @@
 msgstr ""
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:82
-#, fuzzy
 msgid "Delete this Repository"
-msgstr ""
+msgstr "Tároló törlése"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:85
-#, fuzzy, python-format
+#, python-format
 msgid "This repository has %s fork"
 msgid_plural "This repository has %s forks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Ennek a tárolónak %s elágazása van"
+msgstr[1] "Ennek a tárolónak %s elágazása van"
 
 #: kallithea/templates/admin/repos/repo_edit_advanced.html:86
 msgid "Detach forks"
@@ -4437,9 +4436,8 @@
 msgstr ""
 
 #: kallithea/templates/base/root.html:22
-#, fuzzy
 msgid "Add Another Comment"
-msgstr ""
+msgstr "Egy másik hozzászólás hozzáadása"
 
 #: kallithea/templates/base/root.html:23
 #: kallithea/templates/data_table/_dt_elements.html:216
@@ -4809,9 +4807,8 @@
 msgstr ""
 
 #: kallithea/templates/changeset/changeset_file_comment.html:50
-#, fuzzy
 msgid "Delete comment?"
-msgstr ""
+msgstr "Hozzászólás törlése?"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:67
 msgid "Commenting on line {1}."
@@ -4866,11 +4863,11 @@
 msgstr[1] ""
 
 #: kallithea/templates/changeset/changeset_file_comment.html:115
-#, fuzzy, python-format
+#, python-format
 msgid "%d inline"
 msgid_plural "%d inline"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d sorközi"
+msgstr[1] "%d sorközi"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:116
 #, python-format
@@ -4957,9 +4954,9 @@
 msgstr ""
 
 #: kallithea/templates/compare/compare_cs.html:84
-#, fuzzy, python-format
+#, python-format
 msgid "%s changesets"
-msgstr ""
+msgstr "%s módosításcsomag"
 
 #: kallithea/templates/compare/compare_cs.html:85
 msgid "behind"
@@ -5575,14 +5572,12 @@
 msgstr ""
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:227
-#, fuzzy
 msgid "Remove reviewer"
-msgstr ""
+msgstr "Átnéző eltávolítása"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:247
-#, fuzzy
 msgid "Potential Reviewers"
-msgstr ""
+msgstr "Lehetséges átnézők"
 
 #: kallithea/templates/pullrequests/pullrequest_show.html:250
 msgid "Click to add the repository owner as reviewer:"
@@ -5841,4 +5836,3 @@
 #: kallithea/templates/tags/tags.html:26
 msgid "Compare Tags"
 msgstr ""
-
--- a/kallithea/i18n/ja/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/ja/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -1009,7 +1009,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr "ユーザーホワイトリストにIP %s を追加しました"
 
 #: kallithea/controllers/admin/users.py:488
@@ -1017,7 +1017,7 @@
 msgstr "IPアドレスの保存中にエラーが発生しました"
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr "ユーザーホワイトリストからIPアドレスを削除しました"
 
 #: kallithea/lib/auth.py:745
@@ -2011,7 +2011,7 @@
 msgstr "リビジョン %(revs)s はすでにプルリクエストの一部かステータスが設定されています"
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr "有効なIPv4かIPv6のアドレスを入力してください"
 
 #: kallithea/model/validators.py:818
@@ -3092,7 +3092,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr "新しいIPアドレス"
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/kallithea.pot	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/kallithea.pot	Tue Jun 09 22:46:40 2015 +0200
@@ -983,7 +983,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -991,7 +991,7 @@
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -1963,7 +1963,7 @@
 msgstr ""
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr ""
 
 #: kallithea/model/validators.py:818
@@ -3001,7 +3001,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr ""
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/nl_BE/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/nl_BE/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -1000,7 +1000,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -1008,7 +1008,7 @@
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -2001,7 +2001,7 @@
 msgstr ""
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr ""
 
 #: kallithea/model/validators.py:818
@@ -3062,7 +3062,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr ""
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/pl/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/pl/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -1014,7 +1014,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr "Dodano ip %s do listy dozwolonych adresów użytkownia"
 
 #: kallithea/controllers/admin/users.py:488
@@ -1022,7 +1022,7 @@
 msgstr "Wystąpił błąd podczas zapisywania e-maila"
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr "Usunięto adres ip z listy dozwolonych adresów dla użytkownika"
 
 #: kallithea/lib/auth.py:745
@@ -2046,7 +2046,7 @@
 msgstr "Rewizja  %(revs)s jest już częścią  nowej gałęzi więc określ jego status"
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr "Proszę podać poprawny adres IPv4 lub IPv6"
 
 #: kallithea/model/validators.py:818
@@ -3138,7 +3138,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr "Nowy adres ip"
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -1010,7 +1010,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -1018,7 +1018,7 @@
 msgstr "Ocorreu um erro durante o salvamento do IP"
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -2038,7 +2038,7 @@
 "estado"
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr "Por favor, forneça um endereço válido IPv4 ou IPv6"
 
 #: kallithea/model/validators.py:818
@@ -3126,7 +3126,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr "Novo endereço IP"
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/ru/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/ru/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -12,18 +12,20 @@
 # SkryabinD <skryabind@gmail.com>, 2014
 # softforwinxp <softforwinxp@gmail.com>, 2013
 # zhmylove <zhmylove@narod.ru>, 2013
+# Andrew Shadura <andrew@shadura.me>, 2015
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: Kallithea\n"
 "Report-Msgid-Bugs-To: translations@kallithea-scm.org\n"
 "POT-Creation-Date: 2015-04-01 03:17+0200\n"
-"PO-Revision-Date: 2015-04-01 13:08+0200\n"
+"PO-Revision-Date: 2015-04-13 20:18+0200\n"
 "Last-Translator: Andrew Shadura <andrew@shadura.me>\n"
 "Language-Team: Russian "
 "<https://hosted.weblate.org/projects/kallithea/kallithea/ru/>\n"
 "Language: ru\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<="
 "4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
@@ -84,7 +86,7 @@
 
 #: kallithea/controllers/compare.py:255
 msgid "Cannot compare repositories without using common ancestor"
-msgstr ""
+msgstr "Невозможно сравнивать репозитории без общего предка"
 
 #: kallithea/controllers/error.py:96
 msgid "The request could not be understood by the server due to malformed syntax."
@@ -221,7 +223,7 @@
 
 #: kallithea/controllers/files.py:541
 msgid "Empty repository"
-msgstr "Пустой репозитарий"
+msgstr "Пустой репозиторий"
 
 #: kallithea/controllers/files.py:543
 msgid "Unknown archive type"
@@ -357,12 +359,12 @@
 
 #: kallithea/controllers/pullrequests.py:398
 msgid "Missing changesets since the previous pull request:"
-msgstr ""
+msgstr "Отсутствующие ревизии относительно предыдущего pull-запроса:"
 
 #: kallithea/controllers/pullrequests.py:405
 #, python-format
 msgid "New changesets on %s %s since the previous pull request:"
-msgstr ""
+msgstr "Новые ревизии на %s %s относительно предыдущего pull-запроса"
 
 #: kallithea/controllers/pullrequests.py:412
 msgid "Ancestor didn't change - show diff since previous version:"
@@ -373,17 +375,17 @@
 msgid ""
 "This pull request is based on another %s revision and there is no simple "
 "diff."
-msgstr ""
+msgstr "Этот pull-запрос основан на другой ревизии %s, простой diff невозможен"
 
 #: kallithea/controllers/pullrequests.py:421
 #, python-format
 msgid "No changes found on %s %s since previous version."
-msgstr ""
+msgstr "Нет изменений на %s %s относительно предыдущей версии."
 
 #: kallithea/controllers/pullrequests.py:456
 #, python-format
 msgid "Closed, replaced by %s ."
-msgstr ""
+msgstr "Закрыт, замещён %s ."
 
 #: kallithea/controllers/pullrequests.py:464
 msgid "Pull request update created"
@@ -400,29 +402,29 @@
 #: kallithea/controllers/pullrequests.py:577
 #, python-format
 msgid "This pull request has already been merged to %s."
-msgstr ""
+msgstr "Этот pull-запрос уже принят на ветку %s."
 
 #: kallithea/controllers/pullrequests.py:579
 msgid "This pull request has been closed and can not be updated."
-msgstr ""
+msgstr "Этот pull-запрос был закрыт и не может быть обновлён."
 
 #: kallithea/controllers/pullrequests.py:597
 #, python-format
 msgid "This pull request can be updated with changes on %s:"
-msgstr ""
+msgstr "Этот pull-запрос может быть обновлён из %s:"
 
 #: kallithea/controllers/pullrequests.py:600
 msgid "No changesets found for updating this pull request."
-msgstr ""
+msgstr "Нет изменений для обновления этого pull-запроса."
 
 #: kallithea/controllers/pullrequests.py:608
 #, python-format
 msgid "Note: Branch %s has another head: %s."
-msgstr ""
+msgstr "Внимание: Ветка %s имеет ещё одну верхушку: %s."
 
 #: kallithea/controllers/pullrequests.py:614
 msgid "Git pull requests don't support updates yet."
-msgstr ""
+msgstr "Обновление pull-запросы git не поддерживается."
 
 #: kallithea/controllers/pullrequests.py:701
 msgid "Closing."
@@ -521,12 +523,12 @@
 
 #: kallithea/controllers/admin/gists.py:267
 msgid "Successfully updated gist data"
-msgstr ""
+msgstr "Данные gist-записи обновлены"
 
 #: kallithea/controllers/admin/gists.py:270
 #, python-format
 msgid "Error occurred during update of gist %s"
-msgstr ""
+msgstr "Произошла ошибка при обновлении gist-записи %s"
 
 #: kallithea/controllers/admin/my_account.py:70
 msgid "You can't edit this user since it's crucial for entire application"
@@ -571,17 +573,17 @@
 #: kallithea/controllers/admin/my_account.py:254
 #: kallithea/controllers/admin/users.py:314
 msgid "Api key successfully created"
-msgstr ""
+msgstr "API-ключ успешно создан"
 
 #: kallithea/controllers/admin/my_account.py:266
 #: kallithea/controllers/admin/users.py:330
 msgid "Api key successfully reset"
-msgstr ""
+msgstr "API-ключ успешно сброшен"
 
 #: kallithea/controllers/admin/my_account.py:270
 #: kallithea/controllers/admin/users.py:334
 msgid "Api key successfully deleted"
-msgstr ""
+msgstr "API-ключ успешно удалён"
 
 #: kallithea/controllers/admin/permissions.py:63
 #: kallithea/controllers/admin/permissions.py:67
@@ -805,7 +807,7 @@
 
 #: kallithea/controllers/admin/repos.py:492
 msgid "-- Not a fork --"
-msgstr ""
+msgstr "-- Не форк --"
 
 #: kallithea/controllers/admin/repos.py:526
 msgid "Updated repository visibility in public journal"
@@ -860,7 +862,7 @@
 
 #: kallithea/controllers/admin/repos.py:622
 msgid "Cache invalidation successful"
-msgstr ""
+msgstr "Кэш сброшен"
 
 #: kallithea/controllers/admin/repos.py:626
 msgid "An error occurred during cache invalidation"
@@ -1017,7 +1019,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr "Добавлен IP %s в белый список пользователя"
 
 #: kallithea/controllers/admin/users.py:488
@@ -1025,7 +1027,7 @@
 msgstr "Произошла ошибка при сохранении IP"
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr "Удален IP %s из белого списка пользователя"
 
 #: kallithea/lib/auth.py:745
@@ -1045,7 +1047,7 @@
 
 #: kallithea/lib/base.py:427
 msgid "Repository not found in the filesystem"
-msgstr ""
+msgstr "Репозиторий не найден на файловой системе"
 
 #: kallithea/lib/base.py:453 kallithea/lib/helpers.py:643
 msgid "Changeset not found"
@@ -2052,8 +2054,8 @@
 "статус"
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
-msgstr "Пожалуйста, введите существующий IPv4 или IpV6 адре"
+msgid "Please enter a valid IPv4 or IPv6 address"
+msgstr "Пожалуйста, введите существующий IPv4 или IPv6 адре"
 
 #: kallithea/model/validators.py:818
 #, python-format
@@ -2079,7 +2081,7 @@
 
 #: kallithea/templates/about.html:4 kallithea/templates/about.html:17
 msgid "About"
-msgstr ""
+msgstr "О программе"
 
 #: kallithea/templates/index.html:5
 msgid "Dashboard"
@@ -2316,7 +2318,7 @@
 #: kallithea/templates/password_reset.html:35
 #: kallithea/templates/register.html:79
 msgid "Captcha"
-msgstr ""
+msgstr "Капча"
 
 #: kallithea/templates/password_reset.html:46
 msgid "Send Password Reset Email"
@@ -2331,12 +2333,12 @@
 #: kallithea/templates/register.html:5 kallithea/templates/register.html:14
 #: kallithea/templates/register.html:90
 msgid "Sign Up"
-msgstr "Вступить"
+msgstr "Регистрация"
 
 #: kallithea/templates/register.html:12
 #, python-format
 msgid "Sign Up to %s"
-msgstr ""
+msgstr "Регистра на %s"
 
 #: kallithea/templates/register.html:42
 msgid "Re-enter password"
@@ -2372,7 +2374,7 @@
 
 #: kallithea/templates/register.html:94
 msgid "Please wait for an administrator to activate your account."
-msgstr ""
+msgstr "Пожалуйста, подождите, пока администратор подтвердит Вашу регистрацию."
 
 #: kallithea/templates/switch_to_list.html:10
 #: kallithea/templates/branches/branches_data.html:69
@@ -2433,7 +2435,7 @@
 #: kallithea/templates/admin/admin_log.html:7
 #: kallithea/templates/admin/permissions/permissions_globals.html:18
 msgid "Repository"
-msgstr "Репозитарий"
+msgstr "Репозиторий"
 
 #: kallithea/templates/admin/admin_log.html:8
 #: kallithea/templates/bookmarks/bookmarks.html:51
@@ -2485,12 +2487,12 @@
 #: kallithea/templates/admin/auth/auth_settings.html:40
 #: kallithea/templates/base/root.html:40
 msgid "enabled"
-msgstr ""
+msgstr "включено"
 
 #: kallithea/templates/admin/auth/auth_settings.html:40
 #: kallithea/templates/base/root.html:41
 msgid "disabled"
-msgstr ""
+msgstr "отключено"
 
 #: kallithea/templates/admin/auth/auth_settings.html:51
 msgid "Plugin"
@@ -2556,7 +2558,7 @@
 #: kallithea/templates/admin/defaults/defaults.html:59
 #: kallithea/templates/admin/repos/repo_edit_settings.html:95
 msgid "Enable statistics window on summary page."
-msgstr "Включить окно статистики на странице 'Общие сведения'."
+msgstr "Включить окно статистики на странице «Общие сведения»."
 
 #: kallithea/templates/admin/defaults/defaults.html:65
 #: kallithea/templates/admin/repos/repo_edit_settings.html:100
@@ -2566,7 +2568,7 @@
 #: kallithea/templates/admin/defaults/defaults.html:69
 #: kallithea/templates/admin/repos/repo_edit_settings.html:104
 msgid "Enable download menu on summary page."
-msgstr "Включить меню скачивания на странице  'Общие сведения'."
+msgstr "Включить меню скачивания на странице «Общие сведения»."
 
 #: kallithea/templates/admin/defaults/defaults.html:75
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:34
@@ -2582,7 +2584,7 @@
 #: kallithea/templates/admin/gists/edit.html:5
 #: kallithea/templates/admin/gists/edit.html:18
 msgid "Edit Gist"
-msgstr ""
+msgstr "Правка gist-записи"
 
 #: kallithea/templates/admin/gists/edit.html:36
 #, python-format
@@ -2622,7 +2624,7 @@
 
 #: kallithea/templates/admin/gists/edit.html:145
 msgid "Update Gist"
-msgstr ""
+msgstr "Обновить"
 
 #: kallithea/templates/admin/gists/edit.html:146
 #: kallithea/templates/changeset/changeset_file_comment.html:89
@@ -2633,24 +2635,24 @@
 #: kallithea/templates/admin/gists/index.html:16
 #, python-format
 msgid "Private Gists for User %s"
-msgstr "Приватная запись Gist для пользователя %s"
+msgstr "Приватная gist-запись для пользователя %s"
 
 #: kallithea/templates/admin/gists/index.html:8
 #: kallithea/templates/admin/gists/index.html:18
 #, python-format
 msgid "Public Gists for User %s"
-msgstr "Публичная запись Gist для пользователя %s"
+msgstr "Публичная gist-запись для пользователя %s"
 
 #: kallithea/templates/admin/gists/index.html:10
 #: kallithea/templates/admin/gists/index.html:20
 msgid "Public Gists"
-msgstr "Публичные записи Gist"
+msgstr "Публичные gist-записи"
 
 #: kallithea/templates/admin/gists/index.html:37
 #: kallithea/templates/admin/gists/show.html:25
 #: kallithea/templates/base/base.html:240
 msgid "Create New Gist"
-msgstr ""
+msgstr "Создать новую gist-запись"
 
 #: kallithea/templates/admin/gists/index.html:54
 #: kallithea/templates/data_table/_dt_elements.html:143
@@ -2659,7 +2661,7 @@
 
 #: kallithea/templates/admin/gists/index.html:74
 msgid "There are no gists yet"
-msgstr "Записи Gist отсутствуют"
+msgstr "Gist-записи отсутствуют"
 
 #: kallithea/templates/admin/gists/new.html:5
 #: kallithea/templates/admin/gists/new.html:18
@@ -2737,7 +2739,7 @@
 
 #: kallithea/templates/admin/gists/show.html:56
 msgid "Confirm to delete this Gist"
-msgstr ""
+msgstr "Подтвердите удаление этой gist-записи"
 
 #: kallithea/templates/admin/gists/show.html:63
 #: kallithea/templates/changeset/changeset_file_comment.html:91
@@ -2755,16 +2757,16 @@
 #: kallithea/templates/files/files_edit.html:49
 #: kallithea/templates/files/files_source.html:34
 msgid "Show as Raw"
-msgstr ""
+msgstr "Показать только текст"
 
 #: kallithea/templates/admin/gists/show.html:73
 msgid "created"
-msgstr "создал"
+msgstr "создана"
 
 #: kallithea/templates/admin/gists/show.html:86
 #: kallithea/templates/files/files_source.html:73
 msgid "Show as raw"
-msgstr "Показать без форматирования"
+msgstr "Показать только текст"
 
 #: kallithea/templates/admin/my_account/my_account.html:5
 #: kallithea/templates/admin/my_account/my_account.html:9
@@ -2780,11 +2782,11 @@
 #: kallithea/templates/admin/my_account/my_account.html:37
 #: kallithea/templates/admin/users/user_edit.html:30
 msgid "API Keys"
-msgstr ""
+msgstr "API-ключи"
 
 #: kallithea/templates/admin/my_account/my_account.html:38
 msgid "My Emails"
-msgstr "Мои Email-ы"
+msgstr "Мои адреса E-mail"
 
 #: kallithea/templates/admin/my_account/my_account.html:39
 msgid "My Repositories"
@@ -2817,7 +2819,7 @@
 #: kallithea/templates/admin/users/user_edit_api_keys.html:14
 #, python-format
 msgid "Confirm to reset this api key: %s"
-msgstr ""
+msgstr "Подтвердите сброс этого API-ключа: %s"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:15
 #: kallithea/templates/admin/users/user_edit_api_keys.html:15
@@ -2833,7 +2835,7 @@
 #: kallithea/templates/admin/users/user_edit_api_keys.html:40
 #, python-format
 msgid "Confirm to remove this api key: %s"
-msgstr ""
+msgstr "Подтвердите удаление этого API-ключа: %s"
 
 #: kallithea/templates/admin/my_account/my_account_api_keys.html:42
 #: kallithea/templates/admin/users/user_edit_api_keys.html:42
@@ -2901,7 +2903,7 @@
 
 #: kallithea/templates/admin/my_account/my_account_password.html:7
 msgid "Current password"
-msgstr ""
+msgstr "Текущий пароль"
 
 #: kallithea/templates/admin/my_account/my_account_password.html:16
 #: kallithea/templates/admin/users/user_edit_profile.html:69
@@ -2910,7 +2912,7 @@
 
 #: kallithea/templates/admin/my_account/my_account_password.html:25
 msgid "Confirm new password"
-msgstr ""
+msgstr "Подтвердите новый пароль"
 
 #: kallithea/templates/admin/my_account/my_account_profile.html:11
 msgid "Change your avatar at"
@@ -2933,7 +2935,7 @@
 #: kallithea/templates/admin/my_account/my_account_profile.html:16
 #: kallithea/templates/admin/users/user_edit_profile.html:15
 msgid "current IP"
-msgstr ""
+msgstr "текущий IP-адрес"
 
 #: kallithea/templates/admin/my_account/my_account_profile.html:28
 msgid ""
@@ -3039,9 +3041,8 @@
 "permission, note that all custom default permission on repositories will "
 "be lost"
 msgstr ""
-"Выбранные привилегии будут установлены по умолчанию для каждого "
-"репозитория. Учтите, что ранее установленные привилегии по умолчанию "
-"будут сброшены"
+"Выбранные привилегии будут установлены по умолчанию для каждого репозитория. "
+"Учтите, что ранее установленные привилегии по умолчанию будут сброшены"
 
 #: kallithea/templates/admin/permissions/permissions_globals.html:27
 #: kallithea/templates/admin/permissions/permissions_globals.html:40
@@ -3064,8 +3065,8 @@
 "will be lost"
 msgstr ""
 "Выбранные привилегии будут установлены по умолчанию для каждой группы "
-"репозиториев. Учтите, что ранее установленные привилегии по умолчанию для"
-" групп репозиториев будут сброшены"
+"репозиториев. Учтите, что ранее установленные привилегии по умолчанию для "
+"групп репозиториев будут сброшены"
 
 #: kallithea/templates/admin/permissions/permissions_globals.html:46
 #: kallithea/templates/data_table/_dt_elements.html:211
@@ -3079,8 +3080,8 @@
 "will be lost"
 msgstr ""
 "Выбранные привилегии будут установлены по умолчанию для каждой группы "
-"пользователей. Учтите, что ранее установленные привилегии по умолчанию "
-"для групп пользователей будут сброшены"
+"пользователей. Учтите, что ранее установленные привилегии по умолчанию для "
+"групп пользователей будут сброшены"
 
 #: kallithea/templates/admin/permissions/permissions_globals.html:60
 msgid "Repository creation"
@@ -3120,7 +3121,7 @@
 #: kallithea/templates/admin/users/user_edit_ips.html:23
 #, python-format
 msgid "Confirm to delete this ip: %s"
-msgstr "Подтвердите удаление ip %s"
+msgstr "Подтвердите удаление IP %s"
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:21
 #: kallithea/templates/admin/users/user_edit_ips.html:30
@@ -3129,12 +3130,12 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
-msgstr "Новый ip-адрес"
+msgid "New IP address"
+msgstr "Новый IP-адрес"
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
 msgid "Default User Permissions Overview"
-msgstr "Обзор прав пользователей по-умолчанию"
+msgstr "Обзор прав пользователей по умолчанию"
 
 #: kallithea/templates/admin/repo_groups/repo_group_add.html:11
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:11
@@ -3169,7 +3170,7 @@
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:5
 #, python-format
 msgid "%s Repository Group Settings"
-msgstr "Настройки рруппы репозиториев %s"
+msgstr "Настройки группы репозиториев %s"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit.html:21
 msgid "Add Child Group"
@@ -3228,7 +3229,7 @@
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:25
 msgid "Delete this repository group"
-msgstr ""
+msgstr "Удалить эту группу репозиториев"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:7
 #: kallithea/templates/admin/repos/repo_edit_permissions.html:8
@@ -3271,7 +3272,7 @@
 #: kallithea/templates/admin/user_groups/user_group_edit_perms.html:28
 #: kallithea/templates/admin/user_groups/user_group_edit_perms.html:45
 msgid "default"
-msgstr "по-умолчанию"
+msgstr "по умолчанию"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:34
 #: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:71
@@ -3312,7 +3313,7 @@
 "Enable lock-by-pulling on group. This option will be applied to all other"
 " groups and repositories inside"
 msgstr ""
-"Включить lock-by-pulling для группы. Эта опция будет применена ко всем "
+"Включить автоблокировку для группы. Эта опция будет применена ко всем "
 "дочерним группам и репозиториям"
 
 #: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:53
@@ -3361,7 +3362,8 @@
 #: kallithea/templates/admin/repos/repo_edit_settings.html:76
 #: kallithea/templates/forks/fork.html:42
 msgid "Keep it short and to the point. Use a README file for longer descriptions."
-msgstr "Короткое и осмысленное. Для развернутого описания используйте файл README."
+msgstr ""
+"Короткое и осмысленное. Для развернутого описания используйте файл README."
 
 #: kallithea/templates/admin/repos/repo_add_base.html:45
 #: kallithea/templates/admin/repos/repo_edit_settings.html:46
@@ -4963,7 +4965,7 @@
 msgstr[2] "%d к строкам"
 
 #: kallithea/templates/changeset/changeset_file_comment.html:116
-#, fuzzy, python-format
+#, python-format
 msgid "%d general"
 msgid_plural "%d general"
 msgstr[0] ""
--- a/kallithea/i18n/sk/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/sk/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -997,7 +997,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -1005,7 +1005,7 @@
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -2004,7 +2004,7 @@
 msgstr ""
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr ""
 
 #: kallithea/model/validators.py:818
@@ -3067,7 +3067,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr ""
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/zh_CN/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/zh_CN/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -1006,7 +1006,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -1014,7 +1014,7 @@
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -2004,7 +2004,7 @@
 msgstr "修订%(revs)s已经包含在拉取请求中或者或者已经设置状态"
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr ""
 
 #: kallithea/model/validators.py:818
@@ -3077,7 +3077,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr ""
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/i18n/zh_TW/LC_MESSAGES/kallithea.po	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/i18n/zh_TW/LC_MESSAGES/kallithea.po	Tue Jun 09 22:46:40 2015 +0200
@@ -998,7 +998,7 @@
 
 #: kallithea/controllers/admin/users.py:482
 #, python-format
-msgid "Added ip %s to user whitelist"
+msgid "Added IP address %s to user whitelist"
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:488
@@ -1006,7 +1006,7 @@
 msgstr ""
 
 #: kallithea/controllers/admin/users.py:502
-msgid "Removed ip address from user whitelist"
+msgid "Removed IP address from user whitelist"
 msgstr ""
 
 #: kallithea/lib/auth.py:745
@@ -1995,7 +1995,7 @@
 msgstr ""
 
 #: kallithea/model/validators.py:817
-msgid "Please enter a valid IPv4 or IpV6 address"
+msgid "Please enter a valid IPv4 or IPv6 address"
 msgstr ""
 
 #: kallithea/model/validators.py:818
@@ -3065,7 +3065,7 @@
 
 #: kallithea/templates/admin/permissions/permissions_ips.html:32
 #: kallithea/templates/admin/users/user_edit_ips.html:42
-msgid "New ip address"
+msgid "New IP address"
 msgstr ""
 
 #: kallithea/templates/admin/permissions/permissions_perms.html:1
--- a/kallithea/lib/auth.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/auth.py	Tue Jun 09 22:46:40 2015 +0200
@@ -143,21 +143,6 @@
 def check_password(password, hashed):
     return KallitheaCrypto.hash_check(password, hashed)
 
-
-def generate_api_key(str_, salt=None):
-    """
-    Generates API KEY from given string
-
-    :param str_:
-    :param salt:
-    """
-
-    if salt is None:
-        salt = _RandomNameSequence().next()
-
-    return hashlib.sha1(str_ + salt).hexdigest()
-
-
 class CookieStoreWrapper(object):
 
     def __init__(self, cookie_store):
@@ -519,9 +504,9 @@
             log.debug('Auth User lookup by USER ID %s' % self.user_id)
             is_user_loaded = user_model.fill_data(self, user_id=self.user_id)
 
-        # try go get user by api key
+        # try go get user by API key
         elif self._api_key and self._api_key != self.anonymous_user.api_key:
-            log.debug('Auth User lookup by API KEY %s' % self._api_key)
+            log.debug('Auth User lookup by API key %s' % self._api_key)
             is_user_loaded = user_model.fill_data(self, api_key=self._api_key)
 
         # lookup by username
@@ -719,6 +704,15 @@
 #==============================================================================
 # CHECK DECORATORS
 #==============================================================================
+
+def redirect_to_login(message=None):
+    from kallithea.lib import helpers as h
+    p = url.current()
+    if message:
+        h.flash(h.literal(message), category='warning')
+    log.debug('Redirecting to login page, origin: %s' % p)
+    return redirect(url('login_home', came_from=p, **request.GET))
+
 class LoginRequired(object):
     """
     Must be logged in to execute this function else
@@ -738,58 +732,43 @@
         cls = fargs[0]
         user = cls.authuser
         loc = "%s:%s" % (cls.__class__.__name__, func.__name__)
+        log.debug('Checking access for user %s @ %s' % (user, loc))
 
         # check if our IP is allowed
-        ip_access_valid = True
         if not user.ip_allowed:
-            from kallithea.lib import helpers as h
-            h.flash(h.literal(_('IP %s not allowed' % (user.ip_addr))),
-                    category='warning')
-            ip_access_valid = False
-
-        # check if we used an APIKEY and it's a valid one
-        # defined whitelist of controllers which API access will be enabled
-        _api_key = request.GET.get('api_key', '')
-        api_access_valid = allowed_api_access(loc, api_key=_api_key)
+            return redirect_to_login(_('IP %s not allowed' % (user.ip_addr)))
 
-        # explicit controller is enabled or API is in our whitelist
-        if self.api_access or api_access_valid:
-            log.debug('Checking API KEY access for %s' % cls)
-            if _api_key and _api_key in user.api_keys:
-                api_access_valid = True
-                log.debug('API KEY ****%s is VALID' % _api_key[-4:])
+        # check if we used an API key and it's a valid one
+        api_key = request.GET.get('api_key')
+        if api_key is not None:
+            # explicit controller is enabled or API is in our whitelist
+            if self.api_access or allowed_api_access(loc, api_key=api_key):
+                if api_key in user.api_keys:
+                    log.info('user %s authenticated with API key ****%s @ %s'
+                             % (user, api_key[-4:], loc))
+                    return func(*fargs, **fkwargs)
+                else:
+                    log.warning('API key ****%s is NOT valid' % api_key[-4:])
+                    return redirect_to_login(_('Invalid API key'))
             else:
-                api_access_valid = False
-                if not _api_key:
-                    log.debug("API KEY *NOT* present in request")
-                else:
-                    log.warning("API KEY ****%s *NOT* valid" % _api_key[-4:])
+                # controller does not allow API access
+                log.warning('API access to %s is not allowed' % loc)
+                return abort(403)
 
         # CSRF protection - POSTs with session auth must contain correct token
-        if request.POST and user.is_authenticated and not api_access_valid:
+        if request.POST and user.is_authenticated:
             token = request.POST.get(secure_form.token_key)
             if not token or token != secure_form.authentication_token():
                 log.error('CSRF check failed')
                 return abort(403)
 
-        log.debug('Checking if %s is authenticated @ %s' % (user.username, loc))
-        reason = 'RegularAuth' if user.is_authenticated else 'APIAuth'
-
-        if ip_access_valid and (user.is_authenticated or api_access_valid):
-            log.info('user %s authenticating with:%s IS authenticated on func %s '
-                     % (user, reason, loc)
-            )
+        # regular user authentication
+        if user.is_authenticated:
+            log.info('user %s authenticated with regular auth @ %s' % (user, loc))
             return func(*fargs, **fkwargs)
         else:
-            log.warning('user %s authenticating with:%s NOT authenticated on func: %s: '
-                     'IP_ACCESS:%s API_ACCESS:%s'
-                     % (user, reason, loc, ip_access_valid, api_access_valid)
-            )
-            p = url.current()
-
-            log.debug('redirecting to login page with %s' % p)
-            return redirect(url('login_home', came_from=p))
-
+            log.warning('user %s NOT authenticated with regular auth @ %s' % (user, loc))
+            return redirect_to_login()
 
 class NotAnonymous(object):
     """
@@ -808,13 +787,8 @@
         anonymous = self.user.username == User.DEFAULT_USER
 
         if anonymous:
-            p = url.current()
-
-            import kallithea.lib.helpers as h
-            h.flash(_('You need to be a registered user to '
-                      'perform this action'),
-                    category='warning')
-            return redirect(url('login_home', came_from=p))
+            return redirect_to_login(_('You need to be a registered user to '
+                    'perform this action'))
         else:
             return func(*fargs, **fkwargs)
 
@@ -845,14 +819,7 @@
             anonymous = self.user.username == User.DEFAULT_USER
 
             if anonymous:
-                p = url.current()
-
-                import kallithea.lib.helpers as h
-                h.flash(_('You need to be signed in to '
-                          'view this page'),
-                        category='warning')
-                return redirect(url('login_home', came_from=p))
-
+                return redirect_to_login(_('You need to be signed in to view this page'))
             else:
                 # redirect with forbidden ret code
                 return abort(403)
--- a/kallithea/lib/dbmigrate/schema/db_2_2_0.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/dbmigrate/schema/db_2_2_0.py	Tue Jun 09 22:46:40 2015 +0200
@@ -437,7 +437,7 @@
     user_comments = relationship('ChangesetComment', cascade='all')
     #extra emails for this user
     user_emails = relationship('UserEmailMap', cascade='all')
-    #extra api keys
+    #extra API keys
     user_api_keys = relationship('UserApiKeys', cascade='all')
 
 
@@ -1239,7 +1239,7 @@
                 pass
 
         return get_clone_url(uri_tmpl=uri_tmpl,
-                             qualifed_home_url=qualified_home_url,
+                             qualified_home_url=qualified_home_url,
                              repo_name=self.repo_name,
                              repo_id=self.repo_id, **override)
 
--- a/kallithea/lib/dbmigrate/schema/db_2_2_3.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/dbmigrate/schema/db_2_2_3.py	Tue Jun 09 22:46:40 2015 +0200
@@ -437,7 +437,7 @@
     user_comments = relationship('ChangesetComment', cascade='all')
     #extra emails for this user
     user_emails = relationship('UserEmailMap', cascade='all')
-    #extra api keys
+    #extra API keys
     user_api_keys = relationship('UserApiKeys', cascade='all')
 
 
@@ -1263,7 +1263,7 @@
                 pass
 
         return get_clone_url(uri_tmpl=uri_tmpl,
-                             qualifed_home_url=qualified_home_url,
+                             qualified_home_url=qualified_home_url,
                              repo_name=self.repo_name,
                              repo_id=self.repo_id, **override)
 
--- a/kallithea/lib/exceptions.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/exceptions.py	Tue Jun 09 22:46:40 2015 +0200
@@ -45,6 +45,7 @@
 
 
 class DefaultUserException(Exception):
+    """An invalid action was attempted on the default user"""
     pass
 
 
--- a/kallithea/lib/helpers.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/helpers.py	Tue Jun 09 22:46:40 2015 +0200
@@ -423,7 +423,7 @@
 #==============================================================================
 from kallithea.lib.vcs.utils import author_name, author_email
 from kallithea.lib.utils2 import credentials_filter, age as _age
-from kallithea.model.db import User, ChangesetStatus
+from kallithea.model.db import User, ChangesetStatus, PullRequest
 
 age = lambda  x, y=False: _age(x, y)
 capitalize = lambda x: x.capitalize()
@@ -679,7 +679,7 @@
                 url('changeset_home', repo_name=repo_name,
                     revision=_rev
                 ),
-                _('compare view')
+                _('Compare view')
             )
         )
 
@@ -724,7 +724,7 @@
     def get_fork_name():
         repo_name = action_params
         _url = url('summary_home', repo_name=repo_name)
-        return _('fork name %s') % link_to(action_params, _url)
+        return _('Fork name %s') % link_to(action_params, _url)
 
     def get_user_name():
         user_name = action_params
@@ -736,12 +736,15 @@
 
     def get_pull_request():
         pull_request_id = action_params
+        nice_id = PullRequest.make_nice_id(pull_request_id)
+
         deleted = user_log.repository is None
         if deleted:
             repo_name = user_log.repository_name
         else:
             repo_name = user_log.repository.repo_name
-        return link_to(_('Pull request #%s') % pull_request_id,
+
+        return link_to(_('Pull request %s') % nice_id,
                     url('pullrequest_show', repo_name=repo_name,
                     pull_request_id=pull_request_id))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/lib/middleware/sessionmiddleware.py	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+kallithea.lib.middleware.sessionmiddleware
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+session management middleware
+
+This file overrides Beaker's built-in SessionMiddleware
+class to automagically use secure cookies over HTTPS.
+
+Original Beaker SessionMiddleware class written by Ben Bangert
+"""
+
+from beaker.session import SessionObject
+from beaker.middleware import SessionMiddleware
+
+class SecureSessionMiddleware(SessionMiddleware):
+    def __call__(self, environ, start_response):
+        """
+        This function's implementation is taken directly from Beaker,
+        with HTTPS detection added. When accessed over HTTPS, force
+        setting cookie's secure flag.
+
+        The only difference from that original code is that we switch
+        the secure option on and off depending on the URL scheme (first
+        two lines). To avoid concurrency issues, we use a local options
+        variable.
+        """
+        options = dict(self.options)
+        options["secure"] = environ['wsgi.url_scheme'] == 'https'
+
+        session = SessionObject(environ, **options)
+        if environ.get('paste.registry'):
+            if environ['paste.registry'].reglist:
+                environ['paste.registry'].register(self.session, session)
+        environ[self.environ_key] = session
+        environ['beaker.get_session'] = self._get_session
+
+        if 'paste.testing_variables' in environ and 'webtest_varname' in options:
+            environ['paste.testing_variables'][options['webtest_varname']] = session
+
+        def session_start_response(status, headers, exc_info=None):
+            if session.accessed():
+                session.persist()
+                if session.__dict__['_headers']['set_cookie']:
+                    cookie = session.__dict__['_headers']['cookie_out']
+                    if cookie:
+                        headers.append(('Set-cookie', cookie))
+            return start_response(status, headers, exc_info)
+        return self.wrap_app(environ, session_start_response)
--- a/kallithea/lib/paster_commands/make_rcextensions.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/paster_commands/make_rcextensions.py	Tue Jun 09 22:46:40 2015 +0200
@@ -30,7 +30,6 @@
 
 import os
 import sys
-import logging
 import pkg_resources
 
 from kallithea.lib.utils import BasePasterCommand, ask_ok
@@ -40,46 +39,44 @@
 rc_path = dn(dn(dn(os.path.realpath(__file__))))
 sys.path.append(rc_path)
 
-log = logging.getLogger(__name__)
-
 
 class Command(BasePasterCommand):
 
     max_args = 1
     min_args = 1
 
-    usage = "CONFIG_FILE"
     group_name = "Kallithea"
     takes_config_file = -1
     parser = BasePasterCommand.standard_parser(verbose=True)
-    summary = "Creates additional extensions for kallithea"
+    summary = "Write template file for extending Kallithea in Python."
+    usage = "CONFIG_FILE"
+    description = '''\
+        A rcextensions directory with a __init__.py file will be created next to
+        the ini file. Local customizations in that file will survive upgrades.
+        The file contains instructions on how it can be customized.
+        '''
 
     def command(self):
-        logging.config.fileConfig(self.path_to_ini_file)
         from pylons import config
 
-        def _make_file(ext_file, tmpl):
-            bdir = os.path.split(ext_file)[0]
-            if not os.path.isdir(bdir):
-                os.makedirs(bdir)
-            with open(ext_file, 'wb') as f:
-                f.write(tmpl)
-                log.info('Writen new extensions file to %s' % ext_file)
-
         here = config['here']
-        tmpl = pkg_resources.resource_string(
+        content = pkg_resources.resource_string(
             'kallithea', os.path.join('config', 'rcextensions', '__init__.py')
         )
         ext_file = os.path.join(here, 'rcextensions', '__init__.py')
         if os.path.exists(ext_file):
             msg = ('Extension file already exists, do you want '
                    'to overwrite it ? [y/n]')
-            if ask_ok(msg):
-                _make_file(ext_file, tmpl)
-            else:
-                log.info('nothing done...')
-        else:
-            _make_file(ext_file, tmpl)
+            if not ask_ok(msg):
+                print 'Nothing done...'
+                return
+
+        dirname = os.path.dirname(ext_file)
+        if not os.path.isdir(dirname):
+            os.makedirs(dirname)
+        with open(ext_file, 'wb') as f:
+            f.write(content)
+            print 'Wrote new extensions file to %s' % ext_file
 
     def update_parser(self):
         pass
--- a/kallithea/lib/recaptcha.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/recaptcha.py	Tue Jun 09 22:46:40 2015 +0200
@@ -55,7 +55,7 @@
     recaptcha_challenge_field -- The value of recaptcha_challenge_field from the form
     recaptcha_response_field -- The value of recaptcha_response_field from the form
     private_key -- your reCAPTCHA private key
-    remoteip -- the user's ip address
+    remoteip -- the user's IP address
     """
 
     if not (recaptcha_response_field and recaptcha_challenge_field and
--- a/kallithea/lib/utils.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/utils.py	Tue Jun 09 22:46:40 2015 +0200
@@ -161,7 +161,7 @@
         easy translations
     :param repo: string name of repository or object containing repo_id,
         that action was made on
-    :param ipaddr: optional ip address from what the action was made
+    :param ipaddr: optional IP address from what the action was made
     :param sa: optional sqlalchemy session
 
     """
--- a/kallithea/lib/utils2.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/utils2.py	Tue Jun 09 22:46:40 2015 +0200
@@ -503,8 +503,8 @@
     return ''.join(uri)
 
 
-def get_clone_url(uri_tmpl, qualifed_home_url, repo_name, repo_id, **override):
-    parsed_url = urlobject.URLObject(qualifed_home_url)
+def get_clone_url(uri_tmpl, qualified_home_url, repo_name, repo_id, **override):
+    parsed_url = urlobject.URLObject(qualified_home_url)
     decoded_path = safe_unicode(urllib.unquote(parsed_url.path.rstrip('/')))
     args = {
         'scheme': parsed_url.scheme,
@@ -625,25 +625,25 @@
 
 def _extract_extras(env=None):
     """
-    Extracts the rc extras data from os.environ, and wraps it into named
+    Extracts the Kallithea extras data from os.environ, and wraps it into named
     AttributeDict object
     """
     if not env:
         env = os.environ
 
     try:
-        rc_extras = json.loads(env['KALLITHEA_EXTRAS'])
+        extras = json.loads(env['KALLITHEA_EXTRAS'])
     except KeyError:
-        rc_extras = {}
+        extras = {}
 
     try:
         for k in ['username', 'repository', 'locked_by', 'scm', 'make_lock',
                   'action', 'ip']:
-            rc_extras[k]
+            extras[k]
     except KeyError, e:
-        raise Exception('Missing key %s in os.environ %s' % (e, rc_extras))
+        raise Exception('Missing key %s in os.environ %s' % (e, extras))
 
-    return AttributeDict(rc_extras)
+    return AttributeDict(extras)
 
 
 def _set_extras(extras):
--- a/kallithea/lib/vcs/backends/git/repository.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/vcs/backends/git/repository.py	Tue Jun 09 22:46:40 2015 +0200
@@ -12,6 +12,7 @@
 import os
 import re
 import time
+import errno
 import urllib
 import urllib2
 import logging
@@ -696,7 +697,13 @@
         runs gits update-server-info command in this repo instance
         """
         from dulwich.server import update_server_info
-        update_server_info(self._repo)
+        try:
+            update_server_info(self._repo)
+        except OSError, e:
+            if e.errno != errno.ENOENT:
+                raise
+            # Workaround for dulwich crashing on for example its own dulwich/tests/data/repos/simple_merge.git/info/refs.lock
+            log.error('Ignoring error running update-server-info: %s', e)
 
     @LazyProperty
     def workdir(self):
--- a/kallithea/lib/vcs/backends/hg/repository.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/vcs/backends/hg/repository.py	Tue Jun 09 22:46:40 2015 +0200
@@ -229,7 +229,7 @@
 
     def _get_all_revisions(self):
 
-        return map(lambda x: hex(x[7]), self._repo.changelog.index)[:-1]
+        return [self._repo[x].hex() for x in self._repo.filtered('visible').changelog.revs()]
 
     def get_diff(self, rev1, rev2, path='', ignore_whitespace=False,
                   context=3):
@@ -264,6 +264,7 @@
 
         return ''.join(patch.diff(self._repo, rev1, rev2, match=file_filter,
                           opts=diffopts(git=True,
+                                        showfunc=True,
                                         ignorews=ignore_whitespace,
                                         context=context)))
 
--- a/kallithea/lib/vcs/utils/lazy.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/lib/vcs/utils/lazy.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,3 +1,6 @@
+import threading
+
+
 class _Missing(object):
 
     def __repr__(self):
@@ -41,8 +44,6 @@
             obj.__dict__[self.__name__] = value
         return value
 
-import threading
-
 
 class ThreadLocalLazyProperty(LazyProperty):
     """
--- a/kallithea/model/api_key.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/api_key.py	Tue Jun 09 22:46:40 2015 +0200
@@ -15,7 +15,7 @@
 kallithea.model.api_key
 ~~~~~~~~~~~~~~~~~~~~~~~
 
-api key model for Kallithea
+API key model for Kallithea
 
 This file was forked by the Kallithea project in July 2014.
 Original author and date, and relevant copyright and licensing information is below:
--- a/kallithea/model/changeset_status.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/changeset_status.py	Tue Jun 09 22:46:40 2015 +0200
@@ -66,9 +66,27 @@
         q = q.order_by(ChangesetStatus.version.asc())
         return q
 
+    def _calculate_status(self, statuses):
+        """
+        Given a list of statuses, calculate the resulting status, according to
+        the policy: approve if consensus, reject when at least one reject.
+        """
+
+        if not statuses:
+            return ChangesetStatus.STATUS_UNDER_REVIEW
+
+        if all(st and st.status == ChangesetStatus.STATUS_APPROVED for st in statuses):
+            return ChangesetStatus.STATUS_APPROVED
+
+        if any(st and st.status == ChangesetStatus.STATUS_REJECTED for st in statuses):
+            return ChangesetStatus.STATUS_REJECTED
+
+        return ChangesetStatus.STATUS_UNDER_REVIEW
+
     def calculate_pull_request_result(self, pull_request):
         """
-        Policy: approve if consensus. Only approve and reject counts as valid votes.
+        Return a tuple (reviewers, pending reviewers, pull request status)
+        Only approve and reject counts as valid votes.
         """
 
         # collect latest votes from all voters
@@ -77,24 +95,21 @@
                                              pull_request=pull_request,
                                              with_revisions=True)):
             cs_statuses[st.author.username] = st
+
         # collect votes from official reviewers
         pull_request_reviewers = []
         pull_request_pending_reviewers = []
-        approved_votes = 0
+        relevant_statuses = []
         for r in pull_request.reviewers:
             st = cs_statuses.get(r.user.username)
-            if st and st.status == ChangesetStatus.STATUS_APPROVED:
-                approved_votes += 1
+            relevant_statuses.append(st)
             if not st or st.status in (ChangesetStatus.STATUS_NOT_REVIEWED,
                                        ChangesetStatus.STATUS_UNDER_REVIEW):
                 st = None
                 pull_request_pending_reviewers.append(r.user)
             pull_request_reviewers.append((r.user, st))
 
-        # calculate result
-        result = ChangesetStatus.STATUS_UNDER_REVIEW
-        if approved_votes and approved_votes == len(pull_request.reviewers):
-            result = ChangesetStatus.STATUS_APPROVED
+        result = self._calculate_status(relevant_statuses)
 
         return (pull_request_reviewers,
                 pull_request_pending_reviewers,
--- a/kallithea/model/comment.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/comment.py	Tue Jun 09 22:46:40 2015 +0200
@@ -63,10 +63,6 @@
                                line_no=None, revision=None, pull_request=None,
                                status_change=None, closing_pr=False):
         """
-        Get notification data
-
-        :param comment_text:
-        :param line:
         :returns: tuple (subj,body,recipients,notification_type,email_kwargs)
         """
         # make notification
@@ -130,9 +126,9 @@
             comment_url = pull_request.url(canonical=True,
                 anchor='comment-%s' % comment.comment_id)
             subj = safe_unicode(
-                h.link_to('Re pull request #%(pr_id)s: %(desc)s %(line)s' % \
+                h.link_to('Re pull request %(pr_nice_id)s: %(desc)s %(line)s' % \
                           {'desc': desc,
-                           'pr_id': comment.pull_request.pull_request_id,
+                           'pr_nice_id': comment.pull_request.nice_id(),
                            'line': line},
                           comment_url)
             )
@@ -148,7 +144,7 @@
             #set some variables for email notification
             email_kwargs = {
                 'pr_title': pull_request.title,
-                'pr_id': pull_request.pull_request_id,
+                'pr_nice_id': pull_request.nice_id(),
                 'status_change': status_change,
                 'closing_pr': closing_pr,
                 'pr_comment_url': comment_url,
@@ -167,22 +163,12 @@
                f_path=None, line_no=None, status_change=None, closing_pr=False,
                send_email=True):
         """
-        Creates new comment for changeset or pull request.
-        If status_change is not None this comment is associated with a
-        status change of changeset or changesets associated with pull request
+        Creates a new comment for either a changeset or a pull request.
+        status_change and closing_pr is only for the optional email.
 
-        :param text:
-        :param repo:
-        :param user:
-        :param revision:
-        :param pull_request: (for emails, not for comments)
-        :param f_path:
-        :param line_no:
-        :param status_change: (for emails, not for comments)
-        :param closing_pr: (for emails, not for comments)
-        :param send_email: also send email
+        Returns the created comment.
         """
-        if not text:
+        if not status_change and not text:
             log.warning('Missing text for comment, skipping...')
             return
 
@@ -239,11 +225,6 @@
         return comment
 
     def delete(self, comment):
-        """
-        Deletes given comment
-
-        :param comment_id:
-        """
         comment = self.__get_changeset_comment(comment)
         Session().delete(comment)
 
@@ -251,33 +232,40 @@
 
     def get_comments(self, repo_id, revision=None, pull_request=None):
         """
-        Gets main comments based on revision or pull_request_id
-
-        :param repo_id:
-        :param revision:
-        :param pull_request:
-        """
+        Gets general comments for either revision or pull_request.
 
-        q = ChangesetComment.query()\
-                .filter(ChangesetComment.repo_id == repo_id)\
-                .filter(ChangesetComment.line_no == None)\
-                .filter(ChangesetComment.f_path == None)
-        if revision:
-            q = q.filter(ChangesetComment.revision == revision)
-        elif pull_request:
-            pull_request = self.__get_pull_request(pull_request)
-            q = q.filter(ChangesetComment.pull_request == pull_request)
-        else:
-            raise Exception('Please specify revision or pull_request')
-        q = q.order_by(ChangesetComment.created_on)
-        return q.all()
+        Returns a list, ordered by creation date.
+        """
+        return self._get_comments(repo_id, revision=revision, pull_request=pull_request,
+                                  inline=False)
 
     def get_inline_comments(self, repo_id, revision=None, pull_request=None):
+        """
+        Gets inline comments for either revision or pull_request.
+
+        Returns a list of tuples with file path and list of comments per line number.
+        """
+        comments = self._get_comments(repo_id, revision=revision, pull_request=pull_request,
+                                      inline=True)
+
+        paths = defaultdict(lambda: defaultdict(list))
+        for co in comments:
+            paths[co.f_path][co.line_no].append(co)
+        return paths.items()
+
+    def _get_comments(self, repo_id, revision=None, pull_request=None, inline=False):
+        """
+        Gets comments for either revision or pull_request_id, either inline or general.
+        """
         q = Session().query(ChangesetComment)\
-            .filter(ChangesetComment.repo_id == repo_id)\
-            .filter(ChangesetComment.line_no != None)\
-            .filter(ChangesetComment.f_path != None)\
-            .order_by(ChangesetComment.comment_id.asc())\
+            .filter(ChangesetComment.repo_id == repo_id)
+
+        if inline:
+            q = q.filter(ChangesetComment.line_no != None)\
+                .filter(ChangesetComment.f_path != None)
+        else:
+            q = q.filter(ChangesetComment.line_no == None)\
+                .filter(ChangesetComment.f_path == None)
 
         if revision:
             q = q.filter(ChangesetComment.revision == revision)
@@ -285,12 +273,6 @@
             pull_request = self.__get_pull_request(pull_request)
             q = q.filter(ChangesetComment.pull_request == pull_request)
         else:
-            raise Exception('Please specify revision or pull_request_id')
-
-        comments = q.all()
+            raise Exception('Please specify either revision or pull_request')
 
-        paths = defaultdict(lambda: defaultdict(list))
-
-        for co in comments:
-            paths[co.f_path][co.line_no].append(co)
-        return paths.items()
+        return q.order_by(ChangesetComment.created_on).all()
--- a/kallithea/model/db.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/db.py	Tue Jun 09 22:46:40 2015 +0200
@@ -43,6 +43,7 @@
 from pylons.i18n.translation import lazy_ugettext as _
 
 from kallithea import DB_PREFIX
+from kallithea.lib.exceptions import DefaultUserException
 from kallithea.lib.vcs import get_backend
 from kallithea.lib.vcs.utils.helpers import get_scm
 from kallithea.lib.vcs.exceptions import VCSError
@@ -175,8 +176,8 @@
     }
     DEFAULT_UPDATE_URL = ''
 
-    app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    app_settings_name = Column("app_settings_name", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    app_settings_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    app_settings_name = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
     _app_settings_value = Column("app_settings_value", String(4096, convert_unicode=False), nullable=True, unique=None, default=None)
     _app_settings_type = Column("app_settings_type", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
 
@@ -338,11 +339,11 @@
     HOOK_PULL = 'outgoing.pull_logger'
     HOOK_PRE_PULL = 'preoutgoing.pre_pull'
 
-    ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    ui_section = Column("ui_section", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    ui_key = Column("ui_key", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    ui_value = Column("ui_value", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
+    ui_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    ui_section = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    ui_key = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    ui_value = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    ui_active = Column(Boolean(), nullable=True, unique=None, default=True)
 
     # def __init__(self, section='', key='', value=''):
     #     self.ui_section = section
@@ -401,20 +402,20 @@
     DEFAULT_USER = 'default'
     DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}'
 
-    user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    username = Column("username", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    password = Column("password", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    active = Column("active", Boolean(), nullable=True, unique=None, default=True)
-    admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
+    user_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    username = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    password = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    active = Column(Boolean(), nullable=True, unique=None, default=True)
+    admin = Column(Boolean(), nullable=True, unique=None, default=False)
     name = Column("firstname", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    lastname = Column("lastname", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    lastname = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
     _email = Column("email", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
-    extern_type = Column("extern_type", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    extern_name = Column("extern_name", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    api_key = Column("api_key", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    last_login = Column(DateTime(timezone=False), nullable=True, unique=None, default=None)
+    extern_type = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    extern_name = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    api_key = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    inherit_default_permissions = Column(Boolean(), nullable=False, unique=None, default=True)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
     _user_data = Column("user_data", LargeBinary(), nullable=True)  # JSON data
 
     user_log = relationship('UserLog')
@@ -438,7 +439,7 @@
     user_comments = relationship('ChangesetComment', cascade='all')
     #extra emails for this user
     user_emails = relationship('UserEmailMap', cascade='all')
-    #extra api keys
+    #extra API keys
     user_api_keys = relationship('UserApiKeys', cascade='all')
 
 
@@ -526,6 +527,18 @@
                                       self.user_id, self.username)
 
     @classmethod
+    def get_or_404(cls, id_, allow_default=True):
+        '''
+        Overridden version of BaseModel.get_or_404, with an extra check on
+        the default user.
+        '''
+        user = super(User, cls).get_or_404(id_)
+        if allow_default == False:
+            if user.username == User.DEFAULT_USER:
+                raise DefaultUserException
+        return user
+
+    @classmethod
     def get_by_username(cls, username, case_insensitive=False, cache=False):
         if case_insensitive:
             q = cls.query().filter(cls.username.ilike(username))
@@ -675,12 +688,12 @@
     )
     __mapper_args__ = {}
 
-    user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
-    api_key = Column("api_key", String(255, convert_unicode=False), nullable=False, unique=True)
-    description = Column('description', UnicodeText(1024))
-    expires = Column('expires', Float(53), nullable=False)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    user_api_key_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
+    api_key = Column(String(255, convert_unicode=False), nullable=False, unique=True)
+    description = Column(UnicodeText(1024))
+    expires = Column(Float(53), nullable=False)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
     user = relationship('User')
 
@@ -701,8 +714,8 @@
     )
     __mapper_args__ = {}
 
-    email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
+    email_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
     _email = Column("email", String(255, convert_unicode=False), nullable=True, unique=False, default=None)
     user = relationship('User')
 
@@ -732,10 +745,10 @@
     )
     __mapper_args__ = {}
 
-    ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
-    ip_addr = Column("ip_addr", String(255, convert_unicode=False), nullable=True, unique=False, default=None)
-    active = Column("active", Boolean(), nullable=True, unique=None, default=True)
+    ip_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
+    ip_addr = Column(String(255, convert_unicode=False), nullable=True, unique=False, default=None)
+    active = Column(Boolean(), nullable=True, unique=None, default=True)
     user = relationship('User')
 
     @classmethod
@@ -760,14 +773,14 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
     )
-    user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
-    username = Column("username", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True)
-    repository_name = Column("repository_name", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    user_ip = Column("user_ip", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    action = Column("action", UnicodeText(1200000, convert_unicode=False), nullable=True, unique=None, default=None)
-    action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
+    user_log_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
+    username = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    repository_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=True)
+    repository_name = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    user_ip = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    action = Column(UnicodeText(1200000, convert_unicode=False), nullable=True, unique=None, default=None)
+    action_date = Column(DateTime(timezone=False), nullable=True, unique=None, default=None)
 
     def __unicode__(self):
         return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
@@ -789,13 +802,13 @@
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
     )
 
-    users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    users_group_name = Column("users_group_name", String(255, convert_unicode=False), nullable=False, unique=True, default=None)
-    user_group_description = Column("user_group_description", String(10000, convert_unicode=False), nullable=True, unique=None, default=None)
-    users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
+    users_group_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    users_group_name = Column(String(255, convert_unicode=False), nullable=False, unique=True, default=None)
+    user_group_description = Column(String(10000, convert_unicode=False), nullable=True, unique=None, default=None)
+    users_group_active = Column(Boolean(), nullable=True, unique=None, default=None)
     inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
     _group_data = Column("group_data", LargeBinary(), nullable=True)  # JSON data
 
     members = relationship('UserGroupMember', cascade="all, delete-orphan")
@@ -879,9 +892,9 @@
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
     )
 
-    users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
+    users_group_member_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    users_group_id = Column(Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
     user = relationship('User')
     users_group = relationship('UserGroup')
@@ -900,14 +913,14 @@
     )
     PREFIX = 'ex_'  # prefix used in form to not conflict with already existing fields
 
-    repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
-    field_key = Column("field_key", String(250, convert_unicode=False))
-    field_label = Column("field_label", String(1024, convert_unicode=False), nullable=False)
-    field_value = Column("field_value", String(10000, convert_unicode=False), nullable=False)
-    field_desc = Column("field_desc", String(1024, convert_unicode=False), nullable=False)
-    field_type = Column("field_type", String(255), nullable=False, unique=None)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    repo_field_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    repository_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
+    field_key = Column(String(250, convert_unicode=False))
+    field_label = Column(String(1024, convert_unicode=False), nullable=False)
+    field_value = Column(String(10000, convert_unicode=False), nullable=False)
+    field_desc = Column(String(1024, convert_unicode=False), nullable=False)
+    field_type = Column(String(255), nullable=False, unique=None)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
     repository = relationship('Repository')
 
@@ -944,26 +957,26 @@
     STATE_PENDING = 'repo_state_pending'
     STATE_ERROR = 'repo_state_error'
 
-    repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    repo_name = Column("repo_name", String(255, convert_unicode=False), nullable=False, unique=True, default=None)
-    repo_state = Column("repo_state", String(255), nullable=True)
-
-    clone_uri = Column("clone_uri", String(255, convert_unicode=False), nullable=True, unique=False, default=None)
-    repo_type = Column("repo_type", String(255, convert_unicode=False), nullable=False, unique=False, default=None)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
-    private = Column("private", Boolean(), nullable=True, unique=None, default=None)
+    repo_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    repo_name = Column(String(255, convert_unicode=False), nullable=False, unique=True, default=None)
+    repo_state = Column(String(255), nullable=True)
+
+    clone_uri = Column(String(255, convert_unicode=False), nullable=True, unique=False, default=None)
+    repo_type = Column(String(255, convert_unicode=False), nullable=False, unique=False, default=None)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
+    private = Column(Boolean(), nullable=True, unique=None, default=None)
     enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
     enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
-    description = Column("description", String(10000, convert_unicode=False), nullable=True, unique=None, default=None)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
-    updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
+    description = Column(String(10000, convert_unicode=False), nullable=True, unique=None, default=None)
+    created_on = Column(DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
+    updated_on = Column(DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
     _landing_revision = Column("landing_revision", String(255, convert_unicode=False), nullable=False, unique=False, default=None)
-    enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
+    enable_locking = Column(Boolean(), nullable=False, unique=None, default=False)
     _locked = Column("locked", String(255, convert_unicode=False), nullable=True, unique=False, default=None)
     _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data
 
-    fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
-    group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
+    fork_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
+    group_id = Column(Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
 
     user = relationship('User')
     fork = relationship('Repository', remote_side=repo_id)
@@ -1277,7 +1290,7 @@
                 pass
 
         return get_clone_url(uri_tmpl=uri_tmpl,
-                             qualifed_home_url=qualified_home_url,
+                             qualified_home_url=qualified_home_url,
                              repo_name=self.repo_name,
                              repo_id=self.repo_id, **override)
 
@@ -1384,12 +1397,13 @@
 
         grouped = {}
         for stat in statuses.all():
-            pr_id = pr_repo = None
+            pr_id = pr_nice_id = pr_repo = None
             if stat.pull_request:
                 pr_id = stat.pull_request.pull_request_id
+                pr_nice_id = PullRequest.make_nice_id(pr_id)
                 pr_repo = stat.pull_request.other_repo.repo_name
             grouped[stat.revision] = [str(stat.status), stat.status_lbl,
-                                      pr_id, pr_repo]
+                                      pr_id, pr_repo, pr_nice_id]
         return grouped
 
     def _repo_size(self):
@@ -1463,13 +1477,13 @@
 
     SEP = ' &raquo; '
 
-    group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    group_name = Column("group_name", String(255, convert_unicode=False), nullable=False, unique=True, default=None)
-    group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
-    group_description = Column("group_description", String(10000, convert_unicode=False), nullable=True, unique=None, default=None)
-    enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    group_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    group_name = Column(String(255, convert_unicode=False), nullable=False, unique=True, default=None)
+    group_parent_id = Column(Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
+    group_description = Column(String(10000, convert_unicode=False), nullable=True, unique=None, default=None)
+    enable_locking = Column(Boolean(), nullable=False, unique=None, default=False)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
     repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
     users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
@@ -1497,7 +1511,7 @@
 
         repo_groups = []
         if show_empty_group:
-            repo_groups = [('-1', u'-- %s --' % _('top level'))]
+            repo_groups = [('-1', u'-- %s --' % _('Top level'))]
 
         repo_groups.extend([cls._generate_choice(x) for x in groups])
 
@@ -1728,9 +1742,9 @@
         'hg.create.repository': 1
     }
 
-    permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    permission_name = Column("permission_name", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    permission_longname = Column("permission_longname", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    permission_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    permission_name = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    permission_longname = Column(String(255, convert_unicode=False), nullable=True, unique=None, default=None)
 
     def __unicode__(self):
         return u"<%s('%s:%s')>" % (
@@ -1776,10 +1790,10 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
-    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
+    repo_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    repository_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 
     user = relationship('User')
     repository = relationship('Repository')
@@ -1805,10 +1819,10 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
-    user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
+    user_user_group_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    user_group_id = Column(Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
 
     user = relationship('User')
     user_group = relationship('UserGroup')
@@ -1834,9 +1848,9 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    user_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
     user = relationship('User')
     permission = relationship('Permission')
@@ -1852,10 +1866,10 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
-    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
+    users_group_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    users_group_id = Column(Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    repository_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 
     users_group = relationship('UserGroup')
     permission = relationship('Permission')
@@ -1882,10 +1896,10 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
-    user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
+    user_group_user_group_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    target_user_group_id = Column(Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    user_group_id = Column(Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
 
     target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id')
     user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id')
@@ -1911,9 +1925,9 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    users_group_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    users_group_id = Column(Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
     users_group = relationship('UserGroup')
     permission = relationship('Permission')
@@ -1927,10 +1941,10 @@
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
 
-    group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
-    group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    group_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
+    group_id = Column(Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
     user = relationship('User')
     group = relationship('RepoGroup')
@@ -1954,10 +1968,10 @@
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
 
-    users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
-    group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
-    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
+    users_group_repo_group_to_perm_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    users_group_id = Column(Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
+    group_id = Column(Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
+    permission_id = Column(Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
     users_group = relationship('UserGroup')
     permission = relationship('Permission')
@@ -1980,12 +1994,12 @@
          {'extend_existing': True, 'mysql_engine': 'InnoDB',
           'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
-    stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
-    commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
-    commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
-    languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
+    stat_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    repository_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
+    stat_on_revision = Column(Integer(), nullable=False)
+    commit_activity = Column(LargeBinary(1000000), nullable=False)#JSON data
+    commit_activity_combined = Column(LargeBinary(), nullable=False)#JSON data
+    languages = Column(LargeBinary(1000000), nullable=False)#JSON data
 
     repository = relationship('Repository', single_parent=True)
 
@@ -1999,11 +2013,11 @@
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
 
-    user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
+    user_following_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
     follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
-    follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
-    follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
+    follows_user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
+    follows_from = Column(DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
 
     user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
 
@@ -2024,14 +2038,14 @@
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
     )
     # cache_id, not used
-    cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
+    cache_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
     # cache_key as created by _get_cache_key
-    cache_key = Column("cache_key", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
+    cache_key = Column(String(255, convert_unicode=False))
     # cache_args is a repo_name
-    cache_args = Column("cache_args", String(255, convert_unicode=False), nullable=True, unique=None, default=None)
-    # instance sets cache_active True when it is caching,
-    # other instances set cache_active to False to indicate that this cache is invalid
-    cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
+    cache_args = Column(String(255, convert_unicode=False))
+    # instance sets cache_active True when it is caching, other instances set
+    # cache_active to False to indicate that this cache is invalid
+    cache_active = Column(Boolean(), nullable=True, unique=None, default=False)
 
     def __init__(self, cache_key, repo_name=''):
         self.cache_key = cache_key
@@ -2039,8 +2053,9 @@
         self.cache_active = False
 
     def __unicode__(self):
-        return u"<%s('%s:%s[%s]')>" % (self.__class__.__name__,
-                            self.cache_id, self.cache_key, self.cache_active)
+        return u"<%s('%s:%s[%s]')>" % (
+            self.__class__.__name__,
+            self.cache_id, self.cache_key, self.cache_active)
 
     def _cache_key_partition(self):
         prefix, repo_name, suffix = self.cache_key.partition(self.cache_args)
@@ -2143,24 +2158,25 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
     )
-    comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
-    repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
-    revision = Column('revision', String(40), nullable=True)
-    pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
-    line_no = Column('line_no', Unicode(10), nullable=True)
-    hl_lines = Column('hl_lines', Unicode(512), nullable=True)
-    f_path = Column('f_path', Unicode(1000), nullable=True)
-    user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
-    text = Column('text', UnicodeText(25000), nullable=False)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
-    modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    comment_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    repo_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False)
+    revision = Column(String(40))
+    pull_request_id = Column(Integer(), ForeignKey('pull_requests.pull_request_id'))
+    line_no = Column(Unicode(10))
+    hl_lines = Column(Unicode(512))
+    f_path = Column(Unicode(1000))
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False)
+    text = Column(UnicodeText(25000), nullable=False)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    modified_at = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
     author = relationship('User')
     repo = relationship('Repository')
     # status_change is frequently used directly in templates - make it a lazy
     # join to avoid fetching each related ChangesetStatus on demand.
     # There will only be one ChangesetStatus referencing each comment so the join will not explode.
-    status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='joined')
+    status_change = relationship('ChangesetStatus',
+                                 cascade="all, delete-orphan", lazy='joined')
     pull_request = relationship('PullRequest')
 
     @classmethod
@@ -2180,6 +2196,13 @@
             q = q.filter(cls.pull_request_id == pull_request_id)
         return q.all()
 
+    def url(self):
+        anchor = "comment-%s" % self.comment_id
+        import kallithea.lib.helpers as h
+        if self.revision:
+            return h.url('changeset_home', repo_name=self.repo.repo_name, revision=self.revision, anchor=anchor)
+        elif self.pull_request_id is not None:
+            return self.pull_request.url(anchor=anchor)
 
 class ChangesetStatus(Base, BaseModel):
     __tablename__ = 'changeset_statuses'
@@ -2205,15 +2228,15 @@
         (STATUS_UNDER_REVIEW, _("Under Review")),
     ]
 
-    changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True)
-    repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
-    revision = Column('revision', String(40), nullable=False)
-    status = Column('status', String(128), nullable=False, default=DEFAULT)
-    changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'))
-    modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
-    version = Column('version', Integer(), nullable=False, default=0)
-    pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
+    changeset_status_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    repo_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
+    revision = Column(String(40), nullable=False)
+    status = Column(String(128), nullable=False, default=DEFAULT)
+    changeset_comment_id = Column(Integer(), ForeignKey('changeset_comments.comment_id'))
+    modified_at = Column(DateTime(), nullable=False, default=datetime.datetime.now)
+    version = Column(Integer(), nullable=False, default=0)
+    pull_request_id = Column(Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
 
     author = relationship('User')
     repo = relationship('Repository')
@@ -2248,18 +2271,18 @@
     STATUS_NEW = u'new'
     STATUS_CLOSED = u'closed'
 
-    pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True)
-    title = Column('title', Unicode(255), nullable=True)
-    description = Column('description', UnicodeText(10240), nullable=True)
-    status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) # only for closedness, not approve/reject/etc
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
-    updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
+    pull_request_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    title = Column(Unicode(255), nullable=True)
+    description = Column(UnicodeText(10240))
+    status = Column(Unicode(255), nullable=False, default=STATUS_NEW) # only for closedness, not approve/reject/etc
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    updated_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
     _revisions = Column('revisions', UnicodeText(20500))  # 500 revisions max
-    org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
-    org_ref = Column('org_ref', Unicode(255), nullable=False)
-    other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
-    other_ref = Column('other_ref', Unicode(255), nullable=False)
+    org_repo_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False)
+    org_ref = Column(Unicode(255), nullable=False)
+    other_repo_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False)
+    other_ref = Column(Unicode(255), nullable=False)
 
     @hybrid_property
     def revisions(self):
@@ -2303,6 +2326,15 @@
             .first()
         return str(status.status) if status else ''
 
+    @classmethod
+    def make_nice_id(cls, pull_request_id):
+        '''Return pull request id nicely formatted for displaying'''
+        return '#%s' % pull_request_id
+
+    def nice_id(self):
+        '''Return the id of this pull request, nicely formatted for displaying'''
+        return self.make_nice_id(self.pull_request_id)
+
     def __json__(self):
         return dict(
             revisions=self.revisions
@@ -2334,9 +2366,9 @@
         self.user = user
         self.pull_request = pull_request
 
-    pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True)
-    pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False)
-    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True)
+    pull_requests_reviewers_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    pull_request_id = Column(Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=True)
 
     user = relationship('User')
     pull_request = relationship('PullRequest')
@@ -2357,11 +2389,11 @@
     TYPE_PULL_REQUEST = u'pull_request'
     TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment'
 
-    notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True)
-    subject = Column('subject', Unicode(512), nullable=True)
-    body = Column('body', UnicodeText(50000), nullable=True)
-    created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    notification_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    subject = Column(Unicode(512), nullable=True)
+    body = Column(UnicodeText(50000), nullable=True)
+    created_by = Column(Integer(), ForeignKey('users.user_id'), nullable=True)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
     type_ = Column('type', Unicode(255))
 
     created_by_user = relationship('User')
@@ -2369,8 +2401,8 @@
 
     @property
     def recipients(self):
-        return [x.user for x in UserNotification.query()\
-                .filter(UserNotification.notification == self)\
+        return [x.user for x in UserNotification.query()
+                .filter(UserNotification.notification == self)
                 .order_by(UserNotification.user_id.asc()).all()]
 
     @classmethod
@@ -2407,10 +2439,10 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True}
     )
-    user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True)
-    notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True)
-    read = Column('read', Boolean, default=False)
-    sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
+    user_id = Column(Integer(), ForeignKey('users.user_id'), primary_key=True)
+    notification_id = Column(Integer(), ForeignKey('notifications.notification_id'), primary_key=True)
+    read = Column(Boolean, default=False)
+    sent_on = Column(DateTime(timezone=False), nullable=True, unique=None)
 
     user = relationship('User')
     notification = relationship('Notification')
@@ -2432,14 +2464,14 @@
     GIST_PRIVATE = u'private'
     DEFAULT_FILENAME = u'gistfile1.txt'
 
-    gist_id = Column('gist_id', Integer(), primary_key=True)
-    gist_access_id = Column('gist_access_id', Unicode(250))
-    gist_description = Column('gist_description', UnicodeText(1024))
+    gist_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
+    gist_access_id = Column(Unicode(250))
+    gist_description = Column(UnicodeText(1024))
     gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True)
-    gist_expires = Column('gist_expires', Float(53), nullable=False)
-    gist_type = Column('gist_type', Unicode(128), nullable=False)
-    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
-    modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    gist_expires = Column(Float(53), nullable=False)
+    gist_type = Column(Unicode(128), nullable=False)
+    created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
+    modified_at = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
     owner = relationship('User')
 
@@ -2516,6 +2548,6 @@
         {'extend_existing': True, 'mysql_engine': 'InnoDB',
          'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
     )
-    repository_id = Column('repository_id', String(250), primary_key=True)
-    repository_path = Column('repository_path', Text)
-    version = Column('version', Integer)
+    repository_id = Column(String(250), nullable=False, unique=True, primary_key=True)
+    repository_path = Column(Text)
+    version = Column(Integer)
--- a/kallithea/model/notification.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/notification.py	Tue Jun 09 22:46:40 2015 +0200
@@ -248,25 +248,31 @@
         """
         #alias
         _n = notification
-        _map = {
-            _n.TYPE_CHANGESET_COMMENT: _('%(user)s commented on changeset at %(when)s'),
-            _n.TYPE_MESSAGE: _('%(user)s sent message at %(when)s'),
-            _n.TYPE_MENTION: _('%(user)s mentioned you at %(when)s'),
-            _n.TYPE_REGISTRATION: _('%(user)s registered in Kallithea at %(when)s'),
-            _n.TYPE_PULL_REQUEST: _('%(user)s opened new pull request at %(when)s'),
-            _n.TYPE_PULL_REQUEST_COMMENT: _('%(user)s commented on pull request at %(when)s')
-        }
-        tmpl = _map[notification.type_]
 
         if show_age:
-            when = h.age(notification.created_on)
+            return {
+                    _n.TYPE_CHANGESET_COMMENT: _('%(user)s commented on changeset %(age)s'),
+                    _n.TYPE_MESSAGE: _('%(user)s sent message %(age)s'),
+                    _n.TYPE_MENTION: _('%(user)s mentioned you %(age)s'),
+                    _n.TYPE_REGISTRATION: _('%(user)s registered in Kallithea %(age)s'),
+                    _n.TYPE_PULL_REQUEST: _('%(user)s opened new pull request %(age)s'),
+                    _n.TYPE_PULL_REQUEST_COMMENT: _('%(user)s commented on pull request %(age)s'),
+                }[notification.type_] % dict(
+                    user=notification.created_by_user.username,
+                    age=h.age(notification.created_on),
+                )
         else:
-            when = h.fmt_date(notification.created_on)
-
-        return tmpl % dict(
-            user=notification.created_by_user.username,
-            when=when,
-            )
+            return {
+                    _n.TYPE_CHANGESET_COMMENT: _('%(user)s commented on changeset at %(when)s'),
+                    _n.TYPE_MESSAGE: _('%(user)s sent message at %(when)s'),
+                    _n.TYPE_MENTION: _('%(user)s mentioned you at %(when)s'),
+                    _n.TYPE_REGISTRATION: _('%(user)s registered in Kallithea at %(when)s'),
+                    _n.TYPE_PULL_REQUEST: _('%(user)s opened new pull request at %(when)s'),
+                    _n.TYPE_PULL_REQUEST_COMMENT: _('%(user)s commented on pull request at %(when)s'),
+                }[notification.type_] % dict(
+                    user=notification.created_by_user.username,
+                    when=h.fmt_date(notification.created_on),
+                )
 
 
 class EmailNotificationModel(BaseModel):
@@ -293,13 +299,13 @@
             self.TYPE_PULL_REQUEST_COMMENT: 'pull_request_comment',
         }
         self._subj_map = {
-            self.TYPE_CHANGESET_COMMENT: _('Comment on %(repo_name)s changeset %(short_id)s on %(branch)s by %(comment_username)s'),
+            self.TYPE_CHANGESET_COMMENT: _('[Comment from %(comment_username)s] %(repo_name)s changeset %(short_id)s on %(branch)s'),
             self.TYPE_MESSAGE: 'Test Message',
             # self.TYPE_PASSWORD_RESET
             self.TYPE_REGISTRATION: _('New user %(new_username)s registered'),
             # self.TYPE_DEFAULT
-            self.TYPE_PULL_REQUEST: _('Review request on %(repo_name)s pull request #%(pr_id)s from %(ref)s by %(pr_username)s'),
-            self.TYPE_PULL_REQUEST_COMMENT: _('Comment on %(repo_name)s pull request #%(pr_id)s from %(ref)s by %(comment_username)s'),
+            self.TYPE_PULL_REQUEST: _('[Added by %(pr_username)s] %(repo_name)s pull request %(pr_nice_id)s from %(ref)s'),
+            self.TYPE_PULL_REQUEST_COMMENT: _('[Comment from %(comment_username)s] %(repo_name)s pull request %(pr_nice_id)s from %(ref)s'),
         }
 
     def get_email_description(self, type_, **kwargs):
@@ -314,7 +320,10 @@
             raise
         l = [safe_unicode(x) for x in [kwargs.get('status_change'), kwargs.get('closing_pr') and _('Closing')] if x]
         if l:
-            subj += ' (%s)' % (', '.join(l))
+            if subj.startswith('['):
+                subj = '[' + ', '.join(l) + ': ' + subj[1:]
+            else:
+                subj = '[' + ', '.join(l) + '] ' + subj
         return subj
 
     def get_email_tmpl(self, type_, content_type, **kwargs):
--- a/kallithea/model/pull_request.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/pull_request.py	Tue Jun 09 22:46:40 2015 +0200
@@ -93,7 +93,7 @@
         #reset state to under-review
         from kallithea.model.comment import ChangesetCommentsModel
         comment = ChangesetCommentsModel().create(
-            text=u'Auto status change to %s' % (ChangesetStatus.get_status_lbl(ChangesetStatus.STATUS_UNDER_REVIEW)),
+            text=u'',
             repo=org_repo,
             user=new.author,
             pull_request=new,
@@ -130,10 +130,10 @@
                                       h.canonical_hostname())]
         subject = safe_unicode(
             h.link_to(
-              _('%(user)s wants you to review pull request #%(pr_id)s: %(pr_title)s') % \
+              _('%(user)s wants you to review pull request %(pr_nice_id)s: %(pr_title)s') % \
                 {'user': pr.author.username,
                  'pr_title': pr.title,
-                 'pr_id': pr.pull_request_id},
+                 'pr_nice_id': pr.nice_id()},
                 pr_url)
             )
         body = pr.description
@@ -145,7 +145,7 @@
             'pr_url': pr_url,
             'pr_revisions': revision_data,
             'repo_name': pr.other_repo.repo_name,
-            'pr_id': pr.pull_request_id,
+            'pr_nice_id': pr.nice_id(),
             'ref': org_ref_name,
             'pr_username': pr.author.username,
             'threading': threading,
--- a/kallithea/model/user.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/user.py	Tue Jun 09 22:46:40 2015 +0200
@@ -60,16 +60,7 @@
         return self._get_user(user)
 
     def get_by_username(self, username, cache=False, case_insensitive=False):
-
-        if case_insensitive:
-            user = self.sa.query(User).filter(User.username.ilike(username))
-        else:
-            user = self.sa.query(User)\
-                .filter(User.username == username)
-        if cache:
-            user = user.options(FromCache("sql_cache_short",
-                                          "get_user_%s" % username))
-        return user.scalar()
+        return User.get_by_username(username, case_insensitive, cache)
 
     def get_by_email(self, email, cache=False, case_insensitive=False):
         return User.get_by_email(email, case_insensitive, cache)
@@ -81,12 +72,17 @@
         if not cur_user:
             cur_user = getattr(get_current_authuser(), 'username', None)
 
-        from kallithea.lib.hooks import log_create_user, check_allowed_create_user
+        from kallithea.lib.hooks import log_create_user, \
+            check_allowed_create_user
         _fd = form_data
         user_data = {
-            'username': _fd['username'], 'password': _fd['password'],
-            'email': _fd['email'], 'firstname': _fd['firstname'], 'lastname': _fd['lastname'],
-            'active': _fd['active'], 'admin': False
+            'username': _fd['username'],
+            'password': _fd['password'],
+            'email': _fd['email'],
+            'firstname': _fd['firstname'],
+            'lastname': _fd['lastname'],
+            'active': _fd['active'],
+            'admin': False
         }
         # raises UserCreationError if it's not allowed
         check_allowed_create_user(user_data, cur_user)
@@ -128,7 +124,8 @@
             cur_user = getattr(get_current_authuser(), 'username', None)
 
         from kallithea.lib.auth import get_crypt_password, check_password
-        from kallithea.lib.hooks import log_create_user, check_allowed_create_user
+        from kallithea.lib.hooks import log_create_user, \
+            check_allowed_create_user
         user_data = {
             'username': username, 'password': password,
             'email': email, 'firstname': firstname, 'lastname': lastname,
@@ -153,8 +150,10 @@
             new_user.admin = admin
             new_user.email = email
             new_user.active = active
-            new_user.extern_name = safe_unicode(extern_name) if extern_name else None
-            new_user.extern_type = safe_unicode(extern_type) if extern_type else None
+            new_user.extern_name = safe_unicode(extern_name) \
+                if extern_name else None
+            new_user.extern_type = safe_unicode(extern_type) \
+                if extern_type else None
             new_user.name = firstname
             new_user.lastname = lastname
 
@@ -162,12 +161,13 @@
                 new_user.api_key = generate_api_key(username)
 
             # set password only if creating an user or password is changed
-            password_change = new_user.password and not check_password(password,
-                                                            new_user.password)
+            password_change = new_user.password and \
+                not check_password(password, new_user.password)
             if not edit or password_change:
                 reason = 'new password' if edit else 'new user'
                 log.debug('Updating password reason=>%s' % (reason,))
-                new_user.password = get_crypt_password(password) if password else None
+                new_user.password = get_crypt_password(password) \
+                    if password else None
 
             self.sa.add(new_user)
 
@@ -192,14 +192,17 @@
 
         # notification to admins
         subject = _('New user registration')
-        body = ('New user registration\n'
-                '---------------------\n'
-                '- Username: %s\n'
-                '- Full Name: %s\n'
-                '- Email: %s\n')
-        body = body % (new_user.username, new_user.full_name, new_user.email)
+        body = (
+            'New user registration\n'
+            '---------------------\n'
+            '- Username: {user.username}\n'
+            '- Full Name: {user.full_name}\n'
+            '- Email: {user.email}\n'
+            ).format(user=new_user)
         edit_url = h.canonical_url('edit_user', id=new_user.user_id)
-        email_kwargs = {'registered_user_url': edit_url, 'new_username': new_user.username}
+        email_kwargs = {
+            'registered_user_url': edit_url,
+            'new_username': new_user.username}
         NotificationModel().create(created_by=new_user, subject=subject,
                                    body=body, recipients=None,
                                    type_=Notification.TYPE_REGISTRATION,
@@ -253,29 +256,25 @@
         if user.username == User.DEFAULT_USER:
             raise DefaultUserException(
                 _(u"You can't remove this user since it's"
-                  " crucial for entire application")
-            )
+                  " crucial for entire application"))
         if user.repositories:
             repos = [x.repo_name for x in user.repositories]
             raise UserOwnsReposException(
                 _(u'User "%s" still owns %s repositories and cannot be '
                   'removed. Switch owners or remove those repositories: %s')
-                % (user.username, len(repos), ', '.join(repos))
-            )
+                % (user.username, len(repos), ', '.join(repos)))
         if user.repo_groups:
             repogroups = [x.group_name for x in user.repo_groups]
-            raise UserOwnsReposException(
-                _(u'User "%s" still owns %s repository groups and cannot be '
-                  'removed. Switch owners or remove those repository groups: %s')
-                % (user.username, len(repogroups), ', '.join(repogroups))
-            )
+            raise UserOwnsReposException(_(
+                'User "%s" still owns %s repository groups and cannot be '
+                'removed. Switch owners or remove those repository groups: %s')
+                % (user.username, len(repogroups), ', '.join(repogroups)))
         if user.user_groups:
             usergroups = [x.users_group_name for x in user.user_groups]
             raise UserOwnsReposException(
-                _(u'User "%s" still owns %s user groups and cannot be '
+                _('User "%s" still owns %s user groups and cannot be '
                   'removed. Switch owners or remove those user groups: %s')
-                % (user.username, len(usergroups), ', '.join(usergroups))
-            )
+                % (user.username, len(usergroups), ', '.join(usergroups)))
         self.sa.delete(user)
 
         from kallithea.lib.hooks import log_delete_user
@@ -290,16 +289,17 @@
         user = User.get_by_email(user_email)
         if user:
             log.debug('password reset user found %s' % user)
-            link = h.canonical_url('reset_password_confirmation', key=user.api_key)
+            link = h.canonical_url('reset_password_confirmation',
+                                   key=user.api_key)
             reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
-            body = EmailNotificationModel().get_email_tmpl(reg_type,
-                                                           'txt',
-                                                           user=user.short_contact,
-                                                           reset_url=link)
-            html_body = EmailNotificationModel().get_email_tmpl(reg_type,
-                                                           'html',
-                                                           user=user.short_contact,
-                                                           reset_url=link)
+            body = EmailNotificationModel().get_email_tmpl(
+                reg_type, 'txt',
+                user=user.short_contact,
+                reset_url=link)
+            html_body = EmailNotificationModel().get_email_tmpl(
+                reg_type, 'html',
+                user=user.short_contact,
+                reset_url=link)
             log.debug('sending email')
             run_task(tasks.send_email, [user_email],
                      _("Password reset link"), body, html_body)
@@ -314,8 +314,8 @@
         from kallithea.lib import auth
         user_email = data['email']
         user = User.get_by_email(user_email)
-        new_passwd = auth.PasswordGenerator().gen_password(8,
-                        auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
+        new_passwd = auth.PasswordGenerator().gen_password(
+            8, auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
         if user:
             user.password = auth.get_crypt_password(new_passwd)
             Session().add(user)
@@ -340,7 +340,7 @@
 
         :param auth_user: instance of user to set attributes
         :param user_id: user id to fetch by
-        :param api_key: api key to fetch by
+        :param api_key: API key to fetch by
         :param username: username to fetch by
         """
         if user_id is None and api_key is None and username is None:
@@ -401,12 +401,10 @@
         user = self._get_user(user)
         perm = self._get_perm(perm)
 
-        obj = UserToPerm.query()\
-                .filter(UserToPerm.user == user)\
-                .filter(UserToPerm.permission == perm)\
-                .scalar()
-        if obj:
-            self.sa.delete(obj)
+        UserToPerm.query().filter(
+            UserToPerm.user == user,
+            UserToPerm.permission == perm,
+        ).delete()
 
     def add_extra_email(self, user, email):
         """
@@ -440,7 +438,7 @@
 
     def add_extra_ip(self, user, ip):
         """
-        Adds ip address to UserIpMap
+        Adds IP address to UserIpMap
 
         :param user:
         :param ip:
@@ -458,7 +456,7 @@
 
     def delete_extra_ip(self, user, ip_id):
         """
-        Removes ip address from UserIpMap
+        Removes IP address from UserIpMap
 
         :param user:
         :param ip_id:
--- a/kallithea/model/validators.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/model/validators.py	Tue Jun 09 22:46:40 2015 +0200
@@ -814,7 +814,7 @@
 def ValidIp():
     class _validator(CIDR):
         messages = dict(
-            badFormat=_('Please enter a valid IPv4 or IpV6 address'),
+            badFormat=_('Please enter a valid IPv4 or IPv6 address'),
             illegalBits=_('The network size (bits) must be within the range'
                 ' of 0-32 (not %(bits)r)')
         )
@@ -836,7 +836,7 @@
         def validate_python(self, value, state):
             try:
                 addr = value.strip()
-                #this raises an ValueError if address is not IpV4 or IpV6
+                #this raises an ValueError if address is not IPv4 or IPv6
                 ipaddr.IPNetwork(address=addr)
             except ValueError:
                 raise formencode.Invalid(self.message('badFormat', state),
--- a/kallithea/public/css/contextbar.css	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/public/css/contextbar.css	Tue Jun 09 22:46:40 2015 +0200
@@ -19,19 +19,19 @@
 
 .icon-diff-M:before {
     font-family: 'kallithea';
-    content: '\e805';
+    content: '\22a1';
     color: #d0b44c;
 }
 
 .icon-diff-D:before {
     font-family: 'kallithea';
-    content: '\e807';
+    content: '\229f';
     color: #bd2c00;
 }
 
 .icon-diff-A:before {
     font-family: 'kallithea';
-    content: '\e806';
+    content: '\229e';
     color: #6cc644;
 }
 
@@ -279,7 +279,8 @@
 #revision-changer:before,
 #context-pages a.childs:after,
 #context-pages a.dropdown:after {
-    content: ' \25BE';
+    font-family: 'kallithea';
+    content: ' \23f7';
 }
 #context-pages a.childs {
     padding-right: 30px;
--- a/kallithea/public/css/style.css	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/public/css/style.css	Tue Jun 09 22:46:40 2015 +0200
@@ -253,7 +253,8 @@
 h4:hover > a.permalink,
 h5:hover > a.permalink,
 h6:hover > a.permalink,
-div:hover > a.permalink {
+div:hover > a.permalink,
+div:hover > span > a.permalink {
     visibility: visible;
 }
 
@@ -510,7 +511,7 @@
 
 td.quick_repo_menu:before {
     font-family: "kallithea";
-    content: "\e80f";           /* triangle-right */
+    content: "\23f5";           /* triangle-right */
     margin-left: 3px;
     padding-right: 3px;
 }
@@ -523,7 +524,7 @@
 
 td.quick_repo_menu.active:before {
     font-family: "kallithea";
-    content: "\e80d";           /* triangle-down */
+    content: "\23f7";           /* triangle-down */
     margin-left: 1px;
     padding-right: 1px;
 }
@@ -735,12 +736,12 @@
 
 .yui-skin-sam th.yui-dt-asc .yui-dt-liner:after {
     font-family: "kallithea";
-    content: "\e810";           /* triangle-up */
+    content: "\23f6";           /* triangle-up */
 }
 
 .yui-skin-sam th.yui-dt-desc .yui-dt-liner:after {
     font-family: "kallithea";
-    content: "\e80d";           /* triangle-down */
+    content: "\23f7";           /* triangle-down */
 }
 
 tbody .yui-dt-editable { cursor: pointer }
@@ -1871,7 +1872,7 @@
     padding: 20px;
 }
 
-#login div.form div.fields div.field div.label {
+#login div.form div.form-horizontal div.form-group > label {
     width: 173px;
     float: left;
     text-align: right;
@@ -1879,7 +1880,7 @@
     padding: 5px 0 0 5px;
 }
 
-#login div.form div.fields div.field div.input input {
+#login div.form div.form-horizontal div.form-group div input {
     background: #FFF;
     border-top: 1px solid #b3b3b3;
     border-left: 1px solid #b3b3b3;
@@ -1891,20 +1892,16 @@
     padding: 7px 7px 6px;
 }
 
-#login div.form div.fields div.buttons {
-    clear: both;
-    overflow: hidden;
-    border-top: 1px solid #DDD;
-    text-align: right;
-    margin: 0;
-    padding: 10px 0 0;
+#login div.form .buttons {
+    float: right;
 }
 
 #login div.form div.links {
     clear: both;
     overflow: hidden;
     margin: 10px 0 0;
-    padding: 0 0 2px;
+    border-top: 1px solid #DDD;
+    padding: 10px 0 0;
 }
 
 .user-menu {
@@ -2310,6 +2307,14 @@
     margin-right: -3px;
 }
 
+.changeset-logical-index {
+    color: #666666;
+    font-style: italic;
+    font-size: 85%;
+    padding-right: 0.5em;
+    text-align: right;
+}
+
 .changeset_hash {
     color: #000000;
 }
@@ -2690,15 +2695,11 @@
     float: left;
     padding: 2px 0px 0px 2px;
 }
-.changeset-status-container .changeset-status-lbl {
-    float: left;
-    padding: 3px 4px 0px 0px
-}
 .code-header .changeset-status-container .changeset-status-lbl {
     float: left;
     padding: 0px 4px 0px 0px;
 }
-.changeset-status-container .changeset-status-ico {
+.changeset-status-container div.changeset-status-ico {
     float: left;
 }
 .code-header .changeset-status-container .changeset-status-ico,
@@ -3719,7 +3720,8 @@
 }
 
 .repo-switcher .select2-chosen:after {
-    content: ' \25BE';
+    font-family: 'kallithea';
+    content: ' \23f7';
 }
 
 .repo-switcher-dropdown.select2-drop.select2-drop-active {
@@ -3758,8 +3760,8 @@
 }
 
 #content div.box div.form div.fields,
-#login div.form,
-#login div.form div.fields,
+#login div.form-horizontal,
+#login div.form-horizontal div.form-group,
 #register div.form,
 #register div.form div.fields {
     clear: both;
@@ -3769,7 +3771,7 @@
 }
 
 #content div.box div.form div.fields div.field div.label span,
-#login div.form div.fields div.field div.label span,
+#login div.form div.form-horizontal div.form-group div.label span,
 #register div.form div.fields div.field div.label span {
     height: 1%;
     display: block;
@@ -3779,7 +3781,7 @@
 }
 
 #content div.box div.form div.fields div.field div.input input.error,
-#login div.form div.fields div.field div.input input.error,
+#login div.form div.form-horizontal div.form-group div.input input.error,
 #register div.form div.fields div.field div.input input.error {
     background: #FBE3E4;
     border-top: 1px solid #e1b2b3;
@@ -3789,7 +3791,7 @@
 }
 
 #content div.box div.form div.fields div.field div.input input.success,
-#login div.form div.fields div.field div.input input.success,
+#login div.form div.form-horizontal div.form-group div.input input.success,
 #register div.form div.fields div.field div.input input.success {
     background: #E6EFC2;
     border-top: 1px solid #cebb98;
@@ -3891,7 +3893,7 @@
 }
 
 #content div.box div.action div.button,
-#login div.form div.fields div.field div.input div.link,
+#login div.form div.form-horizontal div.form-group div.input div.link,
 #register div.form div.fields div.field div.input div.link {
     text-align: right;
     margin: 6px 0 0;
@@ -3960,7 +3962,7 @@
     padding: 0;
 }
 
-#login div.form div.fields div.field,
+#login div.form div.form-horizontal div.form-group,
 #register div.form div.fields div.field {
     clear: both;
     overflow: hidden;
@@ -3968,7 +3970,7 @@
     padding: 0 0 10px;
 }
 
-#login div.form div.fields div.field span.error-message,
+#login div.form div.form-horizontal div.form-group span.error-message,
 #register div.form div.fields div.field span.error-message {
     height: 1%;
     display: block;
@@ -3978,36 +3980,36 @@
     max-width: 320px;
 }
 
-#login div.form div.fields div.field div.label label,
+#login div.form div.form-horizontal div.form-group label,
 #register div.form div.fields div.field div.label label {
     color: #000;
     font-weight: 700;
 }
 
-#login div.form div.fields div.field div.input,
+#login div.form div.form-horizontal div.form-group div,
 #register div.form div.fields div.field div.input {
     float: left;
     margin: 0;
     padding: 0;
 }
 
-#login div.form div.fields div.field div.input input.large {
+#login div.form div.form-horizontal div.form-group div input.large {
     width: 250px;
 }
 
-#login div.form div.fields div.field div.checkbox,
+#login div.form div.form-horizontal div.form-group div.checkbox,
 #register div.form div.fields div.field div.checkbox {
     margin: 0 0 0 184px;
     padding: 0;
 }
 
-#login div.form div.fields div.field div.checkbox label,
+#login div.form div.form-horizontal div.form-group div.checkbox label,
 #register div.form div.fields div.field div.checkbox label {
     color: #565656;
     font-weight: 700;
 }
 
-#login div.form div.fields div.buttons input,
+#login div.form div.buttons input,
 #register div.form div.fields div.buttons input {
     color: #000;
     font-size: 1em;
@@ -4222,7 +4224,7 @@
     clear: both;
     overflow: hidden;
     margin: 0;
-    padding: 0 20px 10px;
+    padding: 0 20px;
 }
 
 div.rst-block h1,
@@ -4350,6 +4352,10 @@
     font-size: 16px;
 }
 
+.automatic-comment {
+    font-style: italic;
+}
+
 /** comment form **/
 
 .status-block {
@@ -4972,7 +4978,7 @@
     position: relative;
     width: 0;
 }
- 
+
 table.code-difftable .add .code pre:before {
     content: "+";
     color: #080;
@@ -4981,7 +4987,7 @@
     position: relative;
     width: 0;
 }
- 
+
 table.code-difftable .unmod .code pre:before {
     content: " ";
     float: left;
@@ -4989,7 +4995,7 @@
     position: relative;
     width: 0;
 }
- 
+
 .add-bubble {
     position: relative;
     display: none;
@@ -5026,7 +5032,7 @@
     font-size: 14px;
     color: #ffffff;
     font-family: "kallithea";
-    content: '\e80c';
+    content: '\1f5ea';
 }
 
 .add-bubble div:hover {
@@ -5067,8 +5073,8 @@
     margin: 5px;
 }
 
-div.prev-next-comment div.prev-comment,
-div.prev-next-comment div.next-comment {
+div.comment-prev-next-links div.prev-comment,
+div.comment-prev-next-links div.next-comment {
     display: inline-block;
     min-width: 150px;
     margin: 3px 6px;
--- a/kallithea/public/fontello/config.json	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/public/fontello/config.json	Tue Jun 09 22:46:40 2015 +0200
@@ -401,7 +401,7 @@
     {
       "uid": "c04672812513206682a859166c207252",
       "css": "clippy",
-      "code": 59419,
+      "code": 128203,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -457,7 +457,7 @@
     {
       "uid": "c9e14800494dc6027b3dcee0817cf984",
       "css": "code",
-      "code": 59425,
+      "code": 8596,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -485,7 +485,7 @@
     {
       "uid": "7aeda197b5b0fba630669530807d736d",
       "css": "comment",
-      "code": 59403,
+      "code": 128489,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -499,7 +499,7 @@
     {
       "uid": "28655242f029e97efd1bf5379e22c4ba",
       "css": "comment-discussion",
-      "code": 59404,
+      "code": 128490,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -555,7 +555,7 @@
     {
       "uid": "776af96a4db73c51c13fd256f12d6f40",
       "css": "database",
-      "code": 59392,
+      "code": 9923,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -639,7 +639,7 @@
     {
       "uid": "ccc8f787411138446b85c9fe52e33b8b",
       "css": "diff-added",
-      "code": 59398,
+      "code": 8862,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -667,7 +667,7 @@
     {
       "uid": "2672a84540d3632649f01108e2db0341",
       "css": "diff-modified",
-      "code": 59397,
+      "code": 8865,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -681,7 +681,7 @@
     {
       "uid": "1ce39df7ee1648c4054633b371546367",
       "css": "diff-removed",
-      "code": 59399,
+      "code": 8863,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -905,7 +905,7 @@
     {
       "uid": "c59600c892bd7e46476f38e89812fbbf",
       "css": "gear",
-      "code": 59441,
+      "code": 9965,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -1031,7 +1031,7 @@
     {
       "uid": "b00e349d8883c0b89796940a9913e8e8",
       "css": "globe",
-      "code": 59410,
+      "code": 127758,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -1283,7 +1283,7 @@
     {
       "uid": "3617d121a15ef91892d5083aeead6ce3",
       "css": "key",
-      "code": 59430,
+      "code": 128273,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -1591,7 +1591,7 @@
     {
       "uid": "ef6263a57a35ecee2f8ddda2fe20dcab",
       "css": "move-down",
-      "code": 59395,
+      "code": 11123,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -1633,7 +1633,7 @@
     {
       "uid": "13e7ebf511552da48a5bc1d2e7cf6de2",
       "css": "move-up",
-      "code": 59396,
+      "code": 11121,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2123,7 +2123,7 @@
     {
       "uid": "809bb7ea7bf6ca7e94029eae402f922f",
       "css": "search",
-      "code": 59435,
+      "code": 128269,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2333,7 +2333,7 @@
     {
       "uid": "92dd16866a2367537f47bec5ee11484f",
       "css": "tools",
-      "code": 59400,
+      "code": 128736,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2347,7 +2347,7 @@
     {
       "uid": "448bfec39235117b6a7e3e8d46aa184f",
       "css": "trashcan",
-      "code": 59433,
+      "code": 128465,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2361,7 +2361,7 @@
     {
       "uid": "ebbb1978bedc8e562ab0d462a832919f",
       "css": "triangle-down",
-      "code": 59405,
+      "code": 9207,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2375,7 +2375,7 @@
     {
       "uid": "814cb1fe473de29d20b3d4e366ed434b",
       "css": "triangle-left",
-      "code": 59406,
+      "code": 9204,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2389,7 +2389,7 @@
     {
       "uid": "d191392505c6a27bbeafd2d283a18d23",
       "css": "triangle-right",
-      "code": 59407,
+      "code": 9205,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2403,7 +2403,7 @@
     {
       "uid": "14bdc9ddaebbaecf5bad552a14cae637",
       "css": "triangle-up",
-      "code": 59408,
+      "code": 9206,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2501,7 +2501,7 @@
     {
       "uid": "16b70cc2a5fbff7de2cbf73498e25b5c",
       "css": "keyhole-circled",
-      "code": 59426,
+      "code": 128272,
       "src": "custom_icons",
       "selected": true,
       "svg": {
@@ -2543,91 +2543,91 @@
     {
       "uid": "d73eceadda1f594cec0536087539afbf",
       "css": "heart",
-      "code": 59436,
+      "code": 9829,
       "src": "fontawesome"
     },
     {
       "uid": "f3dc2d6d8fe9cf9ebff84dc260888cdf",
       "css": "heart-empty",
-      "code": 59437,
+      "code": 9825,
       "src": "fontawesome"
     },
     {
       "uid": "8b80d36d4ef43889db10bc1f0dc9a862",
       "css": "user",
-      "code": 59438,
+      "code": 128100,
       "src": "fontawesome"
     },
     {
       "uid": "31972e4e9d080eaa796290349ae6c1fd",
       "css": "users",
-      "code": 59439,
+      "code": 128101,
       "src": "fontawesome"
     },
     {
       "uid": "12f4ece88e46abd864e40b35e05b11cd",
       "css": "ok",
-      "code": 59440,
+      "code": 128504,
       "src": "fontawesome"
     },
     {
       "uid": "43ab845088317bd348dee1d975700c48",
       "css": "ok-circled",
-      "code": 59402,
+      "code": 128505,
       "src": "fontawesome"
     },
     {
       "uid": "5211af474d3a9848f67f945e2ccaf143",
       "css": "cancel",
-      "code": 59434,
+      "code": 128500,
       "src": "fontawesome"
     },
     {
       "uid": "0f4cae16f34ae243a6144c18a003f2d8",
       "css": "cancel-circled",
-      "code": 59401,
+      "code": 128501,
       "src": "fontawesome"
     },
     {
       "uid": "44e04715aecbca7f266a17d5a7863c68",
       "css": "plus",
-      "code": 59471,
+      "code": 10133,
       "src": "fontawesome"
     },
     {
       "uid": "4ba33d2607902cf690dd45df09774cb0",
       "css": "plus-circled",
-      "code": 59468,
+      "code": 8853,
       "src": "fontawesome"
     },
     {
       "uid": "861ab06e455e2de3232ebef67d60d708",
       "css": "minus",
-      "code": 59472,
+      "code": 10134,
       "src": "fontawesome"
     },
     {
       "uid": "eeadb020bb75d089b25d8424aabe19e0",
       "css": "minus-circled",
-      "code": 59469,
+      "code": 8854,
       "src": "fontawesome"
     },
     {
       "uid": "c1f1975c885aa9f3dad7810c53b82074",
       "css": "lock",
-      "code": 59450,
+      "code": 128274,
       "src": "fontawesome"
     },
     {
       "uid": "05376be04a27d5a46e855a233d6e8508",
       "css": "lock-open-alt",
-      "code": 59451,
+      "code": 128275,
       "src": "fontawesome"
     },
     {
       "uid": "c5fd349cbd3d23e4ade333789c29c729",
       "css": "eye",
-      "code": 59474,
+      "code": 128065,
       "src": "fontawesome"
     },
     {
@@ -2639,7 +2639,7 @@
     {
       "uid": "3db5347bd219f3bce6025780f5d9ef45",
       "css": "tag",
-      "code": 59452,
+      "code": 128278,
       "src": "fontawesome"
     },
     {
@@ -2675,25 +2675,25 @@
     {
       "uid": "d35a1d35efeb784d1dc9ac18b9b6c2b6",
       "css": "pencil",
-      "code": 59458,
+      "code": 128393,
       "src": "fontawesome"
     },
     {
       "uid": "44fae3bfdd54754dc68ec50d37efea37",
       "css": "pencil-squared",
-      "code": 59460,
+      "code": 128394,
       "src": "fontawesome"
     },
     {
       "uid": "41087bc74d4b20b55059c60a33bf4008",
       "css": "edit",
-      "code": 59461,
+      "code": 128395,
       "src": "fontawesome"
     },
     {
       "uid": "1b5a5d7b7e3c71437f5a26befdd045ed",
       "css": "doc",
-      "code": 59443,
+      "code": 128453,
       "src": "fontawesome"
     },
     {
@@ -2705,7 +2705,7 @@
     {
       "uid": "5408be43f7c42bccee419c6be53fdef5",
       "css": "doc-text",
-      "code": 59445,
+      "code": 128456,
       "src": "fontawesome"
     },
     {
@@ -2729,25 +2729,25 @@
     {
       "uid": "f8aa663c489bcbd6e68ec8147dca841e",
       "css": "folder",
-      "code": 59475,
+      "code": 128448,
       "src": "fontawesome"
     },
     {
       "uid": "c95735c17a10af81448c7fed98a04546",
       "css": "folder-open",
-      "code": 59462,
+      "code": 128449,
       "src": "fontawesome"
     },
     {
       "uid": "b091a8bd0fdade174951f17d936f51e4",
       "css": "folder-empty",
-      "code": 59476,
+      "code": 128193,
       "src": "fontawesome"
     },
     {
       "uid": "6533bdc16ab201eb3f3b27ce989cab33",
       "css": "folder-open-empty",
-      "code": 59463,
+      "code": 128194,
       "src": "fontawesome"
     },
     {
@@ -2771,13 +2771,13 @@
     {
       "uid": "98687378abd1faf8f6af97c254eb6cd6",
       "css": "cog-alt",
-      "code": 59442,
+      "code": 9881,
       "src": "fontawesome"
     },
     {
       "uid": "5bb103cd29de77e0e06a52638527b575",
       "css": "wrench",
-      "code": 59479,
+      "code": 128295,
       "src": "fontawesome"
     },
     {
@@ -2789,19 +2789,19 @@
     {
       "uid": "598a5f2bcf3521d1615de8e1881ccd17",
       "css": "clock",
-      "code": 59449,
+      "code": 8986,
       "src": "fontawesome"
     },
     {
       "uid": "98d9c83c1ee7c2c25af784b518c522c5",
       "css": "block",
-      "code": 59470,
+      "code": 128683,
       "src": "fontawesome"
     },
     {
       "uid": "d3b3f17bc3eb7cd809a07bbd4d178bee",
       "css": "resize-vertical",
-      "code": 59415,
+      "code": 11109,
       "src": "fontawesome"
     },
     {
@@ -2825,25 +2825,25 @@
     {
       "uid": "ccddff8e8670dcd130e3cb55fdfc2fd0",
       "css": "down-open",
-      "code": 59464,
+      "code": 8595,
       "src": "fontawesome"
     },
     {
       "uid": "d870630ff8f81e6de3958ecaeac532f2",
       "css": "left-open",
-      "code": 59465,
+      "code": 8594,
       "src": "fontawesome"
     },
     {
       "uid": "399ef63b1e23ab1b761dfbb5591fa4da",
       "css": "right-open",
-      "code": 59466,
+      "code": 8592,
       "src": "fontawesome"
     },
     {
       "uid": "fe6697b391355dec12f3d86d6d490397",
       "css": "up-open",
-      "code": 59467,
+      "code": 8593,
       "src": "fontawesome"
     },
     {
@@ -2879,13 +2879,13 @@
     {
       "uid": "a73c5deb486c8d66249811642e5d719a",
       "css": "arrows-cw",
-      "code": 59448,
+      "code": 128472,
       "src": "fontawesome"
     },
     {
       "uid": "6020aff067fc3c119cdd75daa5249220",
       "css": "exchange",
-      "code": 59483,
+      "code": 8644,
       "src": "fontawesome"
     },
     {
@@ -2909,25 +2909,25 @@
     {
       "uid": "9755f76110ae4d12ac5f9466c9152031",
       "css": "book",
-      "code": 59454,
+      "code": 128210,
       "src": "fontawesome"
     },
     {
       "uid": "130380e481a7defc690dfb24123a1f0c",
       "css": "circle",
-      "code": 59485,
+      "code": 8226,
       "src": "fontawesome"
     },
     {
       "uid": "422e07e5afb80258a9c4ed1706498f8a",
       "css": "circle-empty",
-      "code": 59484,
+      "code": 9702,
       "src": "fontawesome"
     },
     {
       "uid": "f4445feb55521283572ee88bc304f928",
       "css": "floppy",
-      "code": 59480,
+      "code": 128190,
       "src": "fontawesome"
     },
     {
@@ -2939,7 +2939,7 @@
     {
       "uid": "56a21935a5d4d79b2e91ec00f760b369",
       "css": "sort",
-      "code": 59482,
+      "code": 8597,
       "src": "fontawesome"
     }
   ]
--- a/kallithea/public/fontello/css/kallithea.css	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/public/fontello/css/kallithea.css	Tue Jun 09 22:46:40 2015 +0200
@@ -1,10 +1,12 @@
-@font-face {
+@charset "UTF-8";
+
+ @font-face {
   font-family: 'kallithea';
-  src: url('../font/kallithea.eot?81834162');
-  src: url('../font/kallithea.eot?81834162#iefix') format('embedded-opentype'),
-       url('../font/kallithea.woff?81834162') format('woff'),
-       url('../font/kallithea.ttf?81834162') format('truetype'),
-       url('../font/kallithea.svg?81834162#kallithea') format('svg');
+  src: url('../font/kallithea.eot?23730278');
+  src: url('../font/kallithea.eot?23730278#iefix') format('embedded-opentype'),
+       url('../font/kallithea.woff?23730278') format('woff'),
+       url('../font/kallithea.ttf?23730278') format('truetype'),
+       url('../font/kallithea.svg?23730278#kallithea') format('svg');
   font-weight: normal;
   font-style: normal;
 }
@@ -14,7 +16,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'kallithea';
-    src: url('../font/kallithea.svg?81834162#kallithea') format('svg');
+    src: url('../font/kallithea.svg?23730278#kallithea') format('svg');
   }
 }
 */
@@ -35,7 +37,7 @@
   /* For safety - reset parent styles, that can break glyph codes*/
   font-variant: normal;
   text-transform: none;
-     
+ 
   /* fix buttons height, for twitter bootstrap */
   line-height: 1em;
  
@@ -46,102 +48,73 @@
   /* you can be more comfortable with increased icons size */
   /* font-size: 120%; */
  
+  /* Font smoothing. That was taken from TWBS */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+ 
   /* Uncomment for 3D effect */
   /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
 }
  
-.icon-database:before { content: '\e800'; } /* '' */
+.icon-circle:before { content: '\2022'; } /* '•' */
+.icon-right-open:before { content: '\2190'; } /* '←' */
+.icon-up-open:before { content: '\2191'; } /* '↑' */
+.icon-left-open:before { content: '\2192'; } /* '→' */
+.icon-down-open:before { content: '\2193'; } /* '↓' */
+.icon-code:before { content: '\2194'; } /* '↔' */
+.icon-sort:before { content: '\2195'; } /* '↕' */
+.icon-exchange:before { content: '\21c4'; } /* '⇄' */
+.icon-plus-circled:before { content: '\2295'; } /* '⊕' */
+.icon-minus-circled:before { content: '\2296'; } /* '⊖' */
+.icon-diff-added:before { content: '\229e'; } /* '⊞' */
+.icon-diff-removed:before { content: '\229f'; } /* '⊟' */
+.icon-diff-modified:before { content: '\22a1'; } /* '⊡' */
+.icon-clock:before { content: '\231a'; } /* '⌚' */
+.icon-triangle-left:before { content: '\23f4'; } /* '⏴' */
+.icon-triangle-right:before { content: '\23f5'; } /* '⏵' */
+.icon-triangle-up:before { content: '\23f6'; } /* '⏶' */
+.icon-triangle-down:before { content: '\23f7'; } /* '⏷' */
+.icon-circle-empty:before { content: '\25e6'; } /* '◦' */
+.icon-heart-empty:before { content: '\2661'; } /* '♡' */
+.icon-heart:before { content: '\2665'; } /* '♥' */
+.icon-cog-alt:before { content: '\2699'; } /* '⚙' */
+.icon-database:before { content: '\26c3'; } /* '⛃' */
+.icon-gear:before { content: '\26ed'; } /* '⛭' */
+.icon-plus:before { content: '\2795'; } /* '➕' */
+.icon-minus:before { content: '\2796'; } /* '➖' */
+.icon-resize-vertical:before { content: '\2b65'; } /* '⭥' */
+.icon-move-up:before { content: '\2b71'; } /* '⭱' */
+.icon-move-down:before { content: '\2b73'; } /* '⭳' */
 .icon-file-submodule:before { content: '\e801'; } /* '' */
 .icon-git-merge:before { content: '\e802'; } /* '' */
-.icon-move-down:before { content: '\e803'; } /* '' */
-.icon-move-up:before { content: '\e804'; } /* '' */
-.icon-diff-modified:before { content: '\e805'; } /* '' */
-.icon-diff-added:before { content: '\e806'; } /* '' */
-.icon-diff-removed:before { content: '\e807'; } /* '' */
-.icon-tools:before { content: '\e808'; } /* '' */
-.icon-cancel-circled:before { content: '\e809'; } /* '' */
-.icon-ok-circled:before { content: '\e80a'; } /* '' */
-.icon-comment:before { content: '\e80b'; } /* '' */
-.icon-comment-discussion:before { content: '\e80c'; } /* '' */
-.icon-triangle-down:before { content: '\e80d'; } /* '' */
-.icon-triangle-left:before { content: '\e80e'; } /* '' */
-.icon-triangle-right:before { content: '\e80f'; } /* '' */
-.icon-triangle-up:before { content: '\e810'; } /* '' */
 .icon-ruler:before { content: '\e811'; } /* '' */
-.icon-globe:before { content: '\e812'; } /* '' */
 .icon-download-cloud:before { content: '\e813'; } /* '' */
 .icon-upload-cloud:before { content: '\e814'; } /* '' */
 .icon-graph:before { content: '\e815'; } /* '' */
 .icon-file-zip:before { content: '\e816'; } /* '' */
-.icon-resize-vertical:before { content: '\e817'; } /* '' */
 .icon-file-code:before { content: '\e81a'; } /* '' */
-.icon-clippy:before { content: '\e81b'; } /* '' */
 .icon-doc-text-inv:before { content: '\e81c'; } /* '' */
 .icon-diff:before { content: '\e81d'; } /* '' */
 .icon-diff-ignored:before { content: '\e81e'; } /* '' */
 .icon-diff-renamed:before { content: '\e81f'; } /* '' */
 .icon-paste:before { content: '\e820'; } /* '' */
-.icon-code:before { content: '\e821'; } /* '' */
-.icon-keyhole-circled:before { content: '\e822'; } /* '' */
 .icon-file-directory:before { content: '\e823'; } /* '' */
 .icon-git-compare:before { content: '\e824'; } /* '' */
 .icon-git-pull-request:before { content: '\e825'; } /* '' */
-.icon-key:before { content: '\e826'; } /* '' */
 .icon-repo-forked:before { content: '\e827'; } /* '' */
 .icon-fork:before { content: '\e828'; } /* '' */
-.icon-trashcan:before { content: '\e829'; } /* '' */
-.icon-cancel:before { content: '\e82a'; } /* '' */
-.icon-search:before { content: '\e82b'; } /* '' */
-.icon-heart:before { content: '\e82c'; } /* '' */
-.icon-heart-empty:before { content: '\e82d'; } /* '' */
-.icon-user:before { content: '\e82e'; } /* '' */
-.icon-users:before { content: '\e82f'; } /* '' */
-.icon-ok:before { content: '\e830'; } /* '' */
-.icon-gear:before { content: '\e831'; } /* '' */
-.icon-cog-alt:before { content: '\e832'; } /* '' */
-.icon-doc:before { content: '\e833'; } /* '' */
 .icon-docs:before { content: '\e834'; } /* '' */
-.icon-doc-text:before { content: '\e835'; } /* '' */
 .icon-doc-inv:before { content: '\e836'; } /* '' */
 .icon-file-powerpoint:before { content: '\e837'; } /* '' */
-.icon-arrows-cw:before { content: '\e838'; } /* '' */
-.icon-clock:before { content: '\e839'; } /* '' */
-.icon-lock:before { content: '\e83a'; } /* '' */
-.icon-lock-open-alt:before { content: '\e83b'; } /* '' */
-.icon-tag:before { content: '\e83c'; } /* '' */
 .icon-tags:before { content: '\e83d'; } /* '' */
-.icon-book:before { content: '\e83e'; } /* '' */
 .icon-bookmark-empty:before { content: '\e83f'; } /* '' */
 .icon-bookmark:before { content: '\e840'; } /* '' */
 .icon-align-left:before { content: '\e841'; } /* '' */
-.icon-pencil:before { content: '\e842'; } /* '' */
 .icon-sliders:before { content: '\e843'; } /* '' */
-.icon-pencil-squared:before { content: '\e844'; } /* '' */
-.icon-edit:before { content: '\e845'; } /* '' */
-.icon-folder-open:before { content: '\e846'; } /* '' */
-.icon-folder-open-empty:before { content: '\e847'; } /* '' */
-.icon-down-open:before { content: '\e848'; } /* '' */
-.icon-left-open:before { content: '\e849'; } /* '' */
-.icon-right-open:before { content: '\e84a'; } /* '' */
-.icon-up-open:before { content: '\e84b'; } /* '' */
-.icon-plus-circled:before { content: '\e84c'; } /* '' */
-.icon-minus-circled:before { content: '\e84d'; } /* '' */
-.icon-block:before { content: '\e84e'; } /* '' */
-.icon-plus:before { content: '\e84f'; } /* '' */
-.icon-minus:before { content: '\e850'; } /* '' */
 .icon-eye-off:before { content: '\e851'; } /* '' */
-.icon-eye:before { content: '\e852'; } /* '' */
-.icon-folder:before { content: '\e853'; } /* '' */
-.icon-folder-empty:before { content: '\e854'; } /* '' */
 .icon-rss:before { content: '\e855'; } /* '' */
 .icon-rss-squared:before { content: '\e856'; } /* '' */
-.icon-wrench:before { content: '\e857'; } /* '' */
-.icon-floppy:before { content: '\e858'; } /* '' */
 .icon-strike:before { content: '\e859'; } /* '' */
-.icon-sort:before { content: '\e85a'; } /* '' */
-.icon-exchange:before { content: '\e85b'; } /* '' */
-.icon-circle-empty:before { content: '\e85c'; } /* '' */
-.icon-circle:before { content: '\e85d'; } /* '' */
 .icon-box:before { content: '\e85e'; } /* '' */
 .icon-right:before { content: '\e85f'; } /* '' */
 .icon-left:before { content: '\e860'; } /* '' */
@@ -150,4 +123,37 @@
 .icon-up-circled:before { content: '\e863'; } /* '' */
 .icon-up:before { content: '\e864'; } /* '' */
 .icon-down:before { content: '\e865'; } /* '' */
-.icon-down-circled:before { content: '\e866'; } /* '' */
\ No newline at end of file
+.icon-down-circled:before { content: '\e866'; } /* '' */
+.icon-globe:before { content: '🌎'; } /* '\1f30e' */
+.icon-eye:before { content: '👁'; } /* '\1f441' */
+.icon-user:before { content: '👤'; } /* '\1f464' */
+.icon-users:before { content: '👥'; } /* '\1f465' */
+.icon-floppy:before { content: '💾'; } /* '\1f4be' */
+.icon-folder-empty:before { content: '📁'; } /* '\1f4c1' */
+.icon-folder-open-empty:before { content: '📂'; } /* '\1f4c2' */
+.icon-clippy:before { content: '📋'; } /* '\1f4cb' */
+.icon-book:before { content: '📒'; } /* '\1f4d2' */
+.icon-search:before { content: '🔍'; } /* '\1f50d' */
+.icon-keyhole-circled:before { content: '🔐'; } /* '\1f510' */
+.icon-key:before { content: '🔑'; } /* '\1f511' */
+.icon-lock:before { content: '🔒'; } /* '\1f512' */
+.icon-lock-open-alt:before { content: '🔓'; } /* '\1f513' */
+.icon-tag:before { content: '🔖'; } /* '\1f516' */
+.icon-wrench:before { content: '🔧'; } /* '\1f527' */
+.icon-pencil:before { content: '🖉'; } /* '\1f589' */
+.icon-pencil-squared:before { content: '🖊'; } /* '\1f58a' */
+.icon-edit:before { content: '🖋'; } /* '\1f58b' */
+.icon-folder:before { content: '🗀'; } /* '\1f5c0' */
+.icon-folder-open:before { content: '🗁'; } /* '\1f5c1' */
+.icon-doc:before { content: '🗅'; } /* '\1f5c5' */
+.icon-doc-text:before { content: '🗈'; } /* '\1f5c8' */
+.icon-trashcan:before { content: '🗑'; } /* '\1f5d1' */
+.icon-arrows-cw:before { content: '🗘'; } /* '\1f5d8' */
+.icon-comment:before { content: '🗩'; } /* '\1f5e9' */
+.icon-comment-discussion:before { content: '🗪'; } /* '\1f5ea' */
+.icon-cancel:before { content: '🗴'; } /* '\1f5f4' */
+.icon-cancel-circled:before { content: '🗵'; } /* '\1f5f5' */
+.icon-ok:before { content: '🗸'; } /* '\1f5f8' */
+.icon-ok-circled:before { content: '🗹'; } /* '\1f5f9' */
+.icon-block:before { content: '🚫'; } /* '\1f6ab' */
+.icon-tools:before { content: '🛠'; } /* '\1f6e0' */
\ No newline at end of file
Binary file kallithea/public/fontello/font/kallithea.eot has changed
--- a/kallithea/public/fontello/font/kallithea.svg	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/public/fontello/font/kallithea.svg	Tue Jun 09 22:46:40 2015 +0200
@@ -6,98 +6,65 @@
 <font id="kallithea" horiz-adv-x="1000" >
 <font-face font-family="kallithea" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
 <missing-glyph horiz-adv-x="1000" />
-<glyph glyph-name="database" unicode="&#xe800;" d="m375-88c-207 0-375 56-375 126 0 37 0 79 0 125 0 10 5 21 13 31 42-54 187-94 362-94s320 40 362 94c8-10 13-21 13-31 0-37 0-75 0-125 0-70-168-126-375-126z m0 251c-207 0-375 56-375 125 0 37 0 78 0 125 0 6 3 13 6 19l0 0c2 4 4 8 7 12 42-54 187-94 362-94s320 40 362 94c3-4 5-8 7-12l0 0c4-6 6-13 6-19 0-37 0-75 0-125 0-69-168-125-375-125z m0 250c-207 0-375 56-375 125 0 19 0 40 0 62 0 20 0 41 0 63 0 69 168 125 375 125 207 0 375-56 375-125 0-20 0-41 0-63 0-19 0-39 0-62 0-69-168-125-375-125z m0 312c-138 0-250-28-250-62s112-63 250-63 250 28 250 63-112 62-250 62z" horiz-adv-x="750" />
+<glyph glyph-name="circle" unicode="&#x2022;" d="m857 350q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="right-open" unicode="&#x2190;" d="m618 361l-414-415q-11-10-25-10t-26 10l-92 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l92 93q11 10 26 10t25-10l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
+<glyph glyph-name="up-open" unicode="&#x2191;" d="m939 107l-92-92q-11-10-26-10t-25 10l-296 297-296-297q-11-10-25-10t-26 10l-92 92q-11 11-11 26t11 25l414 414q11 10 25 10t25-10l414-414q11-11 11-25t-11-26z" horiz-adv-x="1000" />
+<glyph glyph-name="left-open" unicode="&#x2192;" d="m653 682l-296-296 296-297q11-10 11-25t-11-25l-92-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25t11 25l414 414q10 10 25 10t25-10l92-93q11-10 11-25t-11-25z" horiz-adv-x="714.3" />
+<glyph glyph-name="down-open" unicode="&#x2193;" d="m939 399l-414-413q-10-11-25-11t-25 11l-414 413q-11 11-11 26t11 25l92 92q11 11 26 11t25-11l296-296 296 296q11 11 25 11t26-11l92-92q11-11 11-25t-11-26z" horiz-adv-x="1000" />
+<glyph glyph-name="code" unicode="&#x2194;" d="m594 663l-94-94 219-219-219-219 94-93 281 312-281 313z m-313 0l-281-313 281-312 94 93-219 219 219 219-94 94z" horiz-adv-x="875" />
+<glyph glyph-name="sort" unicode="&#x2195;" d="m571 243q0-15-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 10-11 25t11 25 25 11h500q14 0 25-11t10-25z m0 214q0-14-10-25t-25-11h-500q-15 0-25 11t-11 25 11 25l250 250q10 11 25 11t25-11l250-250q10-10 10-25z" horiz-adv-x="571.4" />
+<glyph glyph-name="exchange" unicode="&#x21c4;" d="m1000 189v-107q0-7-5-12t-13-6h-768v-107q0-7-5-12t-13-6q-6 0-13 6l-178 178q-5 5-5 13 0 8 5 13l179 178q5 5 12 5 8 0 13-5t5-13v-107h768q7 0 13-5t5-13z m0 304q0-8-5-13l-179-179q-5-5-12-5-8 0-13 6t-5 12v107h-768q-7 0-13 6t-5 12v107q0 8 5 13t13 5h768v107q0 8 5 13t13 5q6 0 13-5l178-178q5-5 5-13z" horiz-adv-x="1000" />
+<glyph glyph-name="plus-circled" unicode="&#x2295;" d="m679 314v72q0 14-11 25t-25 10h-143v143q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-143h-143q-14 0-25-10t-10-25v-72q0-14 10-25t25-11h143v-142q0-15 11-25t25-11h71q15 0 25 11t11 25v142h143q14 0 25 11t11 25z m178 36q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="minus-circled" unicode="&#x2296;" d="m679 314v72q0 14-11 25t-25 10h-429q-14 0-25-10t-10-25v-72q0-14 10-25t25-10h429q14 0 25 10t11 25z m178 36q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="diff-added" unicode="&#x229e;" d="m500 538h-125v-125h-125v-125h125v-125h125v125h125v125h-125v125z m313 250c-32 0-719 0-750 0s-63-32-63-63 0-719 0-750 31-63 63-63 718 0 750 0 62 32 62 63 0 719 0 750-31 63-62 63z m-63-719c0-16-17-31-31-31s-545 0-563 0-31 11-31 31c0 15 0 547 0 562s16 32 31 32 548 0 563 0 31-16 31-32 0-547 0-562z" horiz-adv-x="875" />
+<glyph glyph-name="diff-removed" unicode="&#x229f;" d="m813 788h-750c-32 0-63-32-63-63v-750c0-31 31-63 63-63h750c31 0 62 32 62 63v750c0 31-31 63-62 63z m-63-719c0-16-17-31-31-31h-563c-17 0-31 11-31 31v562c0 16 16 32 31 32h563c14 0 31-16 31-32v-562z m-500 219h375v125h-375v-125z" horiz-adv-x="875" />
+<glyph glyph-name="diff-modified" unicode="&#x22a1;" d="m813 788h-750c-32 0-63-32-63-63v-750c0-31 31-63 63-63h750c31 0 62 32 62 63v750c0 31-31 63-62 63z m-63-719c0-16-17-31-31-31h-563c-17 0-31 11-31 31v562c0 16 16 32 31 32h563c14 0 31-16 31-32v-562z m-312 406c-70 0-125-56-125-125s55-125 125-125 125 56 125 125-56 125-125 125z" horiz-adv-x="875" />
+<glyph glyph-name="clock" unicode="&#x231a;" d="m500 546v-250q0-7-5-12t-13-5h-178q-8 0-13 5t-5 12v36q0 8 5 13t13 5h125v196q0 8 5 13t12 5h36q8 0 13-5t5-13z m232-196q0 83-41 152t-110 111-152 41-153-41-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152z m125 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="triangle-left" unicode="&#x23f4;" d="m0 350l375-375v750l-375-375z" horiz-adv-x="374.8" />
+<glyph glyph-name="triangle-right" unicode="&#x23f5;" d="m0 725l375-375-375-375v750z" horiz-adv-x="374.9" />
+<glyph glyph-name="triangle-up" unicode="&#x23f6;" d="m375 600l-375-375h750l-375 375z" horiz-adv-x="749.5" />
+<glyph glyph-name="triangle-down" unicode="&#x23f7;" d="m0 475l375-375 375 375h-750z" horiz-adv-x="749.5" />
+<glyph glyph-name="circle-empty" unicode="&#x25e6;" d="m429 654q-83 0-153-41t-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152-41 152-110 111-152 41z m428-304q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="heart-empty" unicode="&#x2661;" d="m929 517q0 46-12 80t-31 55-46 33-52 18-55 4-62-14-62-36-48-40-34-34q-10-13-27-13t-27 13q-14 15-34 34t-48 40-62 36-62 14-55-4-52-18-46-33-31-55-12-80q0-93 105-198l324-312 324 312q105 105 105 198z m71 0q0-123-128-251l-347-335q-10-10-25-10t-25 10l-348 336q-5 5-15 15t-31 36-38 55-30 67-13 77q0 123 71 192t196 70q34 0 70-12t67-33 54-38 42-38q20 20 42 38t54 38 67 33 70 12q125 0 196-70t71-192z" horiz-adv-x="1000" />
+<glyph glyph-name="heart" unicode="&#x2665;" d="m500-79q-14 0-25 10l-348 336q-5 5-15 15t-31 36-38 55-30 67-13 77q0 123 71 192t196 70q34 0 70-12t67-33 54-38 42-38q20 20 42 38t54 38 67 33 70 12q125 0 196-70t71-192q0-123-128-251l-347-335q-10-10-25-10z" horiz-adv-x="1000" />
+<glyph glyph-name="cog-alt" unicode="&#x2699;" d="m500 350q0 59-42 101t-101 42-101-42-42-101 42-101 101-42 101 42 42 101z m429-286q0 29-22 51t-50 21-50-21-21-51q0-29 21-50t50-21 51 21 21 50z m0 572q0 29-22 50t-50 21-50-21-21-50q0-30 21-51t50-21 51 21 21 51z m-215-235v-103q0-6-4-11t-9-6l-86-14q-6-19-18-42 19-27 50-64 4-6 4-11 0-7-4-11-13-17-46-50t-44-33q-6 0-11 4l-64 50q-21-11-43-17-6-60-13-87-4-13-17-13h-104q-6 0-11 4t-5 10l-13 85q-19 6-42 18l-66-50q-4-4-11-4-6 0-12 4-80 75-80 90 0 5 4 10 5 8 23 30t26 34q-13 24-20 46l-85 13q-5 1-9 5t-4 11v103q0 6 4 11t9 6l86 14q7 19 18 42-19 27-50 64-4 6-4 11 0 7 4 11 12 17 46 50t44 33q6 0 12-4l64-50q19 10 43 18 6 60 13 86 3 13 16 13h104q6 0 11-4t6-10l13-85q19-6 41-17l66 49q5 4 11 4 7 0 12-4 81-75 81-90 0-5-4-10-7-9-24-30t-25-34q13-27 19-46l85-12q5-2 9-6t4-11z m357-298v-78q0-9-83-17-6-15-16-29 28-63 28-77 0-2-2-4-68-40-69-40-5 0-26 27t-29 37q-11-1-17-1t-17 1q-7-11-29-37t-25-27q-1 0-69 40-3 2-3 4 0 14 29 77-10 14-17 29-83 8-83 17v78q0 9 83 18 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 1 17 1t17-1q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-9 83-18z m0 572v-78q0-9-83-18-6-15-16-29 28-63 28-77 0-2-2-4-68-39-69-39-5 0-26 26t-29 38q-11-1-17-1t-17 1q-7-12-29-38t-25-26q-1 0-69 39-3 2-3 4 0 14 29 77-10 14-17 29-83 9-83 18v78q0 9 83 17 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 2 17 2t17-2q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-8 83-17z" horiz-adv-x="1071.4" />
+<glyph glyph-name="database" unicode="&#x26c3;" d="m375-88c-207 0-375 56-375 126 0 37 0 79 0 125 0 10 5 21 13 31 42-54 187-94 362-94s320 40 362 94c8-10 13-21 13-31 0-37 0-75 0-125 0-70-168-126-375-126z m0 251c-207 0-375 56-375 125 0 37 0 78 0 125 0 6 3 13 6 19l0 0c2 4 4 8 7 12 42-54 187-94 362-94s320 40 362 94c3-4 5-8 7-12l0 0c4-6 6-13 6-19 0-37 0-75 0-125 0-69-168-125-375-125z m0 250c-207 0-375 56-375 125 0 19 0 40 0 62 0 20 0 41 0 63 0 69 168 125 375 125 207 0 375-56 375-125 0-20 0-41 0-63 0-19 0-39 0-62 0-69-168-125-375-125z m0 312c-138 0-250-28-250-62s112-63 250-63 250 28 250 63-112 62-250 62z" horiz-adv-x="750" />
+<glyph glyph-name="gear" unicode="&#x26ed;" d="m437 508c-87 0-158-71-158-158 0-87 71-158 158-158 88 0 158 71 158 158 0 87-70 158-158 158z m318-249l-29-68 51-100 7-14-71-70-116 55-68-29-35-106-5-15h-99l-43 121-69 28-100-50-13-7-71 70 55 116-28 69-107 35-14 4v100l121 43 28 68-51 100-7 14 71 70 116-55 68 29 35 106 5 15h99l43-121 69-28 100 50 13 7 71-70-55-116 28-69 107-34 14-5v-99l-120-44z" horiz-adv-x="875" />
+<glyph glyph-name="plus" unicode="&#x2795;" d="m786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q22 0 38-16t16-38z" horiz-adv-x="785.7" />
+<glyph glyph-name="minus" unicode="&#x2796;" d="m786 439v-107q0-22-16-38t-38-15h-678q-23 0-38 15t-16 38v107q0 23 16 38t38 16h678q22 0 38-16t16-38z" horiz-adv-x="785.7" />
+<glyph glyph-name="resize-vertical" unicode="&#x2b65;" d="m393 671q0-14-11-25t-25-10h-71v-572h71q15 0 25-10t11-25-11-26l-143-142q-10-11-25-11t-25 11l-143 142q-10 11-10 26t10 25 25 10h72v572h-72q-14 0-25 10t-10 25 10 26l143 142q11 11 25 11t25-11l143-142q11-11 11-26z" horiz-adv-x="428.6" />
+<glyph glyph-name="move-up" unicode="&#x2b71;" d="m0 163h188v-313h250v313h187l-312 375-313-375z m0 687v-187h625v187h-625z" horiz-adv-x="625" />
+<glyph glyph-name="move-down" unicode="&#x2b73;" d="m625 538h-187v312h-250v-312h-188l313-375 312 375z m-625-688h625v188h-625v-188z" horiz-adv-x="625" />
 <glyph glyph-name="file-submodule" unicode="&#xe801;" d="m813 350c-32 0-188 0-188 0 0 31-31 63-62 63s-94 0-125 0-63-32-63-63 0-312 0-312h500s0 218 0 250-31 62-62 62z m-250-62h-125s0 16 0 31 14 31 31 31 47 0 62 0 32-15 32-31 0-31 0-31z m250 312c-32 0-329 0-344 0s-31 17-31 31 0 0 0 32-32 62-63 62-281 0-312 0-63-31-63-62 0-625 0-625h313s0 343 0 375 31 62 62 62 219 0 250 0 63-31 63-62h187s0 93 0 125-31 62-62 62z m-438 0h-312s0 16 0 31 15 32 31 32 234 0 250 0 31-17 31-32 0-31 0-31z" horiz-adv-x="875" />
 <glyph glyph-name="git-merge" unicode="&#xe802;" d="m625 413c-46 0-86-26-108-64-6 1-11 1-17 1-128 0-249 98-294 218 27 23 44 57 44 95 0 69-56 125-125 125s-125-56-125-125c0-47 25-86 63-108v-410c-38-21-63-61-63-107 0-70 56-126 125-126s125 56 125 126c0 46-25 86-62 107v225c82-87 195-145 312-145 6 0 11 0 17 1 22-38 62-63 108-63 69 0 125 56 125 125 0 69-56 125-125 125z m-500-438c-34 0-62 28-62 63 0 34 28 62 62 62 35 0 63-28 63-62 0-35-28-63-63-63z m0 625c-34 0-62 28-62 63s28 62 62 62c35 0 63-28 63-62s-28-63-63-63z m500-375c-34 0-62 28-62 63 0 34 28 62 62 62 35 0 63-28 63-62 0-35-28-63-63-63z" horiz-adv-x="750" />
-<glyph glyph-name="move-down" unicode="&#xe803;" d="m625 538h-187v312h-250v-312h-188l313-375 312 375z m-625-688h625v188h-625v-188z" horiz-adv-x="625" />
-<glyph glyph-name="move-up" unicode="&#xe804;" d="m0 163h188v-313h250v313h187l-312 375-313-375z m0 687v-187h625v187h-625z" horiz-adv-x="625" />
-<glyph glyph-name="diff-modified" unicode="&#xe805;" d="m813 788h-750c-32 0-63-32-63-63v-750c0-31 31-63 63-63h750c31 0 62 32 62 63v750c0 31-31 63-62 63z m-63-719c0-16-17-31-31-31h-563c-17 0-31 11-31 31v562c0 16 16 32 31 32h563c14 0 31-16 31-32v-562z m-312 406c-70 0-125-56-125-125s55-125 125-125 125 56 125 125-56 125-125 125z" horiz-adv-x="875" />
-<glyph glyph-name="diff-added" unicode="&#xe806;" d="m500 538h-125v-125h-125v-125h125v-125h125v125h125v125h-125v125z m313 250c-32 0-719 0-750 0s-63-32-63-63 0-719 0-750 31-63 63-63 718 0 750 0 62 32 62 63 0 719 0 750-31 63-62 63z m-63-719c0-16-17-31-31-31s-545 0-563 0-31 11-31 31c0 15 0 547 0 562s16 32 31 32 548 0 563 0 31-16 31-32 0-547 0-562z" horiz-adv-x="875" />
-<glyph glyph-name="diff-removed" unicode="&#xe807;" d="m813 788h-750c-32 0-63-32-63-63v-750c0-31 31-63 63-63h750c31 0 62 32 62 63v750c0 31-31 63-62 63z m-63-719c0-16-17-31-31-31h-563c-17 0-31 11-31 31v562c0 16 16 32 31 32h563c14 0 31-16 31-32v-562z m-500 219h375v125h-375v-125z" horiz-adv-x="875" />
-<glyph glyph-name="tools" unicode="&#xe808;" d="m280 396c16-16 80-83 80-83l35 36-55 57 105 112c0 0-47 47-26 28 20 74 1 157-55 215-56 58-135 77-206 57l120-125-31-122-119-33-120 125c-20-74-1-156 55-214 58-60 143-78 217-53z m402-121l-145-144 240-249c20-20 45-31 71-31 26 0 52 11 71 31 40 40 40 106 0 147l-237 246z m318 417l-153 158-451-466 55-57-270-279-62-33-87-142 23-23 137 90 32 64 270 279 55-57 451 466z" horiz-adv-x="1000" />
-<glyph glyph-name="cancel-circled" unicode="&#xe809;" d="m641 224q0 14-10 25l-101 101 101 101q10 11 10 25 0 15-10 26l-51 50q-10 11-25 11-15 0-25-11l-101-101-101 101q-11 11-26 11-15 0-25-11l-50-50q-11-11-11-26 0-14 11-25l101-101-101-101q-11-11-11-25 0-15 11-26l50-50q10-11 25-11 15 0 26 11l101 101 101-101q10-11 25-11 15 0 25 11l51 50q10 11 10 26z m216 126q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
-<glyph glyph-name="ok-circled" unicode="&#xe80a;" d="m717 440q0 16-11 26l-50 50q-11 11-25 11t-26-11l-227-227-126 126q-11 11-25 11t-26-11l-50-50q-10-10-10-26 0-15 10-25l202-202q10-10 25-10 15 0 25 10l303 303q11 10 11 25z m140-90q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
-<glyph glyph-name="comment" unicode="&#xe80b;" d="m750 725h-625c-60 0-125-62-125-125v-375c0-125 125-125 125-125h63v-250l250 250c0 0 252 0 312 0s125 66 125 125v375c0 61-62 125-125 125z" horiz-adv-x="875" />
-<glyph glyph-name="comment-discussion" unicode="&#xe80c;" d="m250 350c0 63 0 188 0 188s-156 0-187 0-63-32-63-63 0-281 0-312 31-63 63-63 62 0 62 0v-188l190 188s158 0 187 0 61 31 61 63 0 62 0 62-125 0-188 0-125 63-125 125z m563 375c-32 0-407 0-438 0s-62-31-62-62 0-282 0-313 31-62 62-62 186 0 186 0l189-188v188s31 0 63 0 62 31 62 62 0 281 0 313-31 62-62 62z" horiz-adv-x="875" />
-<glyph glyph-name="triangle-down" unicode="&#xe80d;" d="m0 475l375-375 375 375h-750z" horiz-adv-x="749.5" />
-<glyph glyph-name="triangle-left" unicode="&#xe80e;" d="m0 350l375-375v750l-375-375z" horiz-adv-x="374.8" />
-<glyph glyph-name="triangle-right" unicode="&#xe80f;" d="m0 725l375-375-375-375v750z" horiz-adv-x="374.9" />
-<glyph glyph-name="triangle-up" unicode="&#xe810;" d="m375 600l-375-375h750l-375 375z" horiz-adv-x="749.5" />
 <glyph glyph-name="ruler" unicode="&#xe811;" d="m125 267h42v41h-42v-41z m42 416h-42v-41h42v41z m0-750h-42v-41h-83v-42h208v42h-83v41z m-42 584h42v41h-42v-41z m0-125h42v41h-42v-41z m250 458v-1000h542v1000h-542z m333-917h-250v834h250v-834z m125 0h-83v84h83v-84z m0 125h-83v84h83v-84z m0 125h-83v84h83v-84z m0 125h-83v84h83v-84z m0 125h-83v84h83v-84z m0 125h-83v84h83v-84z m0 125h-83v84h83v-84z m-791 125h83v-41h42v41h83v42h-208v-42z m83-791h42v41h-42v-41z m0 125h42v41h-42v-41z" horiz-adv-x="1000" />
-<glyph glyph-name="globe" unicode="&#xe812;" d="m500 725c-207 0-375-168-375-375s168-375 375-375c25 0 50 2 74 7-10 5-11 40-1 59 11 22 44 78 11 97s-24 27-44 48-12 25-13 31c-5 19 19 47 20 50s1 14 1 17-15 13-19 13-5-6-10-6-28 13-32 17-7 12-14 19-7 1-18 5-43 17-68 27-28 24-28 35-15 25-22 35c-7 11-9 25-11 22s13-42 10-43-8 11-15 20 8 5-16 51 8 70 9 94 20-9 10 6 1 48-6 60-49-14-49-14c1 12 36 31 62 49s41 4 62-2 22-5 15 2 3 10 19 7 20-22 45-20 2-5 6-11-4-6-20-17 0-10 29-31 20 14 17 29 21 3 21 3c17-11 14 0 27-4s47-34 47-34c-43-24-16-26-8-32s-16-16-16-16c-9 9-10 0-16-3s0-12 0-12c-31-5-24-37-23-45s-20-19-25-30 13-35 4-36-19 36-71 22c-15-4-49-22-31-58s49 10 59 5-3-28-1-29 29-1 31-32 40-29 49-29 36 23 40 24 20 14 56-6 53-17 65-25 3-26 15-31 56 2 68-17-47-112-65-123-27-33-45-48-44-34-68-48c-22-13-26-36-35-43 168 37 293 187 293 366 0 207-168 375-375 375z m88-352c-5-1-16-11-42 5s-44 12-46 15c0 0-2 6 9 7 24 2 53-22 60-22s9 6 21 3c12-4 3-6-2-8z m-123 315c-2 2 2 4 5 7 2 3 1 6 3 8 5 6 32 13 27-2-5-15-31-16-35-13z m66-48c-9 0-31 3-27 7 16 15-6 19-19 21s-19 8-12 9 33-1 37-4 29-14 30-20 0-13-9-13z m79 3c-7-6-44 21-51 27-31 26-47 17-54 22-6 4-4 10 6 19s38-3 54-5 35-14 35-29c0-15 18-28 10-34z" horiz-adv-x="1000" />
 <glyph glyph-name="download-cloud" unicode="&#xe813;" d="m714 332q0 8-5 13t-13 5h-125v196q0 8-5 13t-12 5h-108q-7 0-12-5t-5-13v-196h-125q-8 0-13-5t-5-13q0-8 5-13l196-196q5-5 13-5t13 5l196 196q5 6 5 13z m357-125q0-89-62-151t-152-63h-607q-103 0-177 73t-73 177q0 72 39 134t105 92q-1 17-1 24 0 118 84 202t202 84q87 0 159-49t105-129q40 35 93 35 59 0 101-42t42-101q0-43-23-77 72-17 119-76t46-133z" horiz-adv-x="1071.4" />
 <glyph glyph-name="upload-cloud" unicode="&#xe814;" d="m714 368q0 8-5 13l-196 196q-5 5-13 5t-13-5l-196-196q-5-6-5-13 0-8 5-13t13-5h125v-196q0-8 5-13t12-5h108q7 0 12 5t5 13v196h125q8 0 13 5t5 13z m357-161q0-89-62-151t-152-63h-607q-103 0-177 73t-73 177q0 72 39 134t105 92q-1 17-1 24 0 118 84 202t202 84q87 0 159-49t105-129q40 35 93 35 59 0 101-42t42-101q0-43-23-77 72-17 119-76t46-133z" horiz-adv-x="1071.4" />
 <glyph glyph-name="graph" unicode="&#xe815;" d="m688 600h-188v-625h188v625z m250-187h-188v-438h188v438z m-875-501v126h62v62h-62v125h62v63h-62v125h62v62h-62v125h62v63h-62v125h62v62h-125v-1000h1000v62h-937z m375 376h-188v-313h188v313z" horiz-adv-x="1000" />
 <glyph glyph-name="file-zip" unicode="&#xe816;" d="m313 288v62h-63v-62h63z m0 125v62h-63v-62h63z m0 125v62h-63v-62h63z m-125-63h62v63h-62v-63z m375 313h-563v-876h750v688l-187 188z m125-813h-625v750h187v-62h63v62h187l188-187v-563z m-500 625h62v63h-62v-63z m0-250h62v63h-62v-63z m0-125l-63-62v-125h250v125l-62 62h-63v63h-62v-63z m125-62v-63h-125v63h125z" horiz-adv-x="750" />
-<glyph glyph-name="resize-vertical" unicode="&#xe817;" d="m393 671q0-14-11-25t-25-10h-71v-572h71q15 0 25-10t11-25-11-26l-143-142q-10-11-25-11t-25 11l-143 142q-10 11-10 26t10 25 25 10h72v572h-72q-14 0-25 10t-10 25 10 26l143 142q11 11 25 11t25-11l143-142q11-11 11-26z" horiz-adv-x="428.6" />
 <glyph glyph-name="file-code" unicode="&#xe81a;" d="m281 475l-156-156 156-156 63 62-94 94 94 94-63 62z m125-62l94-94-94-94 63-62 156 156-156 156-63-62z m157 375h-563v-876h750v688l-187 188z m125-813h-625v750h437l188-187v-563z" horiz-adv-x="750" />
-<glyph glyph-name="clippy" unicode="&#xe81b;" d="m688-25h-625v563h625v-188h62v313c0 34-28 62-62 62h-188c0 69-56 125-125 125s-125-56-125-125h-187c-35 0-63-28-63-62v-688c0-34 28-63 63-63h625c34 0 62 29 62 63v125h-62v-125z m-500 688c28 0 28 0 62 0s63 28 63 62 28 63 62 63 63-29 63-63 31-62 62-62 32 0 63 0 62-29 62-63h-500c0 38 27 63 63 63z m-63-500h125v62h-125v-62z m438 125v125l-250-188 250-187v125h312v125h-312z m-438-250h188v62h-188v-62z m313 437h-313v-62h313v62z m-188-125h-125v-62h125v62z" horiz-adv-x="875" />
 <glyph glyph-name="doc-text-inv" unicode="&#xe81c;" d="m819 584q8-7 16-20h-264v264q13-8 21-16z m-265-91h303v-589q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h446v-304q0-22 16-38t38-15z m89-411v36q0 8-5 13t-13 5h-393q-8 0-13-5t-5-13v-36q0-8 5-13t13-5h393q8 0 13 5t5 13z m0 143v36q0 7-5 12t-13 5h-393q-8 0-13-5t-5-12v-36q0-8 5-13t13-5h393q8 0 13 5t5 13z m0 143v35q0 8-5 13t-13 5h-393q-8 0-13-5t-5-13v-35q0-8 5-13t13-5h393q8 0 13 5t5 13z" horiz-adv-x="857.1" />
 <glyph glyph-name="diff" unicode="&#xe81d;" d="m438 600h-125v-125h-125v-125h125v-125h125v125h125v125h-125v125z m-250-625h375v125h-375v-125z m437 875h-500v-62h469l219-219v-594h62v625l-250 250z m-625-125v-875h750v688l-187 187h-563z m688-813h-625v751h468l157-157v-594z" horiz-adv-x="875" />
 <glyph glyph-name="diff-ignored" unicode="&#xe81e;" d="m813 788h-750c-32 0-63-32-63-63v-750c0-31 31-63 63-63h750c31 0 62 32 62 63v750c0 31-31 63-62 63z m-63-719c0-16-17-31-31-31h-563c-17 0-31 11-31 31v562c0 16 16 32 31 32h563c14 0 31-16 31-32v-562z m-500 189v-95h96l279 279v96h-96l-279-280z" horiz-adv-x="875" />
 <glyph glyph-name="diff-renamed" unicode="&#xe81f;" d="m813 788h-750c-32 0-63-32-63-63v-750c0-31 31-63 63-63h750c31 0 62 32 62 63v750c0 31-31 63-62 63z m-63-719c0-16-17-31-31-31h-563c-17 0-31 11-31 31v562c0 16 16 32 31 32h563c14 0 31-16 31-32v-562z m-312 344h-188v-125h188v-125l250 187-250 188v-125z" horiz-adv-x="875" />
 <glyph glyph-name="paste" unicode="&#xe820;" d="m429-79h500v358h-233q-22 0-38 15t-15 38v232h-214v-643z m142 804v36q0 7-5 12t-12 6h-393q-7 0-13-6t-5-12v-36q0-7 5-13t13-5h393q7 0 12 5t5 13z m143-375h167l-167 167v-167z m286-71v-375q0-23-16-38t-38-16h-535q-23 0-38 16t-16 38v89h-303q-23 0-38 16t-16 37v750q0 23 16 38t38 16h607q22 0 38-16t15-38v-183q12-7 20-15l228-228q16-16 27-42t11-50z" horiz-adv-x="1000" />
-<glyph glyph-name="code" unicode="&#xe821;" d="m594 663l-94-94 219-219-219-219 94-93 281 312-281 313z m-313 0l-281-313 281-312 94 93-219 219 219 219-94 94z" horiz-adv-x="875" />
-<glyph glyph-name="keyhole-circled" unicode="&#xe822;" d="m500 734c-212 0-384-172-384-384 0-212 172-384 384-384 212 0 384 172 384 384 0 212-172 384-384 384z m131-646h-262l57 285c-34 24-57 63-57 108 0 72 59 131 131 131 72 0 131-59 131-131 0-45-23-84-57-108l57-285z" horiz-adv-x="1000" />
 <glyph glyph-name="file-directory" unicode="&#xe823;" d="m813 663c-32 0-329 0-344 0s-31 15-31 31 0 0 0 31-32 63-63 63-281 0-312 0-63-32-63-63 0-687 0-687h875s0 531 0 562-31 63-62 63z m-438 0h-312s0 14 0 31 15 31 31 31 235 0 250 0 31-15 31-31 0-31 0-31z" horiz-adv-x="875" />
 <glyph glyph-name="git-compare" unicode="&#xe824;" d="m813 145s0 299 0 393-94 187-188 187c-62 0-62 0-62 0v125l-188-187 188-188v125s31 0 62 0 63-31 63-62 0-393 0-393c-38-22-63-62-63-107 0-70 56-126 125-126s125 56 125 126c0 45-25 85-62 107z m-63-170c-34 0-62 28-62 63s28 62 62 62 63-28 63-62-29-63-63-63z m-437 125s-32 0-63 0-62 31-62 63 0 392 0 392c37 22 62 62 62 108 0 69-56 125-125 125s-125-56-125-125c0-46 25-86 63-108 0 0 0-299 0-392s93-188 187-188c63 0 63 0 63 0v-125l187 188-187 187v-125z m-188 500c-34 0-62 28-62 63s28 62 62 62 63-28 63-62-29-63-63-63z" horiz-adv-x="875" />
 <glyph glyph-name="git-pull-request" unicode="&#xe825;" d="m688 145s0 299 0 393-94 187-188 187c-62 0-62 0-62 0v125l-188-187 188-188v125s31 0 62 0 63-31 63-62 0-393 0-393c-38-22-63-62-63-107 0-70 56-126 125-126s125 56 125 126c0 45-25 85-62 107z m-63-170c-34 0-62 28-62 63s28 62 62 62 63-28 63-62-29-63-63-63z m-500 813c-69 0-125-56-125-125 0-46 25-86 63-108v-409c-38-22-63-62-63-107 0-70 56-126 125-126s125 56 125 126c0 45-25 85-62 107v409c37 22 62 62 62 108 0 69-56 125-125 125z m0-813c-34 0-62 28-62 63s28 62 62 62 63-28 63-62-29-63-63-63z m0 625c-34 0-62 28-62 63s28 62 62 62 63-28 63-62-29-63-63-63z" horiz-adv-x="750" />
-<glyph glyph-name="key" unicode="&#xe826;" d="m626 788c-138 0-250-112-250-250 0-19 2-38 6-56l-382-382v-62l63-63h125l62 63v62h63v63h62v62h125l69 69c18-4 37-6 57-6 138 0 250 112 250 250s-112 250-250 250z m-251-438l-312-312v62l312 313v-63z m313 188c-35 0-63 28-63 62 0 35 28 63 63 63s62-28 62-63c0-34-28-62-62-62z" horiz-adv-x="875.9" />
 <glyph glyph-name="repo-forked" unicode="&#xe827;" d="m750 725c0 69-56 125-125 125s-125-56-125-125c0-46 25-87 63-108v-104l-188-207-187 207v104c37 21 62 61 62 108 0 69-56 125-125 125s-125-56-125-125c0-46 25-87 63-108v-153l250-275v-107c-38-21-63-61-63-108 0-69 56-125 125-125s125 56 125 125c0 46-25 87-62 108v107l250 275v153c37 21 62 61 62 108z m-625 62c33 0 61-28 61-61s-28-61-61-61-60 28-60 61 27 61 60 61z m250-871c-33 0-60 28-60 61s27 61 60 61 61-28 61-61-28-61-61-61z m250 871c33 0 61-28 61-61s-28-61-61-61-60 28-60 61 27 61 60 61z" horiz-adv-x="750" />
 <glyph glyph-name="fork" unicode="&#xe828;" d="m161 29q0 22-16 38t-38 15-38-15-15-38 15-38 38-16 38 16 16 38z m0 642q0 23-16 38t-38 16-38-16-15-38 15-38 38-15 38 15 16 38z m357-71q0 22-16 38t-38 16-38-16-15-38 15-38 38-16 38 16 16 38z m53 0q0-29-14-54t-39-39q-1-160-126-231-38-21-114-45-71-22-94-39t-23-56v-15q24-14 39-39t14-53q0-45-31-76t-76-32-76 32-31 76q0 29 15 53t39 39v458q-25 14-39 39t-15 53q0 45 31 76t76 32 76-32 31-76q0-29-14-53t-39-39v-278q30 15 86 32 30 10 49 17t39 17 33 22 22 29 16 38 5 51q-25 14-39 39t-15 54q0 45 31 76t76 31 76-31 31-76z" horiz-adv-x="571.4" />
-<glyph glyph-name="trashcan" unicode="&#xe829;" d="m688 725h-250c0 0 0 24 0 31 0 18-14 32-32 32s-31-14-31-32c0-17 0-31 0-31h-250c-34 0-62-28-62-62v-63c0-34 28-62 62-62v-563c0-35 28-63 63-63h437c35 0 63 28 63 63v563c34 0 62 28 62 62v63c0 34-28 62-62 62z m-63-719c0-17-14-31-31-31h-375c-17 0-31 14-31 31v532h62v-469c0-17 14-31 31-31s32 14 32 31l0 469h62v-469c0-17 14-31 31-31s32 14 32 31l0 469h62l0-469c0-17 14-31 31-31s32 14 32 31v469h62v-532z m63 610c0-9-7-16-16-16h-531c-9 0-16 7-16 16v31c0 9 7 16 16 16h531c9 0 16-7 16-16v-31z" horiz-adv-x="750" />
-<glyph glyph-name="cancel" unicode="&#xe82a;" d="m724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
-<glyph glyph-name="search" unicode="&#xe82b;" d="m938 38l-244 243c35 57 56 123 56 194 0 207-168 375-375 375-207 0-375-168-375-375 0-207 168-375 375-375 71 0 138 21 194 56l244-244c17-17 45-17 62 0l63 63c17 17 17 45 0 63z m-563 187c-138 0-250 112-250 250s112 250 250 250 250-112 250-250-112-250-250-250z" horiz-adv-x="950.3" />
-<glyph glyph-name="heart" unicode="&#xe82c;" d="m500-79q-14 0-25 10l-348 336q-5 5-15 15t-31 36-38 55-30 67-13 77q0 123 71 192t196 70q34 0 70-12t67-33 54-38 42-38q20 20 42 38t54 38 67 33 70 12q125 0 196-70t71-192q0-123-128-251l-347-335q-10-10-25-10z" horiz-adv-x="1000" />
-<glyph glyph-name="heart-empty" unicode="&#xe82d;" d="m929 517q0 46-12 80t-31 55-46 33-52 18-55 4-62-14-62-36-48-40-34-34q-10-13-27-13t-27 13q-14 15-34 34t-48 40-62 36-62 14-55-4-52-18-46-33-31-55-12-80q0-93 105-198l324-312 324 312q105 105 105 198z m71 0q0-123-128-251l-347-335q-10-10-25-10t-25 10l-348 336q-5 5-15 15t-31 36-38 55-30 67-13 77q0 123 71 192t196 70q34 0 70-12t67-33 54-38 42-38q20 20 42 38t54 38 67 33 70 12q125 0 196-70t71-192z" horiz-adv-x="1000" />
-<glyph glyph-name="user" unicode="&#xe82e;" d="m786 66q0-67-41-106t-108-39h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q5 0 24-12t41-27 60-27 75-12 74 12 61 27 41 27 24 12q34 0 62-11t48-30 34-45 24-55 15-60 8-61 2-58z m-179 498q0-88-63-151t-151-63-152 63-62 151 62 152 152 63 151-63 63-152z" horiz-adv-x="785.7" />
-<glyph glyph-name="users" unicode="&#xe82f;" d="m331 350q-90-3-148-71h-75q-45 0-77 22t-31 66q0 197 69 197 4 0 25-11t54-24 66-12q38 0 75 13-3-21-3-37 0-78 45-143z m598-356q0-66-41-105t-108-39h-488q-68 0-108 39t-41 105q0 30 2 58t8 61 14 61 24 54 35 45 48 30 62 11q6 0 24-12t41-26 59-27 76-12 75 12 60 27 41 26 23 12q35 0 63-11t47-30 35-45 24-54 15-61 8-61 2-58z m-572 713q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z m393-214q0-89-63-152t-151-62-152 62-63 152 63 151 152 63 151-63 63-151z m321-126q0-43-31-66t-77-22h-75q-57 68-147 71 45 65 45 143 0 16-3 37 37-13 74-13 33 0 67 12t54 24 24 11q69 0 69-197z m-71 340q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z" horiz-adv-x="1071.4" />
-<glyph glyph-name="ok" unicode="&#xe830;" d="m932 534q0-22-15-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38t15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q15-16 15-38z" horiz-adv-x="1000" />
-<glyph glyph-name="gear" unicode="&#xe831;" d="m437 508c-87 0-158-71-158-158 0-87 71-158 158-158 88 0 158 71 158 158 0 87-70 158-158 158z m318-249l-29-68 51-100 7-14-71-70-116 55-68-29-35-106-5-15h-99l-43 121-69 28-100-50-13-7-71 70 55 116-28 69-107 35-14 4v100l121 43 28 68-51 100-7 14 71 70 116-55 68 29 35 106 5 15h99l43-121 69-28 100 50 13 7 71-70-55-116 28-69 107-34 14-5v-99l-120-44z" horiz-adv-x="875" />
-<glyph glyph-name="cog-alt" unicode="&#xe832;" d="m500 350q0 59-42 101t-101 42-101-42-42-101 42-101 101-42 101 42 42 101z m429-286q0 29-22 51t-50 21-50-21-21-51q0-29 21-50t50-21 51 21 21 50z m0 572q0 29-22 50t-50 21-50-21-21-50q0-30 21-51t50-21 51 21 21 51z m-215-235v-103q0-6-4-11t-9-6l-86-14q-6-19-18-42 19-27 50-64 4-6 4-11 0-7-4-11-13-17-46-50t-44-33q-6 0-11 4l-64 50q-21-11-43-17-6-60-13-87-4-13-17-13h-104q-6 0-11 4t-5 10l-13 85q-19 6-42 18l-66-50q-4-4-11-4-6 0-12 4-80 75-80 90 0 5 4 10 5 8 23 30t26 34q-13 24-20 46l-85 13q-5 1-9 5t-4 11v103q0 6 4 11t9 6l86 14q7 19 18 42-19 27-50 64-4 6-4 11 0 7 4 11 12 17 46 50t44 33q6 0 12-4l64-50q19 10 43 18 6 60 13 86 3 13 16 13h104q6 0 11-4t6-10l13-85q19-6 41-17l66 49q5 4 11 4 7 0 12-4 81-75 81-90 0-5-4-10-7-9-24-30t-25-34q13-27 19-46l85-12q5-2 9-6t4-11z m357-298v-78q0-9-83-17-6-15-16-29 28-63 28-77 0-2-2-4-68-40-69-40-5 0-26 27t-29 37q-11-1-17-1t-17 1q-7-11-29-37t-25-27q-1 0-69 40-3 2-3 4 0 14 29 77-10 14-17 29-83 8-83 17v78q0 9 83 18 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 1 17 1t17-1q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-9 83-18z m0 572v-78q0-9-83-18-6-15-16-29 28-63 28-77 0-2-2-4-68-39-69-39-5 0-26 26t-29 38q-11-1-17-1t-17 1q-7-12-29-38t-25-26q-1 0-69 39-3 2-3 4 0 14 29 77-10 14-17 29-83 9-83 18v78q0 9 83 17 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 2 17 2t17-2q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-8 83-17z" horiz-adv-x="1071.4" />
-<glyph glyph-name="doc" unicode="&#xe833;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z" horiz-adv-x="857.1" />
 <glyph glyph-name="docs" unicode="&#xe834;" d="m946 636q23 0 38-16t16-38v-678q0-23-16-38t-38-16h-535q-23 0-38 16t-16 38v160h-303q-23 0-38 16t-16 38v375q0 22 11 49t27 42l228 228q15 16 42 27t49 11h232q23 0 38-16t16-38v-183q38 23 71 23h232z m-303-119l-167-167h167v167z m-357 214l-167-167h167v167z m109-361l176 176v233h-214v-233q0-22-15-38t-38-15h-233v-357h286v143q0 22 11 49t27 42z m534-449v643h-215v-232q0-22-15-38t-38-15h-232v-358h500z" horiz-adv-x="1000" />
-<glyph glyph-name="doc-text" unicode="&#xe835;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-572 483q0 7 5 12t13 5h393q8 0 13-5t5-12v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36z m411-125q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z m0-143q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z" horiz-adv-x="857.1" />
 <glyph glyph-name="doc-inv" unicode="&#xe836;" d="m571 564v264q13-8 21-16l227-228q8-7 16-20h-264z m-71-18q0-22 16-38t38-15h303v-589q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h446v-304z" horiz-adv-x="857.1" />
 <glyph glyph-name="file-powerpoint" unicode="&#xe837;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-554 131v-59h183v59h-52v93h76q43 0 66 9 37 12 59 48t23 82q0 45-21 78t-56 49q-27 10-72 10h-206v-59h52v-310h-52z m197 156h-66v150h67q29 0 46-10 31-19 31-64 0-50-34-67-18-9-44-9z" horiz-adv-x="857.1" />
-<glyph glyph-name="arrows-cw" unicode="&#xe838;" d="m843 261q0-3 0-4-36-150-150-243t-267-93q-81 0-157 31t-136 88l-72-72q-11-11-25-11t-25 11-11 25v250q0 14 11 25t25 11h250q14 0 25-11t10-25-10-25l-77-77q40-37 90-57t105-20q74 0 139 37t104 99q6 10 29 66 5 13 17 13h107q8 0 13-6t5-12z m14 446v-250q0-14-10-25t-26-11h-250q-14 0-25 11t-10 25 10 25l77 77q-82 77-194 77-75 0-140-37t-104-99q-6-10-29-66-5-13-17-13h-111q-7 0-13 6t-5 12v4q36 150 151 243t268 93q81 0 158-31t137-88l72 72q11 11 25 11t26-11 10-25z" horiz-adv-x="857.1" />
-<glyph glyph-name="clock" unicode="&#xe839;" d="m500 546v-250q0-7-5-12t-13-5h-178q-8 0-13 5t-5 12v36q0 8 5 13t13 5h125v196q0 8 5 13t12 5h36q8 0 13-5t5-13z m232-196q0 83-41 152t-110 111-152 41-153-41-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152z m125 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
-<glyph glyph-name="lock" unicode="&#xe83a;" d="m179 421h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" />
-<glyph glyph-name="lock-open-alt" unicode="&#xe83b;" d="m589 421q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v179q0 103 74 177t176 73 177-73 73-177q0-15-10-25t-25-11h-36q-14 0-25 11t-11 25q0 59-42 101t-101 42-101-42-41-101v-179h410z" horiz-adv-x="642.9" />
-<glyph glyph-name="tag" unicode="&#xe83c;" d="m250 600q0 30-21 51t-50 20-51-20-21-51 21-50 51-21 50 21 21 50z m595-321q0-30-20-51l-274-274q-22-21-51-21-30 0-50 21l-399 399q-21 21-36 57t-15 65v232q0 29 21 50t50 22h233q29 0 65-15t57-36l399-399q20-21 20-50z" horiz-adv-x="857.1" />
 <glyph glyph-name="tags" unicode="&#xe83d;" d="m250 600q0 30-21 51t-50 20-51-20-21-51 21-50 51-21 50 21 21 50z m595-321q0-30-20-51l-274-274q-22-21-51-21-30 0-50 21l-399 399q-21 21-36 57t-15 65v232q0 29 21 50t50 22h233q29 0 65-15t57-36l399-399q20-21 20-50z m215 0q0-30-21-51l-274-274q-22-21-51-21-20 0-33 8t-29 25l262 262q21 21 21 51 0 29-21 50l-399 399q-21 21-57 36t-65 15h125q29 0 65-15t57-36l399-399q21-21 21-50z" horiz-adv-x="1071.4" />
-<glyph glyph-name="book" unicode="&#xe83e;" d="m915 583q22-32 10-72l-154-505q-10-36-42-60t-69-25h-515q-43 0-83 30t-55 74q-14 37-1 71 0 2 1 15t3 20q0 5-2 12t-2 11q1 6 5 12t9 13 9 13q13 21 25 51t17 51q2 6 0 17t0 16q2 6 9 15t10 13q12 20 23 51t14 51q1 5-1 17t0 16q2 7 12 17t13 13q10 14 23 47t16 54q0 4-2 14t-1 15q1 4 5 10t10 13 10 11q4 7 9 17t8 20 9 20 11 18 15 13 20 6 26-3l0-1q21 5 28 5h425q41 0 63-32t10-72l-152-506q-20-66-40-85t-72-20h-485q-15 0-21-8-6-9-1-24 14-39 81-39h515q16 0 31 9t19 23l168 550q4 13 3 32 21-8 33-24z m-594-1q-2-7 1-12t11-6h339q8 0 15 6t9 12l12 36q2 7-2 12t-11 6h-339q-7 0-14-6t-9-12z m-46-143q-3-7 1-12t11-6h339q7 0 14 6t10 12l11 36q3 7-1 13t-11 5h-339q-8 0-14-5t-10-13z" horiz-adv-x="928.6" />
 <glyph glyph-name="bookmark-empty" unicode="&#xe83f;" d="m643 707h-572v-693l237 227 49 47 50-47 236-227v693z m7 72q12 0 24-5 19-8 29-23t11-35v-719q0-19-11-35t-29-23q-10-4-24-4-27 0-47 18l-246 236-246-236q-20-19-46-19-13 0-25 5-18 7-29 23t-11 35v719q0 19 11 35t29 23q12 5 25 5h585z" horiz-adv-x="714.3" />
 <glyph glyph-name="bookmark" unicode="&#xe840;" d="m650 779q12 0 24-5 19-8 29-23t11-35v-719q0-19-11-35t-29-23q-10-4-24-4-27 0-47 18l-246 236-246-236q-20-19-46-19-13 0-25 5-18 7-29 23t-11 35v719q0 19 11 35t29 23q12 5 25 5h585z" horiz-adv-x="714.3" />
 <glyph glyph-name="align-left" unicode="&#xe841;" d="m1000 100v-71q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v71q0 15 11 25t25 11h928q15 0 25-11t11-25z m-214 214v-71q0-15-11-25t-25-11h-714q-15 0-25 11t-11 25v71q0 15 11 25t25 11h714q15 0 25-11t11-25z m143 215v-72q0-14-11-25t-25-11h-857q-15 0-25 11t-11 25v72q0 14 11 25t25 10h857q14 0 25-10t11-25z m-215 214v-72q0-14-10-25t-25-10h-643q-15 0-25 10t-11 25v72q0 14 11 25t25 11h643q14 0 25-11t10-25z" horiz-adv-x="1000" />
-<glyph glyph-name="pencil" unicode="&#xe842;" d="m203-7l50 51-131 131-51-51v-60h72v-71h60z m291 518q0 12-12 12-5 0-9-4l-303-302q-4-4-4-10 0-12 13-12 5 0 9 4l303 302q3 4 3 10z m-30 107l232-232-464-465h-232v233z m381-54q0-29-20-50l-93-93-232 233 93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51z" horiz-adv-x="857.1" />
 <glyph glyph-name="sliders" unicode="&#xe843;" d="m196 64v-71h-196v71h196z m197 72q14 0 25-11t11-25v-143q0-14-11-25t-25-11h-143q-14 0-25 11t-11 25v143q0 15 11 25t25 11h143z m89 214v-71h-482v71h482z m-357 286v-72h-125v72h125z m732-572v-71h-411v71h411z m-536 643q15 0 26-10t10-26v-142q0-15-10-26t-26-10h-142q-15 0-26 10t-10 26v142q0 15 10 26t26 10h142z m358-286q14 0 25-10t10-25v-143q0-15-10-25t-25-11h-143q-15 0-25 11t-11 25v143q0 14 11 25t25 10h143z m178-71v-71h-125v71h125z m0 286v-72h-482v72h482z" horiz-adv-x="857.1" />
-<glyph glyph-name="pencil-squared" unicode="&#xe844;" d="m225 232l85-85-29-29h-31v53h-54v32z m231 217q8-7-1-16l-163-163q-9-9-16-1-8 7 1 16l163 163q9 9 16 1z m-152-385l303 304-161 161-303-304v-161h161z m339 340l51 51q16 16 16 38t-16 38l-85 85q-15 15-38 15t-38-15l-51-52z m214 214v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
-<glyph glyph-name="edit" unicode="&#xe845;" d="m496 189l64 65-85 85-64-65v-31h53v-54h32z m245 402q-9 9-18 0l-196-196q-9-9 0-18t18 0l196 196q9 9 0 18z m45-331v-106q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q35 0 65-14 9-4 10-13 2-10-5-16l-27-28q-8-8-18-4-13 3-25 3h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v70q0 7 5 12l36 36q8 8 20 4t11-16z m-54 411l161-160-375-375h-161v160z m248-73l-51-52-161 161 51 51q16 16 38 16t38-16l85-84q16-16 16-38t-16-38z" horiz-adv-x="1000" />
-<glyph glyph-name="folder-open" unicode="&#xe846;" d="m1049 319q0-18-18-37l-187-221q-24-28-67-48t-81-20h-607q-19 0-33 7t-15 24q0 17 17 37l188 221q24 28 67 48t80 20h607q19 0 34-7t15-24z m-192 192v-90h-464q-53 0-110-26t-92-67l-188-221-2-3q0 2-1 7t0 7v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q51 0 88-37t37-88z" horiz-adv-x="1071.4" />
-<glyph glyph-name="folder-open-empty" unicode="&#xe847;" d="m994 330q0 20-30 20h-607q-22 0-48-12t-39-29l-164-203q-11-13-11-22 0-20 30-20h607q22 0 48 13t40 29l164 203q10 12 10 21z m-637 91h429v90q0 22-16 38t-38 15h-321q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-476l143 175q25 30 65 49t78 19z m708-91q0-34-25-66l-165-203q-24-30-65-49t-78-19h-607q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q51 0 88-37t37-88v-90h107q30 0 56-13t37-40q8-17 8-38z" horiz-adv-x="1071.4" />
-<glyph glyph-name="down-open" unicode="&#xe848;" d="m939 399l-414-413q-10-11-25-11t-25 11l-414 413q-11 11-11 26t11 25l92 92q11 11 26 11t25-11l296-296 296 296q11 11 25 11t26-11l92-92q11-11 11-25t-11-26z" horiz-adv-x="1000" />
-<glyph glyph-name="left-open" unicode="&#xe849;" d="m653 682l-296-296 296-297q11-10 11-25t-11-25l-92-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25t11 25l414 414q10 10 25 10t25-10l92-93q11-10 11-25t-11-25z" horiz-adv-x="714.3" />
-<glyph glyph-name="right-open" unicode="&#xe84a;" d="m618 361l-414-415q-11-10-25-10t-26 10l-92 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l92 93q11 10 26 10t25-10l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
-<glyph glyph-name="up-open" unicode="&#xe84b;" d="m939 107l-92-92q-11-10-26-10t-25 10l-296 297-296-297q-11-10-25-10t-26 10l-92 92q-11 11-11 26t11 25l414 414q11 10 25 10t25-10l414-414q11-11 11-25t-11-26z" horiz-adv-x="1000" />
-<glyph glyph-name="plus-circled" unicode="&#xe84c;" d="m679 314v72q0 14-11 25t-25 10h-143v143q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-143h-143q-14 0-25-10t-10-25v-72q0-14 10-25t25-11h143v-142q0-15 11-25t25-11h71q15 0 25 11t11 25v142h143q14 0 25 11t11 25z m178 36q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
-<glyph glyph-name="minus-circled" unicode="&#xe84d;" d="m679 314v72q0 14-11 25t-25 10h-429q-14 0-25-10t-10-25v-72q0-14 10-25t25-10h429q14 0 25 10t11 25z m178 36q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
-<glyph glyph-name="block" unicode="&#xe84e;" d="m732 352q0 90-48 164l-421-420q76-50 166-50 62 0 118 25t96 65 65 97 24 119z m-557-167l421 421q-75 50-167 50-83 0-153-40t-110-112-41-152q0-91 50-167z m682 167q0-88-34-168t-91-137-137-92-166-34-167 34-137 92-91 137-34 168 34 167 91 137 137 91 167 34 166-34 137-91 91-137 34-167z" horiz-adv-x="857.1" />
-<glyph glyph-name="plus" unicode="&#xe84f;" d="m786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q22 0 38-16t16-38z" horiz-adv-x="785.7" />
-<glyph glyph-name="minus" unicode="&#xe850;" d="m786 439v-107q0-22-16-38t-38-15h-678q-23 0-38 15t-16 38v107q0 23 16 38t38 16h678q22 0 38-16t16-38z" horiz-adv-x="785.7" />
 <glyph glyph-name="eye-off" unicode="&#xe851;" d="m310 105l43 79q-48 35-76 88t-27 114q0 67 34 125-128-65-213-197 94-144 239-209z m217 424q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-12 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m202 106q0-4 0-5-59-105-176-316t-176-316l-28-50q-5-9-15-9-7 0-75 39-9 6-9 16 0 7 25 49-80 36-147 96t-117 137q-11 17-11 38t11 39q86 131 212 207t277 76q50 0 100-10l31 54q5 9 15 9 3 0 10-3t18-9 18-10 18-10 10-7q9-5 9-15z m21-249q0-78-44-142t-117-92l157 281q4-26 4-47z m250-72q0-19-11-38-22-36-61-81-84-96-194-149t-234-53l41 74q119 10 219 76t169 171q-65 100-158 164l35 63q53-36 102-86t81-102q11-19 11-39z" horiz-adv-x="1000" />
-<glyph glyph-name="eye" unicode="&#xe852;" d="m929 314q-85 132-213 197 34-58 34-125 0-104-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 242 68 187 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-12 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" />
-<glyph glyph-name="folder" unicode="&#xe853;" d="m929 511v-393q0-51-37-88t-88-37h-679q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h375q51 0 88-37t37-88z" horiz-adv-x="928.6" />
-<glyph glyph-name="folder-empty" unicode="&#xe854;" d="m857 118v393q0 22-15 38t-38 15h-393q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-536q0-22 16-38t38-16h679q22 0 38 16t15 38z m72 393v-393q0-51-37-88t-88-37h-679q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h375q51 0 88-37t37-88z" horiz-adv-x="928.6" />
 <glyph glyph-name="rss" unicode="&#xe855;" d="m214 100q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m286-69q1-15-9-26-11-12-27-12h-75q-14 0-24 9t-11 23q-12 128-103 219t-219 103q-14 1-23 11t-9 24v75q0 16 12 26 9 10 24 10h3q89-7 170-45t145-101q63-63 101-145t45-171z m286-1q1-15-10-26-10-11-26-11h-80q-14 0-25 10t-11 23q-6 120-56 228t-129 188-188 129-227 57q-14 0-24 11t-10 24v80q0 15 11 26 10 10 25 10h1q147-8 280-67t238-164q104-104 164-238t67-280z" horiz-adv-x="785.7" />
 <glyph glyph-name="rss-squared" unicode="&#xe856;" d="m286 136q0 29-21 50t-51 21-50-21-21-50 21-51 50-21 51 21 21 51z m196-53q-8 130-99 221t-221 99q-8 1-14-5t-5-13v-71q0-8 5-13t12-5q86-6 147-68t67-147q1-7 6-12t12-5h72q7 0 13 6t5 13z m214 0q-3 86-31 166t-78 145-115 114-145 78-166 31q-8 1-13-5-5-5-5-13v-71q0-7 5-12t12-6q114-4 211-62t156-155 62-211q0-8 5-13t13-5h71q7 0 13 6 6 5 5 13z m161 535v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
-<glyph glyph-name="wrench" unicode="&#xe857;" d="m214 29q0 14-10 25t-25 10-26-10-10-25 10-26 26-10 25 10 10 26z m360 234l-381-381q-21-20-50-20-29 0-51 20l-59 61q-21 20-21 50 0 29 21 51l380 380q22-55 64-97t97-64z m353 243q0-22-12-59-27-75-92-122t-144-46q-104 0-177 73t-73 177 73 176 177 74q32 0 67-10t60-26q9-6 9-15t-9-16l-163-94v-125l108-60q2 2 44 27t75 45 40 20q8 0 13-5t4-14z" horiz-adv-x="928.6" />
-<glyph glyph-name="floppy" unicode="&#xe858;" d="m214-7h429v214h-429v-214z m500 0h72v500q0 8-6 21t-11 20l-157 156q-5 6-19 12t-22 5v-232q0-22-15-38t-38-16h-322q-22 0-37 16t-16 38v232h-72v-714h72v232q0 22 16 38t37 16h465q22 0 38-16t15-38v-232z m-214 518v178q0 8-5 13t-13 5h-107q-7 0-13-5t-5-13v-178q0-8 5-13t13-5h107q7 0 13 5t5 13z m357-18v-518q0-22-15-38t-38-16h-750q-23 0-38 16t-16 38v750q0 22 16 38t38 16h517q23 0 50-12t42-26l156-157q16-15 27-42t11-49z" horiz-adv-x="857.1" />
 <glyph glyph-name="strike" unicode="&#xe859;" d="m982 350q8 0 13-5t5-13v-36q0-7-5-12t-13-5h-964q-8 0-13 5t-5 12v36q0 8 5 13t13 5h964z m-712 36q-16 19-29 44-27 54-27 105 0 101 75 173 74 71 219 71 28 0 94-11 36-7 98-27 6-21 12-66 8-68 8-102 0-10-3-25l-7-2-46 4-8 1q-28 83-58 114-49 51-117 51-64 0-102-33-37-32-37-81 0-41 37-79t156-72q38-11 96-36 33-16 53-29h-414z m282-143h230q4-22 4-51 0-62-23-119-13-30-40-58-20-19-61-45-44-27-85-37-45-12-113-12-64 0-109 13l-78 23q-32 8-40 15-5 5-5 12v8q0 60-1 87 0 17 0 38l1 20v25l57 1q8-19 17-40t12-31 7-15q20-32 45-52 24-20 59-32 33-12 73-12 36 0 78 15 43 14 68 48 26 34 26 72 0 47-45 87-19 16-77 40z" horiz-adv-x="1000" />
-<glyph glyph-name="sort" unicode="&#xe85a;" d="m571 243q0-15-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 10-11 25t11 25 25 11h500q14 0 25-11t10-25z m0 214q0-14-10-25t-25-11h-500q-15 0-25 11t-11 25 11 25l250 250q10 11 25 11t25-11l250-250q10-10 10-25z" horiz-adv-x="571.4" />
-<glyph glyph-name="exchange" unicode="&#xe85b;" d="m1000 189v-107q0-7-5-12t-13-6h-768v-107q0-7-5-12t-13-6q-6 0-13 6l-178 178q-5 5-5 13 0 8 5 13l179 178q5 5 12 5 8 0 13-5t5-13v-107h768q7 0 13-5t5-13z m0 304q0-8-5-13l-179-179q-5-5-12-5-8 0-13 6t-5 12v107h-768q-7 0-13 6t-5 12v107q0 8 5 13t13 5h768v107q0 8 5 13t13 5q6 0 13-5l178-178q5-5 5-13z" horiz-adv-x="1000" />
-<glyph glyph-name="circle-empty" unicode="&#xe85c;" d="m429 654q-83 0-153-41t-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152-41 152-110 111-152 41z m428-304q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
-<glyph glyph-name="circle" unicode="&#xe85d;" d="m857 350q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
 <glyph glyph-name="box" unicode="&#xe85e;" d="m607 386q0 14-10 25t-26 10h-142q-15 0-26-10t-10-25 10-25 26-11h142q15 0 26 11t10 25z m322 107v-536q0-14-11-25t-25-11h-786q-14 0-25 11t-11 25v536q0 14 11 25t25 11h786q14 0 25-11t11-25z m35 250v-143q0-15-10-25t-25-11h-858q-14 0-25 11t-10 25v143q0 14 10 25t25 11h858q14 0 25-11t10-25z" horiz-adv-x="1000" />
 <glyph glyph-name="right" unicode="&#xe85f;" d="m964 352q0-8-5-14l-215-197q-9-8-19-4-11 5-11 17v125h-696q-8 0-13 5t-5 12v108q0 7 5 12t13 5h696v125q0 12 11 17t19-3l215-196q5-5 5-12z" horiz-adv-x="1000" />
 <glyph glyph-name="left" unicode="&#xe860;" d="m1000 404v-108q0-7-5-12t-13-5h-696v-125q0-12-11-17t-19 3l-215 196q-5 5-5 12 0 8 5 14l215 197q9 8 19 4 11-5 11-17v-125h696q8 0 13-5t5-12z" horiz-adv-x="1000" />
@@ -107,6 +74,39 @@
 <glyph glyph-name="up" unicode="&#xe864;" d="m427 575q-5-11-16-11h-125v-696q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v696h-125q-12 0-16 11t3 19l195 215q5 5 13 5 7 0 13-5l198-215q7-9 3-19z" horiz-adv-x="428.6" />
 <glyph glyph-name="down" unicode="&#xe865;" d="m427 125q4-10-3-19l-195-215q-6-5-13-5-8 0-13 5l-198 215q-8 9-3 19 5 11 16 11h125v696q0 8 5 13t13 5h107q8 0 13-5t5-13v-696h125q11 0 16-11z" horiz-adv-x="428.6" />
 <glyph glyph-name="down-circled" unicode="&#xe866;" d="m625 332q0-7-6-13l-178-178q-6-5-12-5t-13 5l-179 178q-8 9-4 20 5 11 17 11h107v196q0 8 5 13t13 5h107q8 0 13-5t5-13v-196h107q8 0 13-5t5-13z m-196 322q-83 0-153-41t-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152-41 152-110 111-152 41z m428-304q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="globe" unicode="&#x1f30e;" d="m500 725c-207 0-375-168-375-375s168-375 375-375c25 0 50 2 74 7-10 5-11 40-1 59 11 22 44 78 11 97s-24 27-44 48-12 25-13 31c-5 19 19 47 20 50s1 14 1 17-15 13-19 13-5-6-10-6-28 13-32 17-7 12-14 19-7 1-18 5-43 17-68 27-28 24-28 35-15 25-22 35c-7 11-9 25-11 22s13-42 10-43-8 11-15 20 8 5-16 51 8 70 9 94 20-9 10 6 1 48-6 60-49-14-49-14c1 12 36 31 62 49s41 4 62-2 22-5 15 2 3 10 19 7 20-22 45-20 2-5 6-11-4-6-20-17 0-10 29-31 20 14 17 29 21 3 21 3c17-11 14 0 27-4s47-34 47-34c-43-24-16-26-8-32s-16-16-16-16c-9 9-10 0-16-3s0-12 0-12c-31-5-24-37-23-45s-20-19-25-30 13-35 4-36-19 36-71 22c-15-4-49-22-31-58s49 10 59 5-3-28-1-29 29-1 31-32 40-29 49-29 36 23 40 24 20 14 56-6 53-17 65-25 3-26 15-31 56 2 68-17-47-112-65-123-27-33-45-48-44-34-68-48c-22-13-26-36-35-43 168 37 293 187 293 366 0 207-168 375-375 375z m88-352c-5-1-16-11-42 5s-44 12-46 15c0 0-2 6 9 7 24 2 53-22 60-22s9 6 21 3c12-4 3-6-2-8z m-123 315c-2 2 2 4 5 7 2 3 1 6 3 8 5 6 32 13 27-2-5-15-31-16-35-13z m66-48c-9 0-31 3-27 7 16 15-6 19-19 21s-19 8-12 9 33-1 37-4 29-14 30-20 0-13-9-13z m79 3c-7-6-44 21-51 27-31 26-47 17-54 22-6 4-4 10 6 19s38-3 54-5 35-14 35-29c0-15 18-28 10-34z" horiz-adv-x="1000" />
+<glyph glyph-name="eye" unicode="&#x1f441;" d="m929 314q-85 132-213 197 34-58 34-125 0-104-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 242 68 187 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-12 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" />
+<glyph glyph-name="user" unicode="&#x1f464;" d="m786 66q0-67-41-106t-108-39h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q5 0 24-12t41-27 60-27 75-12 74 12 61 27 41 27 24 12q34 0 62-11t48-30 34-45 24-55 15-60 8-61 2-58z m-179 498q0-88-63-151t-151-63-152 63-62 151 62 152 152 63 151-63 63-152z" horiz-adv-x="785.7" />
+<glyph glyph-name="users" unicode="&#x1f465;" d="m331 350q-90-3-148-71h-75q-45 0-77 22t-31 66q0 197 69 197 4 0 25-11t54-24 66-12q38 0 75 13-3-21-3-37 0-78 45-143z m598-356q0-66-41-105t-108-39h-488q-68 0-108 39t-41 105q0 30 2 58t8 61 14 61 24 54 35 45 48 30 62 11q6 0 24-12t41-26 59-27 76-12 75 12 60 27 41 26 23 12q35 0 63-11t47-30 35-45 24-54 15-61 8-61 2-58z m-572 713q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z m393-214q0-89-63-152t-151-62-152 62-63 152 63 151 152 63 151-63 63-151z m321-126q0-43-31-66t-77-22h-75q-57 68-147 71 45 65 45 143 0 16-3 37 37-13 74-13 33 0 67 12t54 24 24 11q69 0 69-197z m-71 340q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z" horiz-adv-x="1071.4" />
+<glyph glyph-name="floppy" unicode="&#x1f4be;" d="m214-7h429v214h-429v-214z m500 0h72v500q0 8-6 21t-11 20l-157 156q-5 6-19 12t-22 5v-232q0-22-15-38t-38-16h-322q-22 0-37 16t-16 38v232h-72v-714h72v232q0 22 16 38t37 16h465q22 0 38-16t15-38v-232z m-214 518v178q0 8-5 13t-13 5h-107q-7 0-13-5t-5-13v-178q0-8 5-13t13-5h107q7 0 13 5t5 13z m357-18v-518q0-22-15-38t-38-16h-750q-23 0-38 16t-16 38v750q0 22 16 38t38 16h517q23 0 50-12t42-26l156-157q16-15 27-42t11-49z" horiz-adv-x="857.1" />
+<glyph glyph-name="folder-empty" unicode="&#x1f4c1;" d="m857 118v393q0 22-15 38t-38 15h-393q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-536q0-22 16-38t38-16h679q22 0 38 16t15 38z m72 393v-393q0-51-37-88t-88-37h-679q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h375q51 0 88-37t37-88z" horiz-adv-x="928.6" />
+<glyph glyph-name="folder-open-empty" unicode="&#x1f4c2;" d="m994 330q0 20-30 20h-607q-22 0-48-12t-39-29l-164-203q-11-13-11-22 0-20 30-20h607q22 0 48 13t40 29l164 203q10 12 10 21z m-637 91h429v90q0 22-16 38t-38 15h-321q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-476l143 175q25 30 65 49t78 19z m708-91q0-34-25-66l-165-203q-24-30-65-49t-78-19h-607q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q51 0 88-37t37-88v-90h107q30 0 56-13t37-40q8-17 8-38z" horiz-adv-x="1071.4" />
+<glyph glyph-name="clippy" unicode="&#x1f4cb;" d="m688-25h-625v563h625v-188h62v313c0 34-28 62-62 62h-188c0 69-56 125-125 125s-125-56-125-125h-187c-35 0-63-28-63-62v-688c0-34 28-63 63-63h625c34 0 62 29 62 63v125h-62v-125z m-500 688c28 0 28 0 62 0s63 28 63 62 28 63 62 63 63-29 63-63 31-62 62-62 32 0 63 0 62-29 62-63h-500c0 38 27 63 63 63z m-63-500h125v62h-125v-62z m438 125v125l-250-188 250-187v125h312v125h-312z m-438-250h188v62h-188v-62z m313 437h-313v-62h313v62z m-188-125h-125v-62h125v62z" horiz-adv-x="875" />
+<glyph glyph-name="book" unicode="&#x1f4d2;" d="m915 583q22-32 10-72l-154-505q-10-36-42-60t-69-25h-515q-43 0-83 30t-55 74q-14 37-1 71 0 2 1 15t3 20q0 5-2 12t-2 11q1 6 5 12t9 13 9 13q13 21 25 51t17 51q2 6 0 17t0 16q2 6 9 15t10 13q12 20 23 51t14 51q1 5-1 17t0 16q2 7 12 17t13 13q10 14 23 47t16 54q0 4-2 14t-1 15q1 4 5 10t10 13 10 11q4 7 9 17t8 20 9 20 11 18 15 13 20 6 26-3l0-1q21 5 28 5h425q41 0 63-32t10-72l-152-506q-20-66-40-85t-72-20h-485q-15 0-21-8-6-9-1-24 14-39 81-39h515q16 0 31 9t19 23l168 550q4 13 3 32 21-8 33-24z m-594-1q-2-7 1-12t11-6h339q8 0 15 6t9 12l12 36q2 7-2 12t-11 6h-339q-7 0-14-6t-9-12z m-46-143q-3-7 1-12t11-6h339q7 0 14 6t10 12l11 36q3 7-1 13t-11 5h-339q-8 0-14-5t-10-13z" horiz-adv-x="928.6" />
+<glyph glyph-name="search" unicode="&#x1f50d;" d="m938 38l-244 243c35 57 56 123 56 194 0 207-168 375-375 375-207 0-375-168-375-375 0-207 168-375 375-375 71 0 138 21 194 56l244-244c17-17 45-17 62 0l63 63c17 17 17 45 0 63z m-563 187c-138 0-250 112-250 250s112 250 250 250 250-112 250-250-112-250-250-250z" horiz-adv-x="950.3" />
+<glyph glyph-name="keyhole-circled" unicode="&#x1f510;" d="m500 734c-212 0-384-172-384-384 0-212 172-384 384-384 212 0 384 172 384 384 0 212-172 384-384 384z m131-646h-262l57 285c-34 24-57 63-57 108 0 72 59 131 131 131 72 0 131-59 131-131 0-45-23-84-57-108l57-285z" horiz-adv-x="1000" />
+<glyph glyph-name="key" unicode="&#x1f511;" d="m626 788c-138 0-250-112-250-250 0-19 2-38 6-56l-382-382v-62l63-63h125l62 63v62h63v63h62v62h125l69 69c18-4 37-6 57-6 138 0 250 112 250 250s-112 250-250 250z m-251-438l-312-312v62l312 313v-63z m313 188c-35 0-63 28-63 62 0 35 28 63 63 63s62-28 62-63c0-34-28-62-62-62z" horiz-adv-x="875.9" />
+<glyph glyph-name="lock" unicode="&#x1f512;" d="m179 421h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" />
+<glyph glyph-name="lock-open-alt" unicode="&#x1f513;" d="m589 421q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v179q0 103 74 177t176 73 177-73 73-177q0-15-10-25t-25-11h-36q-14 0-25 11t-11 25q0 59-42 101t-101 42-101-42-41-101v-179h410z" horiz-adv-x="642.9" />
+<glyph glyph-name="tag" unicode="&#x1f516;" d="m250 600q0 30-21 51t-50 20-51-20-21-51 21-50 51-21 50 21 21 50z m595-321q0-30-20-51l-274-274q-22-21-51-21-30 0-50 21l-399 399q-21 21-36 57t-15 65v232q0 29 21 50t50 22h233q29 0 65-15t57-36l399-399q20-21 20-50z" horiz-adv-x="857.1" />
+<glyph glyph-name="wrench" unicode="&#x1f527;" d="m214 29q0 14-10 25t-25 10-26-10-10-25 10-26 26-10 25 10 10 26z m360 234l-381-381q-21-20-50-20-29 0-51 20l-59 61q-21 20-21 50 0 29 21 51l380 380q22-55 64-97t97-64z m353 243q0-22-12-59-27-75-92-122t-144-46q-104 0-177 73t-73 177 73 176 177 74q32 0 67-10t60-26q9-6 9-15t-9-16l-163-94v-125l108-60q2 2 44 27t75 45 40 20q8 0 13-5t4-14z" horiz-adv-x="928.6" />
+<glyph glyph-name="pencil" unicode="&#x1f589;" d="m203-7l50 51-131 131-51-51v-60h72v-71h60z m291 518q0 12-12 12-5 0-9-4l-303-302q-4-4-4-10 0-12 13-12 5 0 9 4l303 302q3 4 3 10z m-30 107l232-232-464-465h-232v233z m381-54q0-29-20-50l-93-93-232 233 93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51z" horiz-adv-x="857.1" />
+<glyph glyph-name="pencil-squared" unicode="&#x1f58a;" d="m225 232l85-85-29-29h-31v53h-54v32z m231 217q8-7-1-16l-163-163q-9-9-16-1-8 7 1 16l163 163q9 9 16 1z m-152-385l303 304-161 161-303-304v-161h161z m339 340l51 51q16 16 16 38t-16 38l-85 85q-15 15-38 15t-38-15l-51-52z m214 214v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
+<glyph glyph-name="edit" unicode="&#x1f58b;" d="m496 189l64 65-85 85-64-65v-31h53v-54h32z m245 402q-9 9-18 0l-196-196q-9-9 0-18t18 0l196 196q9 9 0 18z m45-331v-106q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q35 0 65-14 9-4 10-13 2-10-5-16l-27-28q-8-8-18-4-13 3-25 3h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v70q0 7 5 12l36 36q8 8 20 4t11-16z m-54 411l161-160-375-375h-161v160z m248-73l-51-52-161 161 51 51q16 16 38 16t38-16l85-84q16-16 16-38t-16-38z" horiz-adv-x="1000" />
+<glyph glyph-name="folder" unicode="&#x1f5c0;" d="m929 511v-393q0-51-37-88t-88-37h-679q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h375q51 0 88-37t37-88z" horiz-adv-x="928.6" />
+<glyph glyph-name="folder-open" unicode="&#x1f5c1;" d="m1049 319q0-18-18-37l-187-221q-24-28-67-48t-81-20h-607q-19 0-33 7t-15 24q0 17 17 37l188 221q24 28 67 48t80 20h607q19 0 34-7t15-24z m-192 192v-90h-464q-53 0-110-26t-92-67l-188-221-2-3q0 2-1 7t0 7v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q51 0 88-37t37-88z" horiz-adv-x="1071.4" />
+<glyph glyph-name="doc" unicode="&#x1f5c5;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z" horiz-adv-x="857.1" />
+<glyph glyph-name="doc-text" unicode="&#x1f5c8;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-572 483q0 7 5 12t13 5h393q8 0 13-5t5-12v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36z m411-125q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z m0-143q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z" horiz-adv-x="857.1" />
+<glyph glyph-name="trashcan" unicode="&#x1f5d1;" d="m688 725h-250c0 0 0 24 0 31 0 18-14 32-32 32s-31-14-31-32c0-17 0-31 0-31h-250c-34 0-62-28-62-62v-63c0-34 28-62 62-62v-563c0-35 28-63 63-63h437c35 0 63 28 63 63v563c34 0 62 28 62 62v63c0 34-28 62-62 62z m-63-719c0-17-14-31-31-31h-375c-17 0-31 14-31 31v532h62v-469c0-17 14-31 31-31s32 14 32 31l0 469h62v-469c0-17 14-31 31-31s32 14 32 31l0 469h62l0-469c0-17 14-31 31-31s32 14 32 31v469h62v-532z m63 610c0-9-7-16-16-16h-531c-9 0-16 7-16 16v31c0 9 7 16 16 16h531c9 0 16-7 16-16v-31z" horiz-adv-x="750" />
+<glyph glyph-name="arrows-cw" unicode="&#x1f5d8;" d="m843 261q0-3 0-4-36-150-150-243t-267-93q-81 0-157 31t-136 88l-72-72q-11-11-25-11t-25 11-11 25v250q0 14 11 25t25 11h250q14 0 25-11t10-25-10-25l-77-77q40-37 90-57t105-20q74 0 139 37t104 99q6 10 29 66 5 13 17 13h107q8 0 13-6t5-12z m14 446v-250q0-14-10-25t-26-11h-250q-14 0-25 11t-10 25 10 25l77 77q-82 77-194 77-75 0-140-37t-104-99q-6-10-29-66-5-13-17-13h-111q-7 0-13 6t-5 12v4q36 150 151 243t268 93q81 0 158-31t137-88l72 72q11 11 25 11t26-11 10-25z" horiz-adv-x="857.1" />
+<glyph glyph-name="comment" unicode="&#x1f5e9;" d="m750 725h-625c-60 0-125-62-125-125v-375c0-125 125-125 125-125h63v-250l250 250c0 0 252 0 312 0s125 66 125 125v375c0 61-62 125-125 125z" horiz-adv-x="875" />
+<glyph glyph-name="comment-discussion" unicode="&#x1f5ea;" d="m250 350c0 63 0 188 0 188s-156 0-187 0-63-32-63-63 0-281 0-312 31-63 63-63 62 0 62 0v-188l190 188s158 0 187 0 61 31 61 63 0 62 0 62-125 0-188 0-125 63-125 125z m563 375c-32 0-407 0-438 0s-62-31-62-62 0-282 0-313 31-62 62-62 186 0 186 0l189-188v188s31 0 63 0 62 31 62 62 0 281 0 313-31 62-62 62z" horiz-adv-x="875" />
+<glyph glyph-name="cancel" unicode="&#x1f5f4;" d="m724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
+<glyph glyph-name="cancel-circled" unicode="&#x1f5f5;" d="m641 224q0 14-10 25l-101 101 101 101q10 11 10 25 0 15-10 26l-51 50q-10 11-25 11-15 0-25-11l-101-101-101 101q-11 11-26 11-15 0-25-11l-50-50q-11-11-11-26 0-14 11-25l101-101-101-101q-11-11-11-25 0-15 11-26l50-50q10-11 25-11 15 0 26 11l101 101 101-101q10-11 25-11 15 0 25 11l51 50q10 11 10 26z m216 126q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="ok" unicode="&#x1f5f8;" d="m932 534q0-22-15-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38t15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q15-16 15-38z" horiz-adv-x="1000" />
+<glyph glyph-name="ok-circled" unicode="&#x1f5f9;" d="m717 440q0 16-11 26l-50 50q-11 11-25 11t-26-11l-227-227-126 126q-11 11-25 11t-26-11l-50-50q-10-10-10-26 0-15 10-25l202-202q10-10 25-10 15 0 25 10l303 303q11 10 11 25z m140-90q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="block" unicode="&#x1f6ab;" d="m732 352q0 90-48 164l-421-420q76-50 166-50 62 0 118 25t96 65 65 97 24 119z m-557-167l421 421q-75 50-167 50-83 0-153-40t-110-112-41-152q0-91 50-167z m682 167q0-88-34-168t-91-137-137-92-166-34-167 34-137 92-91 137-34 168 34 167 91 137 137 91 167 34 166-34 137-91 91-137 34-167z" horiz-adv-x="857.1" />
+<glyph glyph-name="tools" unicode="&#x1f6e0;" d="m280 396c16-16 80-83 80-83l35 36-55 57 105 112c0 0-47 47-26 28 20 74 1 157-55 215-56 58-135 77-206 57l120-125-31-122-119-33-120 125c-20-74-1-156 55-214 58-60 143-78 217-53z m402-121l-145-144 240-249c20-20 45-31 71-31 26 0 52 11 71 31 40 40 40 106 0 147l-237 246z m318 417l-153 158-451-466 55-57-270-279-62-33-87-142 23-23 137 90 32 64 270 279 55-57 451 466z" horiz-adv-x="1000" />
 </font>
 </defs>
 </svg>
\ No newline at end of file
Binary file kallithea/public/fontello/font/kallithea.ttf has changed
Binary file kallithea/public/fontello/font/kallithea.woff has changed
--- a/kallithea/public/js/base.js	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/public/js/base.js	Tue Jun 09 22:46:40 2015 +0200
@@ -372,7 +372,6 @@
         .fail(function(jqXHR, textStatus, errorThrown) {
                 if (textStatus == "abort")
                     return;
-                console.log('Ajax failure: ' + textStatus);
                 $target.html('<span class="error_red">ERROR: {0}</span>'.format(textStatus));
                 $target.css('opacity','1.0');
             })
@@ -851,10 +850,9 @@
 /**
  * Double link comments
  */
-var linkInlineComments = function(firstlinks, comments){
-    var $comments = $(comments);
+var linkInlineComments = function($firstlinks, $comments){
     if ($comments.length > 0) {
-        $(firstlinks).html('<a href="#{0}">First comment</a>'.format($comments.attr('id')));
+        $firstlinks.html('<a href="#{0}">First comment</a>'.format($comments.attr('id')));
     }
     if ($comments.length <= 1) {
         return;
@@ -863,18 +861,17 @@
     $comments.each(function(i, e){
             var prev = '';
             if (i > 0){
-                var prev_anchor = YUD.getAttribute(comments.item(i-1),'id');
+                var prev_anchor = $($comments.get(i-1)).attr('id');
                 prev = '<a href="#{0}">Previous comment</a>'.format(prev_anchor);
             }
             var next = '';
-            if (i+1 < comments.length){
-                var next_anchor = YUD.getAttribute(comments.item(i+1),'id');
+            if (i+1 < $comments.length){
+                var next_anchor = $($comments.get(i+1)).attr('id');
                 next = '<a href="#{0}">Next comment</a>'.format(next_anchor);
             }
-            var $div = $(('<div class="prev-next-comment">'+
-                          '<div class="prev-comment">{0}</div>'+
-                          '<div class="next-comment">{1}</div>').format(prev, next));
-            $div.prependTo(this);
+            $(this).find('.comment-prev-next-links').html(
+                '<div class="prev-comment">{0}</div>'.format(prev) +
+                '<div class="next-comment">{0}</div>'.format(next));
         });
 }
 
@@ -914,7 +911,7 @@
                     }
                 })
             .fail(function() {
-                    console.log('failed to load');
+                    console.log('fileBrowserListeners initFilter failed to load');
                 })
         ;
     }
@@ -2063,7 +2060,7 @@
         nextPageLinkLabel: '&gt;',
         previousPageLinkLabel: '&lt;',
         containers:containers
-    })
+    });
 
     return pagi
 }
@@ -2141,6 +2138,46 @@
         });
 }
 
+/**
+ Branch Sorting callback for select2, modifying the filtered result so prefix
+ matches come before matches in the line.
+ **/
+var branchSort = function(results, container, query) {
+    if (query.term) {
+        return results.sort(function (a, b) {
+            // Put closed branches after open ones (a bit of a hack ...)
+            var aClosed = a.text.indexOf("(closed)") > -1,
+                bClosed = b.text.indexOf("(closed)") > -1;
+            if (aClosed && !bClosed) {
+                return 1;
+            }
+            if (bClosed && !aClosed) {
+                return -1;
+            }
+
+            // Put prefix matches before matches in the line
+            var aPos = a.text.indexOf(query.term),
+                bPos = b.text.indexOf(query.term);
+            if (aPos === 0 && bPos !== 0) {
+                return -1;
+            }
+            if (bPos === 0 && aPos !== 0) {
+                return 1;
+            }
+
+            // Default sorting
+            if (a.text > b.text) {
+                return 1;
+            }
+            if (a.text < b.text) {
+                return -1;
+            }
+            return 0;
+        });
+    }
+    return results;
+};
+
 // global hooks after DOM is loaded
 
 $(document).ready(function(){
--- a/kallithea/templates/admin/auth/auth_settings.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/auth/auth_settings.html	Tue Jun 09 22:46:40 2015 +0200
@@ -37,7 +37,7 @@
                     <li>
                       <div style="padding:3px 0px 3px 0px">
                           <span style="margin: 0px 10px 0px 0px" plugin_id="${plugin_path}" class="toggle-plugin btn btn-mini ${'btn-success' if plugin_path in c.enabled_plugins else ''}">
-                          ${_('enabled') if plugin_path in c.enabled_plugins else _('disabled')}</span>${plugin_path}
+                          ${_('Enabled') if plugin_path in c.enabled_plugins else _('Disabled')}</span>${plugin_path}
                       </div>
                     </li>
                %endfor
@@ -58,7 +58,7 @@
             <div class="field">
                 <div class="label"><label for="${fullsetting}">${_(displayname)}</label></div>
                 <div class="input">
-                    ${h.password(fullsetting,class_='small',autocomplete="off")}
+                    ${h.password(fullsetting,class_='small')}
                     <span class="help-block">${setting["description"]}</span>
                 </div>
             </div>
@@ -122,7 +122,6 @@
             $cur_button.html(_TM['disabled']);
         }
         else{
-            console.log(elems);
             if(elems.indexOf(plugin_id) == -1){
                 elems.push(plugin_id);
             }
--- a/kallithea/templates/admin/defaults/defaults.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/defaults/defaults.html	Tue Jun 09 22:46:40 2015 +0200
@@ -8,7 +8,7 @@
 <%def name="breadcrumbs_links()">
     ${h.link_to(_('Admin'),h.url('admin_home'))}
     &raquo;
-    ${_('Defaults')}
+    ${_('Repository Defaults')}
 </%def>
 
 <%block name="header_menu">
--- a/kallithea/templates/admin/gists/edit.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/gists/edit.html	Tue Jun 09 22:46:40 2015 +0200
@@ -58,7 +58,7 @@
                     ${h.select('lifetime', '0', c.lifetime_options)}
                     <span class="" style="color: #AAA">
                      %if c.gist.gist_expires == -1:
-                      ${_('Expires')}: ${_('never')}
+                      ${_('Expires')}: ${_('Never')}
                      %else:
                       ${_('Expires')}: ${h.age(h.time_to_datetime(c.gist.gist_expires))}
                      %endif
@@ -164,7 +164,7 @@
                         $('#eform').submit();
                       }
                     }
-                  })
+                  });
               });
           </script>
         </div>
--- a/kallithea/templates/admin/gists/index.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/gists/index.html	Tue Jun 09 22:46:40 2015 +0200
@@ -54,7 +54,7 @@
                 ${_('Created')} ${h.age(gist.created_on)} /
                 <span style="color: #AAA">
                   %if gist.gist_expires == -1:
-                   ${_('Expires')}: ${_('never')}
+                   ${_('Expires')}: ${_('Never')}
                   %else:
                    ${_('Expires')}: ${h.age(h.time_to_datetime(gist.gist_expires))}
                   %endif
--- a/kallithea/templates/admin/gists/show.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/gists/show.html	Tue Jun 09 22:46:40 2015 +0200
@@ -44,7 +44,7 @@
                         </div>
                         <div class="left item last" style="color: #AAA">
                          %if c.gist.gist_expires == -1:
-                          ${_('Expires')}: ${_('never')}
+                          ${_('Expires')}: ${_('Never')}
                          %else:
                           ${_('Expires')}: ${h.age(h.time_to_datetime(c.gist.gist_expires))}
                          %endif
--- a/kallithea/templates/admin/my_account/my_account.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/my_account/my_account.html	Tue Jun 09 22:46:40 2015 +0200
@@ -33,12 +33,12 @@
            </div>
           </li>
           <li class="${'active' if c.active=='profile' else ''}"><a href="${h.url('my_account')}">${_('Profile')}</a></li>
+          <li class="${'active' if c.active=='emails' else ''}"><a href="${h.url('my_account_emails')}">${_('Email Addresses')}</a></li>
           <li class="${'active' if c.active=='password' else ''}"><a href="${h.url('my_account_password')}">${_('Password')}</a></li>
           <li class="${'active' if c.active=='api_keys' else ''}"><a href="${h.url('my_account_api_keys')}">${_('API Keys')}</a></li>
-          <li class="${'active' if c.active=='emails' else ''}"><a href="${h.url('my_account_emails')}">${_('My Emails')}</a></li>
-          <li class="${'active' if c.active=='repos' else ''}"><a href="${h.url('my_account_repos')}">${_('My Repositories')}</a></li>
-          <li class="${'active' if c.active=='watched' else ''}"><a href="${h.url('my_account_watched')}">${_('Watched')}</a></li>
-          <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('my_account_perms')}">${_('My Permissions')}</a></li>
+          <li class="${'active' if c.active=='repos' else ''}"><a href="${h.url('my_account_repos')}">${_('Owned Repositories')}</a></li>
+          <li class="${'active' if c.active=='watched' else ''}"><a href="${h.url('my_account_watched')}">${_('Watched Repositories')}</a></li>
+          <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('my_account_perms')}">${_('Show Permissions')}</a></li>
         </ul>
     </div>
 
--- a/kallithea/templates/admin/my_account/my_account_api_keys.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/my_account/my_account_api_keys.html	Tue Jun 09 22:46:40 2015 +0200
@@ -5,14 +5,14 @@
         <td>
             <span class="btn btn-mini btn-success disabled">${_('Built-in')}</span>
         </td>
-        <td>${_('expires')}: ${_('never')}</td>
+        <td>${_('Expires')}: ${_('Never')}</td>
         <td>
             ${h.form(url('my_account_api_keys'),method='delete')}
                 ${h.hidden('del_api_key',c.user.api_key)}
                 ${h.hidden('del_api_key_builtin',1)}
                 <button class="btn btn-mini btn-danger" type="submit"
-                        onclick="return confirm('${_('Confirm to reset this api key: %s') % c.user.api_key}');">
-                    ${_('reset')}
+                        onclick="return confirm('${_('Confirm to reset this API key: %s') % c.user.api_key}');">
+                    ${_('Reset')}
                 </button>
             ${h.end_form()}
         </td>
@@ -24,12 +24,12 @@
             <td>${api_key.description}</td>
             <td style="min-width: 80px">
                  %if api_key.expires == -1:
-                  ${_('expires')}: ${_('never')}
+                  ${_('Expires')}: ${_('Never')}
                  %else:
                     %if api_key.expired:
-                        ${_('expired')}: ${h.age(h.time_to_datetime(api_key.expires))}
+                        ${_('Expired')}: ${h.age(h.time_to_datetime(api_key.expires))}
                     %else:
-                        ${_('expires')}: ${h.age(h.time_to_datetime(api_key.expires))}
+                        ${_('Expires')}: ${h.age(h.time_to_datetime(api_key.expires))}
                     %endif
                  %endif
             </td>
@@ -37,16 +37,16 @@
                 ${h.form(url('my_account_api_keys'),method='delete')}
                     ${h.hidden('del_api_key',api_key.api_key)}
                     <button class="btn btn-mini btn-danger" type="submit"
-                            onclick="return confirm('${_('Confirm to remove this api key: %s') % api_key.api_key}');">
+                            onclick="return confirm('${_('Confirm to remove this API key: %s') % api_key.api_key}');">
                         <i class="icon-minus-circled"></i>
-                        ${_('remove')}
+                        ${_('Remove')}
                     </button>
                 ${h.end_form()}
             </td>
           </tr>
         %endfor
     %else:
-    <tr><td><div class="ip">${_('No additional api keys specified')}</div></td></tr>
+    <tr><td><div class="ip">${_('No additional API keys specified')}</div></td></tr>
     %endif
   </table>
 </div>
@@ -58,7 +58,7 @@
         <div class="fields">
              <div class="field">
                 <div class="label">
-                    <label for="description">${_('New api key')}:</label>
+                    <label for="description">${_('New API key')}:</label>
                 </div>
                 <div class="input">
                     ${h.text('description', class_='medium', placeholder=_('Description'))}
@@ -79,5 +79,5 @@
         $("#lifetime").select2({
             'dropdownAutoWidth': true
         });
-    })
+    });
 </script>
--- a/kallithea/templates/admin/my_account/my_account_emails.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/my_account/my_account_emails.html	Tue Jun 09 22:46:40 2015 +0200
@@ -16,7 +16,7 @@
                 ${h.form(url('my_account_emails'),method='delete')}
                     ${h.hidden('del_email_id',em.email_id)}
                     <i class="icon-minus-circled" style="color:#FF4444"></i>
-                    ${h.submit('remove_',_('delete'),id="remove_email_%s" % em.email_id,
+                    ${h.submit('remove_',_('Delete'),id="remove_email_%s" % em.email_id,
                     class_="action_button", onclick="return  confirm('"+_('Confirm to delete this email: %s') % em.email+"');")}
                 ${h.end_form()}
             </td>
--- a/kallithea/templates/admin/my_account/my_account_password.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/my_account/my_account_password.html	Tue Jun 09 22:46:40 2015 +0200
@@ -7,7 +7,7 @@
             <label for="current_password">${_('Current password')}:</label>
         </div>
         <div class="input">
-            ${h.password('current_password',class_='medium',autocomplete="off")}
+            ${h.password('current_password',class_='medium')}
         </div>
      </div>
 
@@ -16,7 +16,7 @@
             <label for="new_password">${_('New password')}:</label>
         </div>
         <div class="input">
-            ${h.password('new_password',class_='medium', autocomplete="off")}
+            ${h.password('new_password',class_='medium')}
         </div>
      </div>
 
@@ -25,7 +25,7 @@
             <label for="password_confirmation">${_('Confirm new password')}:</label>
         </div>
         <div class="input">
-            ${h.password('new_password_confirmation',class_='medium', autocomplete="off")}
+            ${h.password('new_password_confirmation',class_='medium')}
         </div>
      </div>
 
--- a/kallithea/templates/admin/my_account/my_account_profile.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/my_account/my_account_profile.html	Tue Jun 09 22:46:40 2015 +0200
@@ -13,7 +13,7 @@
                 %else:
                 <strong>${_('Avatars are disabled')}</strong>
                 <br/>${c.user.email or _('Missing email, please update your user email address.')}
-                    [${_('current IP')}: ${c.perm_user.ip_addr or "?"}]
+                    [${_('Current IP')}: ${c.perm_user.ip_addr or "?"}]
                 %endif
                </p>
            </div>
--- a/kallithea/templates/admin/my_account/my_account_repos.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/my_account/my_account_repos.html	Tue Jun 09 22:46:40 2015 +0200
@@ -30,7 +30,7 @@
         if (req) {
             req = req.toLowerCase();
             for (i = 0; i<data.length; i++) {
-                var pos = data[i].raw_name.toLowerCase().indexOf(req)
+                var pos = data[i].raw_name.toLowerCase().indexOf(req);
                 if (pos != -1) {
                     filtered.push(data[i]);
                 }
--- a/kallithea/templates/admin/my_account/my_account_watched.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/my_account/my_account_watched.html	Tue Jun 09 22:46:40 2015 +0200
@@ -30,7 +30,7 @@
         if (req) {
             req = req.toLowerCase();
             for (i = 0; i<data.length; i++) {
-                var pos = data[i].raw_name.toLowerCase().indexOf(req)
+                var pos = data[i].raw_name.toLowerCase().indexOf(req);
                 if (pos != -1) {
                     filtered.push(data[i]);
                 }
--- a/kallithea/templates/admin/notifications/show_notification.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/notifications/show_notification.html	Tue Jun 09 22:46:40 2015 +0200
@@ -48,7 +48,7 @@
 var main = "${url('notifications')}";
    $('.delete-notification').click(function(e){
        var notification_id = e.currentTarget.id;
-       deleteNotification(url,notification_id,[function(){window.location=main}])
+       deleteNotification(url,notification_id,[function(){window.location=main}]);
    });
 </script>
 </%def>
--- a/kallithea/templates/admin/permissions/permissions.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/permissions/permissions.html	Tue Jun 09 22:46:40 2015 +0200
@@ -2,13 +2,13 @@
 <%inherit file="/base/base.html"/>
 
 <%block name="title">
-    ${_('Permissions Administration')}
+    ${_('Default Permissions')}
 </%block>
 
 <%def name="breadcrumbs_links()">
     ${h.link_to(_('Admin'),h.url('admin_home'))}
     &raquo;
-    ${_('Permissions')}
+    ${_('Default Permissions')}
 </%def>
 
 <%block name="header_menu">
@@ -27,7 +27,7 @@
       <ul class="nav nav-pills nav-stacked">
         <li class="${'active' if c.active=='globals' else ''}"><a href="${h.url('admin_permissions')}">${_('Global')}</a></li>
         <li class="${'active' if c.active=='ips' else ''}"><a href="${h.url('admin_permissions_ips')}">${_('IP Whitelist')}</a></li>
-        <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('admin_permissions_perms')}">${_('Overview')}</a></li>
+        <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('admin_permissions_perms')}">${_('Show Permissions')}</a></li>
       </ul>
     </div>
 
--- a/kallithea/templates/admin/permissions/permissions_globals.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/permissions/permissions_globals.html	Tue Jun 09 22:46:40 2015 +0200
@@ -50,7 +50,7 @@
                     ${h.checkbox('overwrite_default_user_group','true')}
                     <label for="overwrite_default_user_group">
                     <span class="tooltip"
-                    title="${h.tooltip(_('All default permissions on each user group will be reset to chosen permission, note that all custom default permission on repository groups will be lost'))}">
+                    title="${h.tooltip(_('All default permissions on each user group will be reset to chosen permission, note that all custom default permission on user groups will be lost'))}">
                     ${_('Overwrite existing settings')}</span> </label>
 
                 </div>
--- a/kallithea/templates/admin/permissions/permissions_ips.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/permissions/permissions_ips.html	Tue Jun 09 22:46:40 2015 +0200
@@ -9,8 +9,8 @@
                 ${h.form(url('edit_user_ips', id=c.user.user_id),method='delete')}
                     ${h.hidden('del_ip_id',ip.ip_id)}
                     ${h.hidden('default_user', 'True')}
-                    <i class="icon-minus-circled" style="color:#FF4444"></i> ${h.submit('remove_',_('delete'),id="remove_ip_%s" % ip.ip_id,
-                    class_="action_button", onclick="return confirm('"+_('Confirm to delete this ip: %s') % ip.ip_addr+"');")}
+                    <i class="icon-minus-circled" style="color:#FF4444"></i> ${h.submit('remove_',_('Delete'),id="remove_ip_%s" % ip.ip_id,
+                    class_="action_button", onclick="return confirm('"+_('Confirm to delete this IP address: %s') % ip.ip_addr+"');")}
                 ${h.end_form()}
               </td>
           </tr>
@@ -27,7 +27,7 @@
         <div class="fields">
              <div class="field">
                 <div class="label">
-                    <label for="new_ip">${_('New ip address')}:</label>
+                    <label for="new_ip">${_('New IP address')}:</label>
                 </div>
                 <div class="input">
                     ${h.hidden('default_user', 'True')}
--- a/kallithea/templates/admin/repo_groups/repo_group_add.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repo_groups/repo_group_add.html	Tue Jun 09 22:46:40 2015 +0200
@@ -76,7 +76,7 @@
     $(document).ready(function(){
         var setCopyPermsOption = function(group_val){
             if(group_val != "-1"){
-                $('#copy_perms').show()
+                $('#copy_perms').show();
             }
             else{
                 $('#copy_perms').hide();
@@ -85,11 +85,11 @@
         $("#group_parent_id").select2({
             'dropdownAutoWidth': true
         });
-        setCopyPermsOption($('#group_parent_id').val())
+        setCopyPermsOption($('#group_parent_id').val());
         $("#group_parent_id").on("change", function(e) {
-            setCopyPermsOption(e.val)
-        })
+            setCopyPermsOption(e.val);
+        });
         $('#group_name').focus();
-    })
+    });
 </script>
 </%def>
--- a/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html	Tue Jun 09 22:46:40 2015 +0200
@@ -7,7 +7,7 @@
     (_('Total repositories'), c.repo_group.repositories_recursive_count, ''),
     (_('Children groups'), c.repo_group.children.count(), ''),
     (_('Created on'), h.fmt_date(c.repo_group.created_on), ''),
-    (_('Owner'), h.person(c.repo_group.user), '')
+    (_('Owner'), h.person(c.repo_group.user), ''),
  ]
 %>
 %for dt, dd, tt in elems:
--- a/kallithea/templates/admin/repo_groups/repo_group_edit_perms.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repo_groups/repo_group_edit_perms.html	Tue Jun 09 22:46:40 2015 +0200
@@ -4,11 +4,11 @@
         <div class="field">
             <table id="permissions_manage" class="noborder">
                 <tr>
-                    <td>${_('none')}</td>
-                    <td>${_('read')}</td>
-                    <td>${_('write')}</td>
-                    <td>${_('admin')}</td>
-                    <td>${_('user/user group')}</td>
+                    <td>${_('None')}</td>
+                    <td>${_('Read')}</td>
+                    <td>${_('Write')}</td>
+                    <td>${_('Admin')}</td>
+                    <td>${_('User/User Group')}</td>
                     <td></td>
                 </tr>
                 ## USERS
@@ -25,13 +25,13 @@
                             %if h.HasPermissionAny('hg.admin')() and r2p.user.username != 'default':
                              <a href="${h.url('edit_user',id=r2p.user.user_id)}">${r2p.user.username}</a>
                             %else:
-                             ${r2p.user.username if r2p.user.username != 'default' else _('default')}
+                             ${r2p.user.username if r2p.user.username != 'default' else _('Default')}
                             %endif
                         </td>
                         <td>
                           %if r2p.user.username !='default':
                             <span style="color:#da4f49" class="action_button" onclick="ajaxActionRevoke(${r2p.user.user_id}, 'user', '${'id%s'%id(r2p.user.username)}', '${r2p.user.username}')">
-                             <i class="icon-minus-circled"></i> ${_('revoke')}
+                             <i class="icon-minus-circled"></i> ${_('Revoke')}
                             </span>
                           %endif
                         </td>
@@ -42,9 +42,9 @@
                         <td>${h.radio('u_perm_%s' % r2p.user.username,'group.admin', disabled="disabled")}</td>
                         <td style="white-space: nowrap;">
                             ${h.gravatar(r2p.user.email, cls="perm-gravatar", size=14)}
-                            ${r2p.user.username if r2p.user.username != 'default' else _('default')}
+                            ${r2p.user.username if r2p.user.username != 'default' else _('Default')}
                         </td>
-                        <td><i class="icon-user"></i> ${_('delegated admin')}</td>
+                        <td><i class="icon-user"></i> ${_('Delegated Admin')}</td>
                         %endif
                     </tr>
                 %endfor
@@ -68,7 +68,7 @@
                         </td>
                         <td>
                             <span style="color:#da4f49" class="action_button" onclick="ajaxActionRevoke(${g2p.users_group.users_group_id}, 'user_group', '${'id%s'%id(g2p.users_group.users_group_name)}', '${g2p.users_group.users_group_name}')">
-                            <i class="icon-minus-circled"></i> ${_('revoke')}
+                            <i class="icon-minus-circled"></i> ${_('Revoke')}
                             </span>
                         </td>
                     </tr>
@@ -100,7 +100,7 @@
                 </tr>
                 <tr>
                     <td colspan="6">
-                       ${_('apply to children')}:
+                       ${_('Apply to children')}:
                        ${h.radio('recursive', 'none', label=_('None'), checked="checked")}
                        ${h.radio('recursive', 'groups', label=_('Repository Groups'))}
                        ${h.radio('recursive', 'repos', label=_('Repositories'))}
--- a/kallithea/templates/admin/repo_groups/repo_group_edit_settings.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repo_groups/repo_group_edit_settings.html	Tue Jun 09 22:46:40 2015 +0200
@@ -61,5 +61,5 @@
         $("#group_parent_id").select2({
             'dropdownAutoWidth': true
         });
-    })
+    });
 </script>
--- a/kallithea/templates/admin/repos/repo_add_base.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_add_base.html	Tue Jun 09 22:46:40 2015 +0200
@@ -11,7 +11,10 @@
             <div class="input">
                 ${h.text('repo_name',class_="small")}
                 <div style="margin: 6px 0px 0px 0px">
-                    <a id="remote_clone_toggle" href="#"><i class="icon-download-cloud"></i> ${_('Import existing repository ?')}</a>
+                    <a id="remote_clone_toggle" href="#">
+                        <i class="icon-download-cloud"></i>
+                        ${_('Import existing repository ?')}
+                    </a>
                 </div>
                 %if not c.authuser.is_admin:
                     ${h.hidden('user_created',True)}
@@ -24,7 +27,9 @@
             </div>
             <div class="input">
                 ${h.text('clone_uri',class_="small")}
-                <span class="help-block">${_('Optional URL from which repository should be cloned.')}</span>
+                <span class="help-block">
+                    ${_('Optional URL from which repository should be cloned.')}
+                </span>
             </div>
         </div>
         <div class="field">
@@ -90,7 +95,7 @@
     $(document).ready(function(){
         var setCopyPermsOption = function(group_val){
             if(group_val != "-1"){
-                $('#copy_perms').show()
+                $('#copy_perms').show();
             }
             else{
                 $('#copy_perms').hide();
@@ -100,7 +105,7 @@
         $('#remote_clone_toggle').on('click', function(e){
             $('#remote_clone').show();
             e.preventDefault();
-        })
+        });
         if($('#remote_clone input').hasClass('error')){
             $('#remote_clone').show();
         }
@@ -111,10 +116,10 @@
             'dropdownAutoWidth': true
         });
 
-        setCopyPermsOption($('#repo_group').val())
+        setCopyPermsOption($('#repo_group').val());
         $("#repo_group").on("change", function(e) {
-            setCopyPermsOption(e.val)
-        })
+            setCopyPermsOption(e.val);
+        });
 
         $("#repo_type").select2({
             'minimumResultsForSearch': -1
@@ -123,6 +128,6 @@
             'minimumResultsForSearch': -1
         });
         $('#repo_name').focus();
-    })
+    });
 </script>
 ${h.end_form()}
--- a/kallithea/templates/admin/repos/repo_creating.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_creating.html	Tue Jun 09 22:46:40 2015 +0200
@@ -57,7 +57,7 @@
           setTimeout(worker, 1000);
       }
       else{
-          $("#progress").html($('#progress_error').html())
+          $("#progress").html($('#progress_error').html());
       }
     }
   });
--- a/kallithea/templates/admin/repos/repo_edit_advanced.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_edit_advanced.html	Tue Jun 09 22:46:40 2015 +0200
@@ -16,7 +16,7 @@
         $("#id_fork_of").select2({
             'dropdownAutoWidth': true
         });
-    })
+    });
 </script>
 
 <h3>${_('Public Journal Visibility')}</h3>
--- a/kallithea/templates/admin/repos/repo_edit_fields.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_edit_fields.html	Tue Jun 09 22:46:40 2015 +0200
@@ -15,7 +15,7 @@
             <td>
               ${h.form(url('delete_repo_fields', repo_name=c.repo_info.repo_name, field_id=field.repo_field_id),method='delete')}
                   <i class="icon-minus-circled" style="color:#FF4444"></i>
-                  ${h.submit('remove_%s' % field.repo_field_id, _('delete'), id="remove_field_%s" % field.repo_field_id,
+                  ${h.submit('remove_%s' % field.repo_field_id, _('Delete'), id="remove_field_%s" % field.repo_field_id,
                   class_="action_button", onclick="return confirm('"+_('Confirm to delete this field: %s') % field.field_key+"');")}
               ${h.end_form()}
             </td>
--- a/kallithea/templates/admin/repos/repo_edit_fork.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_edit_fork.html	Tue Jun 09 22:46:40 2015 +0200
@@ -17,5 +17,5 @@
         $("#id_fork_of").select2({
             'dropdownAutoWidth': true
         });
-    })
+    });
 </script>
--- a/kallithea/templates/admin/repos/repo_edit_permissions.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_edit_permissions.html	Tue Jun 09 22:46:40 2015 +0200
@@ -5,11 +5,11 @@
             ${h.hidden('repo_private')}
             <table id="permissions_manage" class="noborder">
                 <tr>
-                    <td>${_('none')}</td>
-                    <td>${_('read')}</td>
-                    <td>${_('write')}</td>
-                    <td>${_('admin')}</td>
-                    <td>${_('user/user group')}</td>
+                    <td>${_('None')}</td>
+                    <td>${_('Read')}</td>
+                    <td>${_('Write')}</td>
+                    <td>${_('Admin')}</td>
+                    <td>${_('User/User Group')}</td>
                     <td></td>
                 </tr>
                 ## USERS
@@ -18,10 +18,10 @@
                         <tr>
                             <td colspan="4">
                                 <span class="private_repo_msg">
-                                ${_('private repository')}
+                                ${_('Private Repository')}
                                 </span>
                             </td>
-                            <td class="private_repo_msg"><i class="icon-user"></i> ${_('default')}</td>
+                            <td class="private_repo_msg"><i class="icon-user"></i> ${_('Default')}</td>
                         </tr>
                     %else:
                     <tr id="id${id(r2p.user.username)}">
@@ -34,13 +34,13 @@
                             %if h.HasPermissionAny('hg.admin')() and r2p.user.username != 'default':
                              <a href="${h.url('edit_user',id=r2p.user.user_id)}">${r2p.user.username}</a>
                             %else:
-                             ${r2p.user.username if r2p.user.username != 'default' else _('default')}
+                             ${r2p.user.username if r2p.user.username != 'default' else _('Default')}
                             %endif
                         </td>
                         <td>
                           %if r2p.user.username !='default':
                             <span style="color:#da4f49" class="action_button" onclick="ajaxActionRevoke(${r2p.user.user_id}, 'user', '${'id%s'%id(r2p.user.username)}', '${r2p.user.username}')">
-                            <i class="icon-minus-circled"></i> ${_('revoke')}
+                            <i class="icon-minus-circled"></i> ${_('Revoke')}
                             </span>
                           %endif
                         </td>
@@ -65,7 +65,7 @@
                         </td>
                         <td>
                             <span style="color:#da4f49" class="action_button" onclick="ajaxActionRevoke(${g2p.users_group.users_group_id}, 'user_group', '${'id%s'%id(g2p.users_group.users_group_name)}', '${g2p.users_group.users_group_name}')">
-                            <i class="icon-minus-circled"></i> ${_('revoke')}
+                            <i class="icon-minus-circled"></i> ${_('Revoke')}
                             </span>
                         </td>
                     </tr>
--- a/kallithea/templates/admin/repos/repo_edit_remote.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_edit_remote.html	Tue Jun 09 22:46:40 2015 +0200
@@ -4,9 +4,12 @@
 </div>
 ${h.form(url('edit_repo_remote', repo_name=c.repo_name), method='put')}
 <div class="form">
-   <div class="fields">
-       ${h.submit('remote_pull_%s' % c.repo_info.repo_name,_('Pull Changes from Remote Location'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to pull changes from remote side.')+"');")}
-   </div>
+    <div class="fields">
+        ${h.submit('remote_pull_%s' % c.repo_info.repo_name,
+            _('Pull Changes from Remote Location'),
+            class_="btn btn-small",
+            onclick="return confirm('"+_('Confirm to pull changes from remote side.')+"');")}
+    </div>
 </div>
 ${h.end_form()}
 %else:
--- a/kallithea/templates/admin/repos/repo_edit_settings.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/repos/repo_edit_settings.html	Tue Jun 09 22:46:40 2015 +0200
@@ -15,27 +15,29 @@
                                Using the above permanent URL guarantees that this repository always will be accessible on that URL.
                                This is useful for CI systems, or any other cases that you need to hardcode the URL into a 3rd party service.''')}</span>
                 </div>
-           </div>
-           <div class="field">
-               <div class="label">
-                   <label for="clone_uri">${_('Clone URL')}:</label>
-               </div>
-               <div class="input">
-                   %if c.repo_info.clone_uri:
+            </div>
+            <div class="field">
+                <div class="label">
+                    <label for="clone_uri">${_('Clone URL')}:</label>
+                </div>
+                <div class="input">
+                  %if c.repo_info.clone_uri:
                     <div id="clone_uri_hidden" style="font-size: 14px">
                         <span id="clone_uri_hidden_value">${c.repo_info.clone_uri_hidden}</span>
-                        <span style="cursor: pointer; padding: 0px 0px 5px 0px" id="edit_clone_uri"><i class="icon-edit"></i>${_('edit')}</span>
+                        <span style="cursor: pointer; padding: 0px 0px 5px 0px" id="edit_clone_uri"><i class="icon-edit"></i>${_('Edit')}</span>
                     </div>
                     <div id="alter_clone_uri" style="display: none">
                         ${h.text('clone_uri',class_="medium",  placeholder=_('new value'))}
                     </div>
-                   %else:
+                  %else:
                     ## not set yet, display form to set it
                     ${h.text('clone_uri',class_="medium")}
                     ${h.hidden('clone_uri_change', 'NEW')}
-                   %endif
-                 <span id="alter_clone_uri_help_block" class="help-block">${_('URL used for doing remote pulls.')}</span>
-               </div>
+                  %endif
+                  <span id="alter_clone_uri_help_block" class="help-block">
+                      ${_('URL used for doing remote pulls.')}
+                  </span>
+                </div>
             </div>
             <div class="field">
                 <div class="label">
@@ -143,15 +145,15 @@
         $('#show_more_clone_id').on('click', function(e){
             $('#clone_id').show();
             e.preventDefault();
-        })
+        });
         $('#edit_clone_uri').on('click', function(e){
           $('#alter_clone_uri').show();
           $('#edit_clone_uri').hide();
           $('#clone_uri_hidden').hide();
           ## store hash of old value for change detection
           var uri_change =  '<input id="clone_uri_change" name="clone_uri_change" type="hidden" value="${h.md5(c.repo_info.clone_uri or "").hexdigest()}" />';
-          $('#alter_clone_uri_help_block').html($('#alter_clone_uri_help_block').html()+" ("+$('#clone_uri_hidden_value').html()+")")
-        })
+          $('#alter_clone_uri_help_block').html($('#alter_clone_uri_help_block').html()+" ("+$('#clone_uri_hidden_value').html()+")");
+        });
 
         $('#repo_landing_rev').select2({
             'dropdownAutoWidth': true
@@ -160,5 +162,5 @@
             'dropdownAutoWidth': true
         });
 
-    })
+    });
 </script>
--- a/kallithea/templates/admin/settings/settings_email.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/settings/settings_email.html	Tue Jun 09 22:46:40 2015 +0200
@@ -13,7 +13,7 @@
 
     (_('SMTP use TLS'), c.ini.get('smtp_use_tls'), ''),
     (_('SMTP use SSL'), c.ini.get('smtp_use_ssl'), ''),
-    (_('SMTP auth'), c.ini.get('smtp_auth'), '')
+    (_('SMTP auth'), c.ini.get('smtp_auth'), ''),
  ]
 %>
 %for dt, dd, tt in elems:
--- a/kallithea/templates/admin/settings/settings_hooks.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/settings/settings_hooks.html	Tue Jun 09 22:46:40 2015 +0200
@@ -33,7 +33,7 @@
             <span class="action_button"
             onclick="ajaxActionHook(${hook.ui_id},'${'id%s' % hook.ui_id }')">
             <i class="icon-minus-circled" style="color:#FF4444"></i>
-            ${_('delete')}
+            ${_('Delete')}
             </span>
         </div>
       </div>
--- a/kallithea/templates/admin/settings/settings_system.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/settings/settings_system.html	Tue Jun 09 22:46:40 2015 +0200
@@ -1,12 +1,12 @@
 <dl class="dl-horizontal">
 <%
  elems = [
-    (_('Kallithea version'), h.literal('%s <b><span style="color:#036185; text-decoration: underline;cursor: pointer" id="check_for_update" >%s</span></b>' % (c.kallithea_version, _('check for updates'))), ''),
+    (_('Kallithea version'), h.literal('%s <b><span style="color:#036185; text-decoration: underline;cursor: pointer" id="check_for_update" >%s</span></b>' % (c.kallithea_version, _('Check for updates'))), ''),
     (_('Python version'), c.py_version, ''),
     (_('Platform'), c.platform, ''),
     (_('Git version'), c.git_version, ''),
     (_('Git path'), c.ini.get('git_path'), ''),
-    (_('Upgrade info endpoint'), h.literal('%s <br/><span style="color:#999999">%s.</span>' % (c.update_url, _('Note: please make sure this server can access this URL'))), '')
+    (_('Upgrade info endpoint'), h.literal('%s <br/><span style="color:#999999">%s.</span>' % (c.update_url, _('Note: please make sure this server can access this URL'))), ''),
  ]
 %>
 
--- a/kallithea/templates/admin/settings/settings_vcs.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/settings/settings_vcs.html	Tue Jun 09 22:46:40 2015 +0200
@@ -91,6 +91,6 @@
                 $('#path_unlock_icon').addClass('icon-lock-open-alt');
                 $('#paths_root_path').removeAttr('readonly');
                 $('#paths_root_path').removeClass('disabled');
-            })
-        })
+            });
+        });
     </script>
--- a/kallithea/templates/admin/user_groups/user_group_add.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/user_groups/user_group_add.html	Tue Jun 09 22:46:40 2015 +0200
@@ -64,6 +64,6 @@
 <script>
     $(document).ready(function(){
         $('#users_group_name').focus();
-    })
+    });
 </script>
 </%def>
--- a/kallithea/templates/admin/user_groups/user_group_edit.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/user_groups/user_group_edit.html	Tue Jun 09 22:46:40 2015 +0200
@@ -28,9 +28,9 @@
       <ul class="nav nav-pills nav-stacked">
         <li class="${'active' if c.active=='settings' else ''}"><a href="${h.url('edit_users_group', id=c.user_group.users_group_id)}">${_('Settings')}</a></li>
         <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.url('edit_user_group_advanced', id=c.user_group.users_group_id)}">${_('Advanced')}</a></li>
-        <li class="${'active' if c.active=='default_perms' else ''}"><a href="${h.url('edit_user_group_default_perms', id=c.user_group.users_group_id)}">${_('Default permissions')}</a></li>
         <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('edit_user_group_perms', id=c.user_group.users_group_id)}">${_('Permissions')}</a></li>
-        <li class="${'active' if c.active=='members' else ''}"><a href="${h.url('edit_user_group_members', id=c.user_group.users_group_id)}">${_('Members')}</a></li>
+        <li class="${'active' if c.active=='default_perms' else ''}"><a href="${h.url('edit_user_group_default_perms', id=c.user_group.users_group_id)}">${_('Show Permissions')}</a></li>
+        <li class="${'active' if c.active=='members' else ''}"><a href="${h.url('edit_user_group_members', id=c.user_group.users_group_id)}">${_('Show Members')}</a></li>
       </ul>
     </div>
 
--- a/kallithea/templates/admin/user_groups/user_group_edit_advanced.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/user_groups/user_group_edit_advanced.html	Tue Jun 09 22:46:40 2015 +0200
@@ -5,7 +5,7 @@
  elems = [
     (_('Members'), len(c.group_members_obj), ''),
     (_('Created on'), h.fmt_date(c.user_group.created_on), ''),
-    (_('Owner'), h.person(c.user_group.user), '')
+    (_('Owner'), h.person(c.user_group.user), ''),
     ]
 %>
 %for dt, dd, tt in elems:
--- a/kallithea/templates/admin/user_groups/user_group_edit_perms.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/user_groups/user_group_edit_perms.html	Tue Jun 09 22:46:40 2015 +0200
@@ -4,11 +4,11 @@
         <div class="field">
             <table id="permissions_manage" class="noborder">
                 <tr>
-                    <td>${_('none')}</td>
-                    <td>${_('read')}</td>
-                    <td>${_('write')}</td>
-                    <td>${_('admin')}</td>
-                    <td>${_('user/user group')}</td>
+                    <td>${_('None')}</td>
+                    <td>${_('Read')}</td>
+                    <td>${_('Write')}</td>
+                    <td>${_('Admin')}</td>
+                    <td>${_('User/User Group')}</td>
                     <td></td>
                 </tr>
                 ## USERS
@@ -25,13 +25,13 @@
                             %if h.HasPermissionAny('hg.admin')() and r2p.user.username != 'default':
                              <a href="${h.url('edit_user',id=r2p.user.user_id)}">${r2p.user.username}</a>
                             %else:
-                             ${r2p.user.username if r2p.user.username != 'default' else _('default')}
+                             ${r2p.user.username if r2p.user.username != 'default' else _('Default')}
                             %endif
                         </td>
                         <td>
                           %if r2p.user.username !='default':
                             <span style="color:#da4f49" class="action_button" onclick="ajaxActionRevoke(${r2p.user.user_id}, 'user', '${'id%s'%id(r2p.user.username)}', '${r2p.user.username}')">
-                             <i class="icon-minus-circled"></i> ${_('revoke')}
+                             <i class="icon-minus-circled"></i> ${_('Revoke')}
                             </span>
                           %endif
                         </td>
@@ -42,9 +42,9 @@
                         <td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.admin', disabled="disabled")}</td>
                         <td style="white-space: nowrap;">
                             ${h.gravatar(r2p.user.email, cls="perm-gravatar", size=14)}
-                            ${r2p.user.username if r2p.user.username != 'default' else _('default')}
+                            ${r2p.user.username if r2p.user.username != 'default' else _('Default')}
                         </td>
-                        <td><i class="icon-user"></i> ${_('delegated admin')}</td>
+                        <td><i class="icon-user"></i> ${_('Delegated Admin')}</td>
                         %endif
                     </tr>
                 %endfor
@@ -68,7 +68,7 @@
                         </td>
                         <td>
                             <span style="color:#da4f49" class="action_button" onclick="ajaxActionRevoke(${g2p.user_group.users_group_id}, 'user_group', '${'id%s'%id(g2p.user_group.users_group_name)}', '${g2p.user_group.users_group_name}')">
-                            <i class="icon-minus-circled"></i> ${_('revoke')}
+                            <i class="icon-minus-circled"></i> ${_('Revoke')}
                             </span>
                         </td>
                     </tr>
--- a/kallithea/templates/admin/user_groups/user_groups.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/user_groups/user_groups.html	Tue Jun 09 22:46:40 2015 +0200
@@ -7,7 +7,7 @@
 
 <%def name="breadcrumbs_links()">
     <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
-    ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; <span id="user_group_count">0</span> ${_('user groups')}
+    ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; <span id="user_group_count">0</span> ${_('User Groups')}
 </%def>
 
 <%block name="header_menu">
--- a/kallithea/templates/admin/users/user_add.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/users/user_add.html	Tue Jun 09 22:46:40 2015 +0200
@@ -41,7 +41,7 @@
                     <label for="password">${_('Password')}:</label>
                 </div>
                 <div class="input">
-                    ${h.password('password',class_='small',autocomplete="off")}
+                    ${h.password('password',class_='small')}
                 </div>
              </div>
 
@@ -50,7 +50,7 @@
                     <label for="password_confirmation">${_('Password confirmation')}:</label>
                 </div>
                 <div class="input">
-                    ${h.password('password_confirmation',class_="small",autocomplete="off")}
+                    ${h.password('password_confirmation',class_="small")}
                 </div>
              </div>
 
@@ -103,6 +103,6 @@
 <script>
     $(document).ready(function(){
         $('#username').focus();
-    })
+    });
 </script>
 </%def>
--- a/kallithea/templates/admin/users/user_edit.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/users/user_edit.html	Tue Jun 09 22:46:40 2015 +0200
@@ -27,11 +27,11 @@
     <div style="width: 150px; float:left">
       <ul class="nav nav-pills nav-stacked">
         <li class="${'active' if c.active=='profile' else ''}"><a href="${h.url('edit_user', id=c.user.user_id)}">${_('Profile')}</a></li>
+        <li class="${'active' if c.active=='emails' else ''}"><a href="${h.url('edit_user_emails', id=c.user.user_id)}">${_('Emails')}</a></li>
         <li class="${'active' if c.active=='api_keys' else ''}"><a href="${h.url('edit_user_api_keys', id=c.user.user_id)}">${_('API Keys')}</a></li>
+        <li class="${'active' if c.active=='ips' else ''}"><a href="${h.url('edit_user_ips', id=c.user.user_id)}">${_('IP Whitelist')}</a></li>
         <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.url('edit_user_advanced', id=c.user.user_id)}">${_('Advanced')}</a></li>
-        <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('edit_user_perms', id=c.user.user_id)}">${_('Default Permissions')}</a></li>
-        <li class="${'active' if c.active=='emails' else ''}"><a href="${h.url('edit_user_emails', id=c.user.user_id)}">${_('Emails')}</a></li>
-        <li class="${'active' if c.active=='ips' else ''}"><a href="${h.url('edit_user_ips', id=c.user.user_id)}">${_('IP Whitelist')}</a></li>
+        <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('edit_user_perms', id=c.user.user_id)}">${_('Show Permissions')}</a></li>
       </ul>
     </div>
 
--- a/kallithea/templates/admin/users/user_edit_advanced.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/users/user_edit_advanced.html	Tue Jun 09 22:46:40 2015 +0200
@@ -7,7 +7,7 @@
     (_('Source of Record'), c.user.extern_type, ''),
     (_('Created on'), h.fmt_date(c.user.created_on), ''),
     (_('Last Login'), c.user.last_login or '-', ''),
-    (_('Member of User groups'), len(c.user.group_member), ', '.join((x.users_group.users_group_name for x in c.user.group_member)))
+    (_('Member of User groups'), len(c.user.group_member), ', '.join((x.users_group.users_group_name for x in c.user.group_member))),
  ]
 %>
 %for dt, dd, tt in elems:
--- a/kallithea/templates/admin/users/user_edit_api_keys.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/users/user_edit_api_keys.html	Tue Jun 09 22:46:40 2015 +0200
@@ -5,14 +5,14 @@
         <td>
             <span class="btn btn-mini btn-success disabled">${_('Built-in')}</span>
         </td>
-        <td>${_('expires')}: ${_('never')}</td>
+        <td>${_('Expires')}: ${_('Never')}</td>
         <td>
             ${h.form(url('edit_user_api_keys', id=c.user.user_id),method='delete')}
                 ${h.hidden('del_api_key',c.user.api_key)}
                 ${h.hidden('del_api_key_builtin',1)}
                 <button class="btn btn-mini btn-danger" type="submit"
-                        onclick="return confirm('${_('Confirm to reset this api key: %s') % c.user.api_key}');">
-                    ${_('reset')}
+                        onclick="return confirm('${_('Confirm to reset this API key: %s') % c.user.api_key}');">
+                    ${_('Reset')}
                 </button>
             ${h.end_form()}
         </td>
@@ -24,12 +24,12 @@
             <td>${api_key.description}</td>
             <td style="min-width: 80px">
                  %if api_key.expires == -1:
-                  ${_('expires')}: ${_('never')}
+                  ${_('Expires')}: ${_('Never')}
                  %else:
                     %if api_key.expired:
-                        ${_('expired')}: ${h.age(h.time_to_datetime(api_key.expires))}
+                        ${_('Expired')}: ${h.age(h.time_to_datetime(api_key.expires))}
                     %else:
-                        ${_('expires')}: ${h.age(h.time_to_datetime(api_key.expires))}
+                        ${_('Expires')}: ${h.age(h.time_to_datetime(api_key.expires))}
                     %endif
                  %endif
             </td>
@@ -37,28 +37,28 @@
                 ${h.form(url('edit_user_api_keys', id=c.user.user_id),method='delete')}
                     ${h.hidden('del_api_key',api_key.api_key)}
                     <button class="btn btn-mini btn-danger" type="submit"
-                            onclick="return confirm('${_('Confirm to remove this api key: %s') % api_key.api_key}');">
+                            onclick="return confirm('${_('Confirm to remove this API key: %s') % api_key.api_key}');">
                         <i class="icon-minus-circled"></i>
-                        ${_('remove')}
+                        ${_('Remove')}
                     </button>
                 ${h.end_form()}
             </td>
           </tr>
         %endfor
     %else:
-    <tr><td><div class="ip">${_('No additional api keys specified')}</div></td></tr>
+    <tr><td><div class="ip">${_('No additional API keys specified')}</div></td></tr>
     %endif
   </table>
 </div>
 
 <div>
-    ${h.form(url('edit_user_api_keys', id=c.user.user_id), method='put')}
+    ${h.form(url('edit_user_api_keys', id=c.user.user_id), method='post')}
     <div class="form">
         <!-- fields -->
         <div class="fields">
              <div class="field">
                 <div class="label">
-                    <label for="description">${_('New api key')}:</label>
+                    <label for="description">${_('New API key')}:</label>
                 </div>
                 <div class="input">
                     ${h.text('description', class_='medium', placeholder=_('Description'))}
@@ -79,5 +79,5 @@
         $("#lifetime").select2({
             'dropdownAutoWidth': true
         });
-    })
+    });
 </script>
--- a/kallithea/templates/admin/users/user_edit_emails.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/users/user_edit_emails.html	Tue Jun 09 22:46:40 2015 +0200
@@ -16,7 +16,7 @@
                 ${h.form(url('edit_user_emails', id=c.user.user_id),method='delete')}
                     ${h.hidden('del_email_id',em.email_id)}
                     <i class="icon-minus-circled" style="color:#FF4444"></i>
-                    ${h.submit('remove_',_('delete'),id="remove_email_%s" % em.email_id,
+                    ${h.submit('remove_',_('Delete'),id="remove_email_%s" % em.email_id,
                     class_="action_button", onclick="return  confirm('"+_('Confirm to delete this email: %s') % em.email+"');")}
                 ${h.end_form()}
             </td>
--- a/kallithea/templates/admin/users/user_edit_ips.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/users/user_edit_ips.html	Tue Jun 09 22:46:40 2015 +0200
@@ -19,8 +19,8 @@
                 ${h.form(url('edit_user_ips', id=c.user.user_id),method='delete')}
                     ${h.hidden('del_ip_id',ip.ip_id)}
                     <i class="icon-minus-circled" style="color:#FF4444"></i>
-                    ${h.submit('remove_',_('delete'),id="remove_ip_%s" % ip.ip_id,
-                    class_="action_button", onclick="return  confirm('"+_('Confirm to delete this ip: %s') % ip.ip_addr+"');")}
+                    ${h.submit('remove_',_('Delete'),id="remove_ip_%s" % ip.ip_id,
+                    class_="action_button", onclick="return  confirm('"+_('Confirm to delete this IP address: %s') % ip.ip_addr+"');")}
                 ${h.end_form()}
             </td>
           </tr>
@@ -39,7 +39,7 @@
         <div class="fields">
              <div class="field">
                 <div class="label">
-                    <label for="new_ip">${_('New ip address')}:</label>
+                    <label for="new_ip">${_('New IP address')}:</label>
                 </div>
                 <div class="input">
                     ${h.text('new_ip', class_='medium')}
--- a/kallithea/templates/admin/users/user_edit_profile.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/admin/users/user_edit_profile.html	Tue Jun 09 22:46:40 2015 +0200
@@ -12,7 +12,7 @@
                 <br/>${c.user.email or _('Missing email, please update this user email address.')}
                         ##show current ip just if we show ourself
                         %if c.authuser.username == c.user.username:
-                            [${_('current IP')}: ${c.perm_user.ip_addr or "?"}]
+                            [${_('Current IP')}: ${c.perm_user.ip_addr or "?"}]
                         %endif
                 %endif
            </div>
@@ -69,7 +69,7 @@
                     <label for="new_password">${_('New password')}:</label>
                 </div>
                 <div class="input">
-                    ${h.password('new_password',class_='medium%s' % disabled,autocomplete="off",readonly=readonly)}
+                    ${h.password('new_password',class_='medium%s' % disabled,readonly=readonly)}
                 </div>
              </div>
 
@@ -78,7 +78,7 @@
                     <label for="password_confirmation">${_('New password confirmation')}:</label>
                 </div>
                 <div class="input">
-                    ${h.password('password_confirmation',class_="medium%s" % disabled,autocomplete="off",readonly=readonly)}
+                    ${h.password('password_confirmation',class_="medium%s" % disabled,readonly=readonly)}
                 </div>
              </div>
 
--- a/kallithea/templates/base/base.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/base/base.html	Tue Jun 09 22:46:40 2015 +0200
@@ -61,9 +61,9 @@
       <li><a href="${h.url('repos_groups')}"><i class="icon-folder"></i> ${_('Repository Groups')}</a></li>
       <li><a href="${h.url('users')}"><i class="icon-user"></i> ${_('Users')}</a></li>
       <li><a href="${h.url('users_groups')}"><i class="icon-users"></i> ${_('User Groups')}</a></li>
-      <li><a href="${h.url('admin_permissions')}"><i class="icon-block"></i> ${_('Permissions')}</a></li>
+      <li><a href="${h.url('admin_permissions')}"><i class="icon-block"></i> ${_('Default Permissions')}</a></li>
       <li><a href="${h.url('auth_home')}"><i class="icon-key"></i> ${_('Authentication')}</a></li>
-      <li><a href="${h.url('defaults')}"><i class="icon-wrench"></i> ${_('Defaults')}</a></li>
+      <li><a href="${h.url('defaults')}"><i class="icon-wrench"></i> ${_('Repository Defaults')}</a></li>
       <li class="last"><a href="${h.url('admin_settings')}"><i class="icon-gear"></i> ${_('Settings')}</a></li>
   </ul>
 
@@ -419,11 +419,11 @@
                     var children = [];
                     $.each(this.children, function(){
                         if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
-                            children.push({'id': this.id, 'text': this.text, 'type': this.type, 'obj': this.obj})
+                            children.push({'id': this.id, 'text': this.text, 'type': this.type, 'obj': this.obj});
                         }
-                    })
+                    });
                     if(children.length !== 0){
-                        data.results.push({'text': section, 'children': children})
+                        data.results.push({'text': section, 'children': children});
                     }
 
                 });
@@ -438,21 +438,21 @@
                       cache[key] = data;
                       query.callback({results: data.results});
                     }
-                  })
+                  });
               }
             }
         });
 
         $("#repo_switcher").on('select2-selecting', function(e){
             e.preventDefault();
-            window.location = pyroutes.url('summary_home', {'repo_name': e.val})
-        })
+            window.location = pyroutes.url('summary_home', {'repo_name': e.val});
+        });
 
         ## Global mouse bindings ##
 
         // general help "?"
         Mousetrap.bind(['?'], function(e) {
-            $('#help_kb').modal({})
+            $('#help_kb').modal({});
         });
 
         // / open the quick filter
@@ -544,7 +544,7 @@
                          ('g g', 'Goto my private gists page'),
                          ('g G', 'Goto my public gists page'),
                          ('n r', 'New repository page'),
-                         ('n g', 'New gist page')
+                         ('n g', 'New gist page'),
                      ]
                   %>
                   %for key, desc in elems:
@@ -572,7 +572,7 @@
                          ('g f', 'Goto files page'),
                          ('g F', 'Goto files page with file search activated'),
                          ('g o', 'Goto repository settings'),
-                         ('g O', 'Goto repository permissions settings')
+                         ('g O', 'Goto repository permissions settings'),
                      ]
                   %>
                   %for key, desc in elems:
--- a/kallithea/templates/base/default_perms_box.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/base/default_perms_box.html	Tue Jun 09 22:46:40 2015 +0200
@@ -11,13 +11,13 @@
         <div class="fields">
              <div class="field">
                 <div class="label label-checkbox">
-                    <label for="inherit_default_permissions">${_('Inherit from defaults')}:</label>
+                    <label for="inherit_default_permissions">${_('Inherit defaults')}:</label>
                 </div>
                 <div class="checkboxes">
                     ${h.checkbox('inherit_default_permissions',value=True)}
                     <span class="help-block">
-                    ${h.literal(_('Select to inherit permissions from %s permissions settings, and default IP address whitelist.')
-                                % h.link_to('default global', url('admin_permissions')))}
+                    ${h.literal(_('Select to inherit global settings, IP whitelist and permissions from the %s.')
+                                % h.link_to('default permissions', url('admin_permissions')))}
                     </span>
                 </div>
              </div>
@@ -83,7 +83,7 @@
     $('#inherit_default_permissions').change(function(){
         show_custom_perms($('#inherit_default_permissions').prop('checked'));
     });
-})
+});
 </script>
 
 </%def>
--- a/kallithea/templates/base/perms_summary.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/base/perms_summary.html	Tue Jun 09 22:46:40 2015 +0200
@@ -10,11 +10,11 @@
             ${section.replace("_"," ").capitalize()}
             %if section != 'global':
                 <div style="float: right">
-                ${_('show')}:
-                ${h.checkbox('perms_filter_none_%s' % section, 'none', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='none')}   <label for="${'perms_filter_none_%s' % section}"><span class="perm_tag none">${_('none')}</span></label>
-                ${h.checkbox('perms_filter_read_%s' % section, 'read', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='read')}   <label for="${'perms_filter_read_%s' % section}"><span class="perm_tag read">${_('read')}</span></label>
-                ${h.checkbox('perms_filter_write_%s' % section, 'write', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='write')} <label for="${'perms_filter_write_%s' % section}"> <span class="perm_tag write">${_('write')}</span></label>
-                ${h.checkbox('perms_filter_admin_%s' % section, 'admin', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='admin')} <label for="${'perms_filter_admin_%s' % section}"><span class="perm_tag admin">${_('admin')}</span></label>
+                ${_('Show')}:
+                ${h.checkbox('perms_filter_none_%s' % section, 'none', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='none')} <label for="${'perms_filter_none_%s' % section}"><span class="perm_tag none">${_('None')}</span></label>
+                ${h.checkbox('perms_filter_read_%s' % section, 'read', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='read')} <label for="${'perms_filter_read_%s' % section}"><span class="perm_tag read">${_('Read')}</span></label>
+                ${h.checkbox('perms_filter_write_%s' % section, 'write', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='write')} <label for="${'perms_filter_write_%s' % section}"> <span class="perm_tag write">${_('Write')}</span></label>
+                ${h.checkbox('perms_filter_admin_%s' % section, 'admin', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='admin')} <label for="${'perms_filter_admin_%s' % section}"><span class="perm_tag admin">${_('Admin')}</span></label>
                 </div>
             %endif
         </div>
@@ -40,7 +40,7 @@
                       </td>
                       %if actions:
                       <td>
-                           <a href="${h.url('admin_permissions')}">${_('edit')}</a>
+                           <a href="${h.url('admin_permissions')}">${_('Edit')}</a>
                       </td>
                       %endif
                   </tr>
@@ -76,11 +76,11 @@
                       %if actions:
                       <td>
                           %if section == 'repositories':
-                              <a href="${h.url('edit_repo_perms',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a>
+                              <a href="${h.url('edit_repo_perms',repo_name=k,anchor='permissions_manage')}">${_('Edit')}</a>
                           %elif section == 'repositories_groups':
-                              <a href="${h.url('edit_repo_group_perms',group_name=k,anchor='permissions_manage')}">${_('edit')}</a>
+                              <a href="${h.url('edit_repo_group_perms',group_name=k,anchor='permissions_manage')}">${_('Edit')}</a>
                           %elif section == 'user_groups':
-                              ##<a href="${h.url('edit_users_group',id=k)}">${_('edit')}</a>
+                              ##<a href="${h.url('edit_users_group',id=k)}">${_('Edit')}</a>
                           %endif
                       </td>
                       %endif
@@ -99,8 +99,6 @@
     $(document).ready(function(){
         var show_empty = function(section){
             var visible = $('.section_{0} tr.perm_row:visible'.format(section)).length;
-            console.log(visible)
-            console.log($('.section_{0} tr.perm_row:visible'.format(section)))
             if(visible == 0){
                 $('#empty_{0}'.format(section)).show();
             }
@@ -108,15 +106,12 @@
                 $('#empty_{0}'.format(section)).hide();
             }
         }
-        $('.perm_filter').on('change', function(e){
-            var self = this;
-            var section = $(this).attr('section');
+        var update_show = function($checkbox){
+            var section = $checkbox.attr('section');
 
-            var opts = {}
             var elems = $('.filter_' + section).each(function(el){
-                var perm_type = $(this).attr('perm_type');
-                var checked = this.checked;
-                opts[perm_type] = checked;
+                var perm_type = $checkbox.attr('perm_type');
+                var checked = $checkbox.prop('checked');
                 if(checked){
                     $('.'+section+'_'+perm_type).show();
                 }
@@ -125,8 +120,9 @@
                 }
             });
             show_empty(section);
-        })
-
-    })
+        }
+        $('.perm_filter').on('change', function(){update_show($(this));});
+        $('.perm_filter[value=none]').each(function(){this.checked = false; update_show($(this));});
+    });
 </script>
 </%def>
--- a/kallithea/templates/changelog/changelog.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/changelog/changelog.html	Tue Jun 09 22:46:40 2015 +0200
@@ -89,11 +89,11 @@
                           %if c.statuses.get(cs.raw_id):
                             <div class="changeset-status-ico">
                             %if c.statuses.get(cs.raw_id)[2]:
-                              <a class="tooltip" title="${_('Changeset status: %s\nClick to open associated pull request #%s') % (h.changeset_status_lbl(c.statuses.get(cs.raw_id)[0]), c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}">
+                              <a class="tooltip" title="${_('Changeset status: %s\nClick to open associated pull request %s') % (c.statuses.get(cs.raw_id)[1], c.statuses.get(cs.raw_id)[4])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}">
                                 <i class="icon-circle changeset-status-${c.statuses.get(cs.raw_id)[0]}"></i>
                               </a>
                             %else:
-                              <a class="tooltip" title="${_('Changeset status: %s') % h.changeset_status_lbl(c.statuses.get(cs.raw_id)[0])}" href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
+                              <a class="tooltip" title="${_('Changeset status: %s') % c.statuses.get(cs.raw_id)[1]}" href="${c.comments[cs.raw_id][0].url()}">
                                   <i class="icon-circle changeset-status-${c.statuses.get(cs.raw_id)[0]}"></i>
                               </a>
                             %endif
@@ -122,7 +122,7 @@
                                     %if c.comments.get(cs.raw_id):
                                         <div class="comments-container">
                                             <div class="comments-cnt" title="${_('Changeset has comments')}">
-                                                <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
+                                                <a href="${c.comments[cs.raw_id][0].url()}">
                                                     ${len(c.comments[cs.raw_id])}
                                                     <i class="icon-comment-discussion"></i>
                                                 </a>
@@ -210,7 +210,7 @@
                         YUD.get('open_new_pr').href = pyroutes.url('pullrequest_home',
                                                                    {'repo_name': '${c.repo_name}',
                                                                     'rev_start': rev_start,
-                                                                    'rev_end': rev_end})
+                                                                    'rev_end': rev_end});
 
                         YUD.setStyle('compare_fork','display','none');
                     }else{
@@ -266,7 +266,8 @@
                 // change branch filter
                 $("#branch_filter").select2({
                     dropdownAutoWidth: true,
-                    minimumInputLength: 1
+                    minimumInputLength: 1,
+                    sortResults: branchSort
                     });
 
                 $("#branch_filter").change(function(e){
--- a/kallithea/templates/changelog/changelog_summary_data.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/changelog/changelog_summary_data.html	Tue Jun 09 22:46:40 2015 +0200
@@ -15,15 +15,15 @@
         <td class="compact">
             <div class="changeset-status-container">
               %if c.statuses.get(cs.raw_id):
-                <div class="changeset-status-ico shortlog">
+                <span class="changeset-status-ico shortlog">
                 %if c.statuses.get(cs.raw_id)[2]:
-                  <a class="tooltip" title="${_('Changeset status: %s\nClick to open associated pull request #%s') % (c.statuses.get(cs.raw_id)[0], c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}">
+                  <a class="tooltip" title="${_('Changeset status: %s\nClick to open associated pull request %s') % (c.statuses.get(cs.raw_id)[1], c.statuses.get(cs.raw_id)[4])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}">
                     <i class="icon-circle changeset-status-${c.statuses.get(cs.raw_id)[0]}"></i>
                   </a>
                 %else:
                   <i class="icon-circle changeset-status-${c.statuses.get(cs.raw_id)[0]}"></i>
                 %endif
-                </div>
+                </span>
               %endif
             </div>
         </td>
@@ -31,7 +31,7 @@
               %if c.comments.get(cs.raw_id,[]):
                <div class="comments-container">
                    <div title="${('comments')}">
-                       <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
+                       <a href="${c.comments[cs.raw_id][0].url()}">
                           <i class="icon-comment"></i>${len(c.comments[cs.raw_id])}
                        </a>
                    </div>
--- a/kallithea/templates/changeset/changeset.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/changeset/changeset.html	Tue Jun 09 22:46:40 2015 +0200
@@ -33,21 +33,21 @@
         <div class="diffblock">
             <div class="parents">
                 <div id="parent_link" class="changeset_hash">
-                    <i style="color:#036185" class="icon-left-open"></i> <a href="#">${_('parent rev.')}</a>
+                    <i style="color:#036185" class="icon-left-open"></i> <a href="#">${_('Parent rev.')}</a>
                 </div>
             </div>
 
             <div class="children">
                 <div id="child_link" class="changeset_hash">
-                    <a href="#">${_('child rev.')}</a> <i style="color:#036185" class="icon-right-open"></i>
+                    <a href="#">${_('Child rev.')}</a> <i style="color:#036185" class="icon-right-open"></i>
                 </div>
             </div>
 
             <div class="code-header banner">
                 <div class="changeset-status-container">
                     %if c.statuses:
-                        <div class="changeset-status-ico"><i class="icon-circle changeset-status-${c.statuses[0]}"></i></div>
-                        <div title="${_('Changeset status')}" class="changeset-status-lbl">[${h.changeset_status_lbl(c.statuses[0])}]</div>
+                        <span class="changeset-status-ico"><i class="icon-circle changeset-status-${c.statuses[0]}"></i></span>
+                        <span title="${_('Changeset status')}" class="changeset-status-lbl">[${h.changeset_status_lbl(c.statuses[0])}]</span>
                     %endif
                 </div>
                 <div class="diff-actions">
@@ -86,7 +86,7 @@
 
                     <span class="logtags">
                         %if len(c.changeset.parents)>1:
-                        <span class="merge">${_('merge')}</span>
+                        <span class="merge">${_('Merge')}</span>
                         %endif
 
                         %if h.is_hg(c.db_repo_scm_instance):
@@ -205,7 +205,7 @@
           var file_comments = $('.inline-comment-placeholder').toArray();
           renderInlineComments(file_comments);
 
-          linkInlineComments(document.getElementsByClassName('firstlink'), document.getElementsByClassName("comment"));
+          linkInlineComments($('.firstlink'), $('.comment'));
 
           pyroutes.register('changeset_home',
                             "${h.url('changeset_home', repo_name='%(repo_name)s', revision='%(revision)s')}",
@@ -221,7 +221,7 @@
                     success: function(data) {
                       if(data.results.length === 0){
                           $('#child_link').addClass('disabled');
-                          $('#child_link').html('${_('no revisions')}');
+                          $('#child_link').html('${_('No revisions')}');
                       }
                       if(data.results.length === 1){
                           var commit = data.results[0];
@@ -246,7 +246,7 @@
                   });
               e.preventDefault();
               }
-          })
+          });
 
           //prev links
           $('#parent_link').on('click', function(e){
@@ -258,7 +258,7 @@
                     success: function(data) {
                       if(data.results.length === 0){
                           $('#parent_link').addClass('disabled');
-                          $('#parent_link').html('${_('no revisions')}');
+                          $('#parent_link').html('${_('No revisions')}');
                       }
                       if(data.results.length === 1){
                           var commit = data.results[0];
@@ -289,7 +289,7 @@
           if (window.location.hash != "") {
               window.location.href = window.location.href;
           }
-      })
+      });
 
     </script>
 
--- a/kallithea/templates/changeset/changeset_comment_block.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/changeset/changeset_comment_block.html	Tue Jun 09 22:46:40 2015 +0200
@@ -1,4 +1,4 @@
 ## this is a dummy html file for partial rendering on server and sending
 ## generated output via ajax after comment submit
 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
-${comment.comment_block(c.co)}
+${comment.comment_block(c.comment)}
--- a/kallithea/templates/changeset/changeset_file_comment.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/changeset/changeset_file_comment.html	Tue Jun 09 22:46:40 2015 +0200
@@ -5,53 +5,43 @@
 ##
 <%def name="comment_block(co)">
   <div class="comment" id="comment-${co.comment_id}" line="${co.line_no}">
+    <div class="comment-prev-next-links"></div>
     <div class="comment-wrapp">
       <div class="meta">
           <div style="float:left">
                ${h.gravatar(co.author.email, size=20)}
           </div>
           <div class="user">
-              ${co.author.username}
-          </div>
-          <div class="date">
-              ${h.age(co.modified_at)}
+              ${co.author.username_and_name}
           </div>
 
-       <div style="float:left;padding:4px 0px 0px 5px">
-        <span class="">
-         %if co.pull_request:
-            %if co.status_change:
-              ${_('Status change from pull request')}
-              <a href="${co.pull_request.url()}">"${co.pull_request.title or _("No title")}"</a>:
-            %else:
-              ${_('Comment from pull request')}
-              <a href="${co.pull_request.url()}">"${co.pull_request.title or _("No title")}"</a>
-            %endif
-         %else:
-            %if co.status_change:
-              ${_('Status change on changeset')}:
-            %else:
-              ${_('Comment on changeset')}
-            %endif
-         %endif
-        </span>
-       </div>
+          <span>
+              ${h.age(co.modified_at)}
+              %if co.pull_request:
+                ${_('on pull request')}
+                <a href="${co.pull_request.url()}">"${co.pull_request.title or _("No title")}"</a>
+              %else:
+                ${_('on this changeset')}
+              %endif
+              <a class="permalink" href="${co.url()}">&para;</a>
+          </span>
 
+          %if h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or co.author.user_id == c.authuser.user_id:
+            <div onClick="confirm('${_("Delete comment?")}') && deleteComment(${co.comment_id})" class="buttons delete-comment btn btn-mini">${_('Delete')}</div>
+          %endif
+      </div>
+      <div class="text">
         %if co.status_change:
-           <div  style="float:left" class="changeset-status-container">
-             <div style="float:left;padding:10px 2px 0px 2px"></div>
-             <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change[0].status_lbl}</div>
-             <div class="changeset-status-ico"><i class="icon-circle changeset-status-${co.status_change[0].status}"></i></div>
+           <div class="rst-block automatic-comment">
+             <p>
+               <span title="${_('Changeset status')}" class="changeset-status-lbl">${_("Status change")}: ${co.status_change[0].status_lbl}</span>
+               <span class="changeset-status-ico"><i class="icon-circle changeset-status-${co.status_change[0].status}"></i></span>
+             </p>
            </div>
         %endif
-
-      <a class="permalink" href="#comment-${co.comment_id}">&para;</a>
-      %if h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or co.author.user_id == c.authuser.user_id:
-          <div onClick="confirm('${_("Delete comment?")}') && deleteComment(${co.comment_id})" class="buttons delete-comment btn btn-mini">${_('Delete')}</div>
-      %endif
-      </div>
-      <div class="text">
+        %if co.text:
           ${h.rst_w_mentions(co.text)|n}
+        %endif
       </div>
     </div>
   </div>
@@ -118,36 +108,30 @@
     <span class="firstlink"></span>
 </%def>
 
-## generates inlines taken from c.comments var
-<%def name="inlines()">
-    <div class="comments-number">
-        ${comment_count(c.inline_cnt, len(c.comments))}
-    </div>
-    %for path, lines in c.inline_comments:
-        % for line,comments in lines.iteritems():
-            <div style="display:none" class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}">
-            %for co in comments:
-                ${comment_block(co)}
-            %endfor
-            </div>
-        %endfor
-    %endfor
-
-</%def>
 
 ## generate inline comments and the main ones
 <%def name="generate_comments()">
 <div class="comments">
-    <div id="inline-comments-container">
-    ## generate inlines for this changeset
-     ${inlines()}
-    </div>
+  <div class="comments-number">
+    ${comment_count(c.inline_cnt, len(c.comments))}
+  </div>
+  <div id="inline-comments-container">
+    %for path, lines in c.inline_comments:
+        %for line, comments in lines.iteritems():
+          <div style="display:none" class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}">
+            %for co in comments:
+                ${comment_block(co)}
+            %endfor
+          </div>
+        %endfor
+    %endfor
+  </div>
 
-    %for co in c.comments:
+  %for co in c.comments:
         <div id="comment-tr-${co.comment_id}">
           ${comment_block(co)}
         </div>
-    %endfor
+  %endfor
 </div>
 </%def>
 
--- a/kallithea/templates/changeset/changeset_range.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/changeset/changeset_range.html	Tue Jun 09 22:46:40 2015 +0200
@@ -85,7 +85,7 @@
              <div class="right">
               <span class="logtags">
                 %if len(cs.parents)>1:
-                <span class="merge">${_('merge')}</span>
+                <span class="merge">${_('Merge')}</span>
                 %endif
                 %if h.is_hg(c.db_repo_scm_instance):
                   %for book in cs.bookmarks:
--- a/kallithea/templates/compare/compare_cs.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/compare/compare_cs.html	Tue Jun 09 22:46:40 2015 +0200
@@ -28,7 +28,7 @@
           %if c.cs_comments.get(cs.raw_id):
               <div class="comments-container">
                   <div class="comments-cnt" title="${_('Changeset has comments')}">
-                      <a href="${h.url('changeset_home',repo_name=c.cs_repo.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.cs_comments[cs.raw_id][0].comment_id)}">
+                      <a href="${c.cs_comments[cs.raw_id][0].url()}">
                           ${len(c.cs_comments[cs.raw_id])}
                           <i class="icon-comment"></i>
                       </a>
@@ -36,6 +36,21 @@
               </div>
           %endif
         </td>
+        <td class="changeset-logical-index">
+          <%
+              num_cs = len(c.cs_ranges)
+              index = num_cs - cnt
+              if index == 1:
+                  title = _('First (oldest) changeset in this list')
+              elif index == num_cs:
+                  title = _('Last (most recent) changeset in this list')
+              else:
+                  title = _('Position in this list of changesets')
+          %>
+          <span class="tooltip" title="${title}">
+            ${index}
+          </span>
+        </td>
         <td style="width: 140px"><span class="tooltip" title="${h.tooltip(h.age(cs.date))}">${cs.date}</span></td>
         <td><div class="gravatar" commit_id="${cs.raw_id}">${h.gravatar(h.email_or_none(cs.author), size=14)}</div></td>
         <td><div class="author">${h.person(cs.author)}</div></td>
--- a/kallithea/templates/compare/compare_diff.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/compare/compare_diff.html	Tue Jun 09 22:46:40 2015 +0200
@@ -113,14 +113,14 @@
                 var children = [];
                 $.each(this.children, function(){
                     if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
-                        children.push({'id': this.id, 'text': this.text})
+                        children.push({'id': this.id, 'text': this.text});
                     }
-                })
-                data.results.push({'text': section, 'children': children})
+                });
+                data.results.push({'text': section, 'children': children});
             });
             //push the typed in changeset
             data.results.push({'text':_TM['Specify changeset'],
-                               'children': [{'id': query.term, 'text': query.term, 'type': 'rev'}]})
+                               'children': [{'id': query.term, 'text': query.term, 'type': 'rev'}]});
             query.callback(data);
           }else{
               $.ajax({
@@ -132,7 +132,7 @@
                   cache[key] = data;
                   query.callback(data);
                 }
-              })
+              });
           }
         }
     });
@@ -140,7 +140,7 @@
         placeholder: "${'%s@%s' % (c.cs_repo.repo_name, c.cs_ref_name)}",
         dropdownAutoWidth: true,
         formatSelection: function(obj){
-            return '{0}@{1}'.format("${c.cs_repo.repo_name}", obj.text)
+            return '{0}@{1}'.format("${c.cs_repo.repo_name}", obj.text);
         },
         query: function(query){
           var key = 'cache2';
@@ -153,14 +153,14 @@
                 var children = [];
                 $.each(this.children, function(){
                     if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
-                        children.push({'id': this.id, 'text': this.text})
+                        children.push({'id': this.id, 'text': this.text});
                     }
-                })
-                data.results.push({'text': section, 'children': children})
+                });
+                data.results.push({'text': section, 'children': children});
             });
             //push the typed in changeset
             data.results.push({'text':_TM['Specify changeset'],
-                               'children': [{'id': query.term, 'text': query.term, 'type': 'rev'}]})
+                               'children': [{'id': query.term, 'text': query.term, 'type': 'rev'}]});
             query.callback(data);
           }else{
               $.ajax({
@@ -172,7 +172,7 @@
                   cache[key] = data;
                   query.callback({results: data.results});
                 }
-              })
+              });
           }
         }
     });
--- a/kallithea/templates/data_table/_dt_elements.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/data_table/_dt_elements.html	Tue Jun 09 22:46:40 2015 +0200
@@ -119,14 +119,14 @@
 <%def name="repo_actions(repo_name, super_user=True)">
   <div>
     <div style="float:left; margin-right:5px;" class="grid_edit">
-      <a href="${h.url('edit_repo',repo_name=repo_name)}" title="${_('edit')}">
-        <i class="icon-pencil"></i> ${h.submit('edit_%s' % repo_name,_('edit'),class_="action_button")}
+      <a href="${h.url('edit_repo',repo_name=repo_name)}" title="${_('Edit')}">
+        <i class="icon-pencil"></i> ${h.submit('edit_%s' % repo_name,_('Edit'),class_="action_button")}
       </a>
     </div>
     <div style="float:left" class="grid_delete">
       ${h.form(h.url('repo', repo_name=repo_name),method='delete')}
         <i class="icon-minus-circled" style="color:#FF4444"></i>
-        ${h.submit('remove_%s' % repo_name,_('delete'),class_="action_button",
+        ${h.submit('remove_%s' % repo_name,_('Delete'),class_="action_button",
         onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo_name+"');")}
       ${h.end_form()}
     </div>
@@ -147,14 +147,14 @@
 
 <%def name="user_actions(user_id, username)">
  <div style="float:left" class="grid_edit">
-   <a href="${h.url('edit_user',id=user_id)}" title="${_('edit')}">
-     <i class="icon-pencil"></i> ${h.submit('edit_%s' % username,_('edit'),class_="action_button")}
+   <a href="${h.url('edit_user',id=user_id)}" title="${_('Edit')}">
+     <i class="icon-pencil"></i> ${h.submit('edit_%s' % username,_('Edit'),class_="action_button")}
    </a>
  </div>
  <div style="float:left" class="grid_delete">
   ${h.form(h.url('delete_user', id=user_id),method='delete')}
     <i class="icon-minus-circled" style="color:#FF4444"></i>
-    ${h.submit('remove_',_('delete'),id="remove_user_%s" % user_id, class_="action_button",
+    ${h.submit('remove_',_('Delete'),id="remove_user_%s" % user_id, class_="action_button",
     onclick="return confirm('"+_('Confirm to delete this user: %s') % username+"');")}
   ${h.end_form()}
  </div>
@@ -164,13 +164,13 @@
  <div style="float:left" class="grid_edit">
     <a href="${h.url('edit_users_group', id=user_group_id)}" title="${_('Edit')}">
     <i class="icon-pencil"></i>
-     ${h.submit('edit_%s' % user_group_name,_('edit'),class_="action_button", id_="submit_user_group_edit")}
+     ${h.submit('edit_%s' % user_group_name,_('Edit'),class_="action_button", id_="submit_user_group_edit")}
     </a>
  </div>
  <div style="float:left" class="grid_delete">
     ${h.form(h.url('users_group', id=user_group_id),method='delete')}
       <i class="icon-minus-circled" style="color:#FF4444"></i>
-      ${h.submit('remove_',_('delete'),id="remove_group_%s" % user_group_id, class_="action_button",
+      ${h.submit('remove_',_('Delete'),id="remove_group_%s" % user_group_id, class_="action_button",
       onclick="return confirm('"+_('Confirm to delete this user group: %s') % user_group_name+"');")}
     ${h.end_form()}
  </div>
@@ -180,13 +180,13 @@
  <div style="float:left" class="grid_edit">
     <a href="${h.url('edit_repo_group',group_name=repo_group_name)}" title="${_('Edit')}">
     <i class="icon-pencil"></i>
-     ${h.submit('edit_%s' % repo_group_name, _('edit'),class_="action_button")}
+     ${h.submit('edit_%s' % repo_group_name, _('Edit'),class_="action_button")}
     </a>
  </div>
  <div style="float:left" class="grid_delete">
     ${h.form(h.url('repos_group', group_name=repo_group_name),method='delete')}
         <i class="icon-minus-circled" style="color:#FF4444"></i>
-        ${h.submit('remove_%s' % repo_group_name,_('delete'),class_="action_button",
+        ${h.submit('remove_%s' % repo_group_name,_('Delete'),class_="action_button",
         onclick="return confirm('"+ungettext('Confirm to delete this group: %s with %s repository','Confirm to delete this group: %s with %s repositories',gr_count) % (repo_group_name, gr_count)+"');")}
     ${h.end_form()}
  </div>
--- a/kallithea/templates/files/diff_2way.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/files/diff_2way.html	Tue Jun 09 22:46:40 2015 +0200
@@ -75,7 +75,7 @@
         cmsettings: {mode: 'text/plain', readOnly: true, lineWrapping: false, lineNumbers: true},
         lhs: function(setValue) {
             if("${c.node1.is_binary}" == "True"){
-                setValue('Binary file')
+                setValue('Binary file');
             }
             else{
                 $.ajax(orig1_url, {dataType: 'text', success: setValue});
@@ -84,7 +84,7 @@
         },
         rhs: function(setValue) {
             if("${c.node2.is_binary}" == "True"){
-                setValue('Binary file')
+                setValue('Binary file');
             }
             else{
                 $.ajax(orig2_url, {dataType: 'text', success: setValue});
@@ -95,13 +95,13 @@
         var val = e.currentTarget.checked;
         $('#compare').mergely('options', {ignorews: val});
         $('#compare').mergely('update');
-    })
+    });
     $('#edit_mode').change(function(e){
         var val = !e.currentTarget.checked;
         $('#compare').mergely('cm', 'lhs').setOption('readOnly', val);
         $('#compare').mergely('cm', 'rhs').setOption('readOnly', val);
         $('#compare').mergely('update');
-    })
+    });
 });
 </script>
 
--- a/kallithea/templates/files/files.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/files/files.html	Tue Jun 09 22:46:40 2015 +0200
@@ -64,10 +64,10 @@
         var url = el.href;
 
         var _base_url = '${h.url("files_home",repo_name=c.repo_name,revision='',f_path='')}';
-        _base_url = _base_url.replace('//','/')
+        _base_url = _base_url.replace('//','/');
 
         //extract rev and the f_path from url.
-        parts = url.split(_base_url)
+        parts = url.split(_base_url);
         if(parts.length != 2){
             return false;
         }
@@ -145,7 +145,7 @@
     $('#hlcode').mouseup(getSelectionLink);
 
     // history select field
-    var cache = {}
+    var cache = {};
     $("#diff1").select2({
         placeholder: _TM['Select changeset'],
         dropdownAutoWidth: true,
@@ -160,10 +160,10 @@
                 var children = [];
                 $.each(this.children, function(){
                     if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
-                        children.push({'id': this.id, 'text': this.text})
+                        children.push({'id': this.id, 'text': this.text});
                     }
-                })
-                data.results.push({'text': section, 'children': children})
+                });
+                data.results.push({'text': section, 'children': children});
             });
             query.callback(data);
           }else{
@@ -176,7 +176,7 @@
                   cache[key] = data;
                   query.callback({results: data.results});
                 }
-              })
+              });
           }
         }
     });
@@ -186,10 +186,10 @@
             success: function(data) {
                 $('#file_authors').html(data);
                 $('#file_authors').show();
-                tooltip_activate()
+                tooltip_activate();
             }
-        })
-    })
+        });
+    });
 }
 
 $(document).ready(function(){
@@ -233,7 +233,8 @@
     // change branch filter
     $("#branch_selector").select2({
         dropdownAutoWidth: true,
-        minimumInputLength: 1
+        minimumInputLength: 1,
+        sortResults: branchSort
         });
 
     $("#branch_selector").change(function(e){
--- a/kallithea/templates/files/files_browser.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/files/files_browser.html	Tue Jun 09 22:46:40 2015 +0200
@@ -29,7 +29,7 @@
         <div class="browser-nav">
             ${h.form(h.url.current())}
             <div class="info_box">
-              <div class="info_box_elem rev">${_('revision')}</div>
+              <div class="info_box_elem rev">${_('Revision')}</div>
               <div class="info_box_elem"><a class="btn btn-mini ypjax-link" href="${c.url_prev}" title="${_('Previous revision')}"><i class="icon-left-open"></i></a></div>
               <div class="info_box_elem">${h.text('at_rev',value=c.changeset.revision,size=5)}</div>
               <div class="info_box_elem"><a class="btn btn-mini ypjax-link" href="${c.url_next}" title="${_('Next revision')}"><i class="icon-right-open"></i></a></div>
@@ -47,7 +47,7 @@
             <div>
                 <div id="node_filter_box_loading" style="display:none">${_('Loading file list...')}</div>
                 <div id="node_filter_box" style="display:none">
-                ${h.files_breadcrumbs(c.repo_name,c.changeset.raw_id,c.file.path)}/<input class="init" type="text" value="type to search..." name="filter" size="25" id="node_filter" autocomplete="off">
+                ${h.files_breadcrumbs(c.repo_name,c.changeset.raw_id,c.file.path)}/<input class="init" type="text" value="type to search..." name="filter" size="25" id="node_filter">
                 </div>
             </div>
         </div>
@@ -59,7 +59,6 @@
                 <tr>
                     <th>${_('Name')}</th>
                     <th>${_('Size')}</th>
-                    <th>${_('Mimetype')}</th>
                     <th>${_('Last Revision')}</th>
                     <th>${_('Last Modified')}</th>
                     <th>${_('Last Committer')}</th>
@@ -76,7 +75,6 @@
                     <td></td>
                     <td></td>
                     <td></td>
-                    <td></td>
                 </tr>
                 %endif
 
@@ -91,11 +89,6 @@
                      %endif
                      </td>
                      <td>
-                      %if node.is_file():
-                          ${node.mimetype}
-                      %endif
-                     </td>
-                     <td>
                          %if node.is_file():
                              <a title="${h.tooltip(node.last_changeset.message)}" href="${h.url('changeset_home',repo_name=c.repo_name,revision=node.last_changeset.raw_id)}" class="tooltip revision-link">${h.show_id(node.last_changeset)}</a>
                          %endif
@@ -129,5 +122,5 @@
         if(search_GET == "1"){
             $("#filter_activate").click();
         }
-    })
+    });
 </script>
--- a/kallithea/templates/files/files_edit.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/files/files_edit.html	Tue Jun 09 22:46:40 2015 +0200
@@ -98,7 +98,7 @@
     var detected_mode = CodeMirror.findModeByExtension("${c.file.extension}");
     if(detected_mode){
         setCodeMirrorMode(myCodeMirror, detected_mode);
-        $($('#set_mode option[value="'+detected_mode.mime+'"]')[0]).attr("selected", "selected")
+        $($('#set_mode option[value="'+detected_mode.mime+'"]')[0]).attr("selected", "selected");
     }
 
     $('#set_mode').on('change', function(e){
@@ -107,6 +107,6 @@
         var detected_mode = CodeMirror.findModeByMIME(node.value);
         setCodeMirrorMode(myCodeMirror, detected_mode);
     });
-})
+});
 </script>
 </%def>
--- a/kallithea/templates/files/files_source.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/files/files_source.html	Tue Jun 09 22:46:40 2015 +0200
@@ -90,5 +90,5 @@
            }
         }
         callbacks(_State) // defined in files.html, main callbacks. Triggerd in pjax calls
-    })
+    });
 </script>
--- a/kallithea/templates/forks/fork.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/forks/fork.html	Tue Jun 09 22:46:40 2015 +0200
@@ -108,6 +108,6 @@
             'minimumResultsForSearch': -1
         });
         $('#repo_name').focus();
-    })
+    });
 </script>
 </%def>
--- a/kallithea/templates/index_base.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/index_base.html	Tue Jun 09 22:46:40 2015 +0200
@@ -112,7 +112,7 @@
             if (req) {
                 req = req.toLowerCase();
                 for (i = 0; i<data.length; i++) {
-                    var pos = data[i].raw_name.toLowerCase().indexOf(req, ${len(group_name)})
+                    var pos = data[i].raw_name.toLowerCase().indexOf(req, ${len(group_name)});
                     if (pos != -1) {
                         filtered.push(data[i]);
                     }
--- a/kallithea/templates/journal/journal.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/journal/journal.html	Tue Jun 09 22:46:40 2015 +0200
@@ -50,10 +50,10 @@
             </h5>
             <ul class="links nav nav-tabs">
                 <li class="active" id="show_watched_li">
-                    <a id="show_watched" href="#watched"><i class="icon-eye"></i> ${_('Watched')}</a>
+                    <a id="show_watched" href="#watched"><i class="icon-eye"></i> ${_('Watched Repositories')}</a>
                 </li>
                 <li id="show_my_li">
-                    <a id="show_my" href="#my"><i class="icon-database"></i> ${_('My Repos')}</a>
+                    <a id="show_my" href="#my"><i class="icon-database"></i> ${_('My Repositories')}</a>
                </li>
             </ul>
         </div>
@@ -172,7 +172,7 @@
             if (req) {
                 req = req.toLowerCase();
                 for (i = 0; i<data.length; i++) {
-                    var pos = data[i].raw_name.toLowerCase().indexOf(req)
+                    var pos = data[i].raw_name.toLowerCase().indexOf(req);
                     if (pos != -1) {
                         filtered.push(data[i]);
                     }
@@ -263,7 +263,7 @@
             if (req) {
                 req = req.toLowerCase();
                 for (i = 0; i<data.length; i++) {
-                    var pos = data[i].raw_name.toLowerCase().indexOf(req)
+                    var pos = data[i].raw_name.toLowerCase().indexOf(req);
                     if (pos != -1) {
                         filtered.push(data[i]);
                     }
--- a/kallithea/templates/login.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/login.html	Tue Jun 09 22:46:40 2015 +0200
@@ -5,50 +5,47 @@
     ${_('Log In')}
 </%block>
 
-<div id="login">
+<div id="login" class="panel panel-default">
     <%include file="/base/flash_msg.html"/>
     <!-- login -->
-    <div class="title withlogo">
+    <div class="panel-heading title withlogo">
         %if c.site_name:
             <h5>${_('Log In to %s') % c.site_name}</h5>
         %else:
             <h5>${_('Log In')}</h5>
         %endif
     </div>
-    <div class="inner">
-        ${h.form(h.url.current(came_from=c.came_from))}
+    <div class="panel-body inner">
+        ${h.form(h.url.current(**request.GET))}
         <div class="form">
             <i class="icon-lock"></i>
             <!-- fields -->
 
-            <div class="fields">
-                <div class="field">
-                    <div class="label">
-                        <label for="username">${_('Username')}:</label>
-                    </div>
-                    <div class="input">
-                        ${h.text('username',class_='focus large')}
+            <div class="form-horizontal">
+                <div class="form-group">
+                    <label class="control-label col-sm-5" for="username">${_('Username')}:</label>
+                    <div class="input col-sm-7">
+                        ${h.text('username',class_='form-control focus large')}
                     </div>
 
                 </div>
-                <div class="field">
-                    <div class="label">
-                        <label for="password">${_('Password')}:</label>
-                    </div>
-                    <div class="input">
-                        ${h.password('password',class_='focus large')}
+                <div class="form-group">
+                    <label class="control-label col-sm-5" for="password">${_('Password')}:</label>
+                    <div class="input col-sm-7">
+                        ${h.password('password',class_='form-control focus large')}
                     </div>
 
                 </div>
-                <div class="field">
-                    <div class="checkbox">
-                        <input type="checkbox" id="remember" name="remember" />
-                        <label for="remember">${_('Remember me')}</label>
+                <div class="form-group">
+                    <div class="col-sm-offset-5 col-sm-7">
+                        <div class="checkbox">
+                            <label for="remember">
+                                <input type="checkbox" id="remember" name="remember"/>
+                                ${_('Remember me')}
+                            </label>
+                        </div>
                     </div>
                 </div>
-                <div class="buttons">
-                    ${h.submit('sign_in',_('Sign In'),class_="btn")}
-                </div>
             </div>
             <!-- end fields -->
             <!-- links -->
@@ -58,6 +55,9 @@
                   /
                  ${h.link_to(_("Don't have an account ?"),h.url('register'))}
                 %endif
+                <span class="buttons">
+                    ${h.submit('sign_in',_('Sign In'),class_="btn btn-default")}
+                </span>
             </div>
 
             <!-- end links -->
--- a/kallithea/templates/pullrequests/pullrequest.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/pullrequests/pullrequest.html	Tue Jun 09 22:46:40 2015 +0200
@@ -224,7 +224,8 @@
       ## (org_repo can't change)
 
       $("#org_ref").select2({
-          dropdownAutoWidth: true
+          dropdownAutoWidth: true,
+          sortResults: branchSort
       });
       $("#org_ref").on("change", function(e){
           loadPreview();
@@ -238,7 +239,8 @@
       });
 
       $("#other_ref").select2({
-          dropdownAutoWidth: true
+          dropdownAutoWidth: true,
+          sortResults: branchSort
       });
       $("#other_ref").on("change", function(e){
           loadPreview();
--- a/kallithea/templates/pullrequests/pullrequest_show.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/pullrequests/pullrequest_show.html	Tue Jun 09 22:46:40 2015 +0200
@@ -3,11 +3,11 @@
 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
 
 <%block name="title">
-    ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)}
+    ${_('%s Pull Request %s') % (c.repo_name, c.pull_request.nice_id())}
 </%block>
 
 <%def name="breadcrumbs_links()">
-    ${_('Pull request #%s from %s#%s') % (c.pull_request.pull_request_id, c.pull_request.org_repo.repo_name, c.cs_branch_name)}
+    ${_('Pull request %s from %s#%s') % (c.pull_request.nice_id(), c.pull_request.org_repo.repo_name, c.cs_branch_name)}
 </%def>
 
 <%block name="header_menu">
@@ -38,7 +38,7 @@
             <label>${_('Description')}:</label>
             %if editable:
             <div style="margin: 5px">
-              <a class="btn btn-small" onclick="YUD.setStyle('pr-edit-form','display','');YUD.setStyle(YUD.getElementsByClassName('pr-not-edit'),'display','none')">${_("Edit")}</a>
+              <a class="btn btn-small" onclick="$('#pr-edit-form').show();$('.pr-not-edit').hide()">${_("Edit")}</a>
             </div>
             %endif
           </div>
@@ -76,15 +76,14 @@
           <div class="input">
             <div class="changeset-status-container" style="float:none;clear:both">
             %if c.current_voting_result:
-              <div class="changeset-status-ico" style="padding:0px 4px 0px 0px">
-                  <i class="icon-circle changeset-status-${c.current_voting_result}" title="${_('Pull request status calculated from votes')}"></i></div>
-              <div class="changeset-status-lbl tooltip" title="${_('Pull request status calculated from votes')}">
+              <span class="changeset-status-ico" style="padding:0px 4px 0px 0px">
+                  <i class="icon-circle changeset-status-${c.current_voting_result}" title="${_('Pull request status calculated from votes')}"></i></span>
+              <span class="changeset-status-lbl tooltip" title="${_('Pull request status calculated from votes')}">
                 %if c.pull_request.is_closed():
                     ${_('Closed')},
                 %endif
                 ${h.changeset_status_lbl(c.current_voting_result)}
-              </div>
-
+              </span>
             %endif
             </div>
           </div>
@@ -221,7 +220,7 @@
                   <div class="reviewer_gravatar gravatar">
                     ${h.gravatar(member.email, size=14)}
                   </div>
-                  <div style="float:left;">${member.full_name} (${_('owner') if c.pull_request.user_id == member.user_id else _('reviewer')})</div>
+                  <div style="float:left;">${member.full_name} (${_('Owner') if c.pull_request.user_id == member.user_id else _('Reviewer')})</div>
                   <input type="hidden" value="${member.user_id}" name="review_members" />
                   %if editable:
                   <div class="reviewer_member_remove action_button" onclick="removeReviewMember(${member.user_id})" title="${_('Remove reviewer')}">
@@ -381,7 +380,7 @@
           var file_comments = $('.inline-comment-placeholder').toArray();
           renderInlineComments(file_comments);
 
-          linkInlineComments(document.getElementsByClassName('firstlink'), document.getElementsByClassName("comment"));
+          linkInlineComments($('.firstlink'), $('.comment'));
 
           $('#updaterevs input').change(function(e){
               var update = !!e.target.value;
--- a/kallithea/templates/register.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/register.html	Tue Jun 09 22:46:40 2015 +0200
@@ -33,7 +33,7 @@
                         <label for="password">${_('Password')}:</label>
                     </div>
                     <div class="input">
-                        ${h.password('password',class_="medium",autocomplete="off")}
+                        ${h.password('password',class_="medium")}
                     </div>
                 </div>
 
@@ -42,7 +42,7 @@
                         <label for="password">${_('Re-enter password')}:</label>
                     </div>
                     <div class="input">
-                        ${h.password('password_confirmation',class_="medium",autocomplete="off")}
+                        ${h.password('password_confirmation',class_="medium")}
                     </div>
                 </div>
 
--- a/kallithea/templates/search/search.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/search/search.html	Tue Jun 09 22:46:40 2015 +0200
@@ -64,8 +64,8 @@
                 <div class="select">
                     ${h.select('type',c.cur_type,[('content',_('File contents')),
                         ('commit',_('Commit messages')),
-                        ('path',_('File names'))
-                        ##('repository',_('Repository names'))
+                        ('path',_('File names')),
+                        ##('repository',_('Repository names')),
                         ])}
                 </div>
              </div>
--- a/kallithea/templates/summary/statistics.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/summary/statistics.html	Tue Jun 09 22:46:40 2015 +0200
@@ -379,7 +379,7 @@
                     item.series.label = 'commits';
                 }
                 var d = new Date(x*1000);
-                var fd = d.toDateString()
+                var fd = d.toDateString();
                 var nr_commits = parseInt(y);
 
                 var cur_data = dataset[item.series.label].data[item.dataIndex];
@@ -433,7 +433,7 @@
     overview.setSelection(initial_ranges);
 
     plot.subscribe("plotselected", plotselected);
-    plot.subscribe("plothover", plothover)
+    plot.subscribe("plothover", plothover);
 
     overview.subscribe("plotselected", function (ranges) {
         plot.setSelection(ranges);
--- a/kallithea/templates/summary/summary.html	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/templates/summary/summary.html	Tue Jun 09 22:46:40 2015 +0200
@@ -126,7 +126,7 @@
                     ${h.hidden('download_options')}
                     <span style="vertical-align: bottom">
                       <input id="archive_subrepos" type="checkbox" name="subrepos" />
-                      <label for="archive_subrepos" class="tooltip" title="${h.tooltip(_('Check this to download archive with subrepos'))}" >${_('with subrepos')}</label>
+                      <label for="archive_subrepos" class="tooltip" title="${h.tooltip(_('Check this to download archive with subrepos'))}" >${_('With subrepos')}</label>
                     </span>
                 %endif
               </div>
@@ -267,10 +267,10 @@
                 var children = [];
                 $.each(this.children, function(){
                     if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
-                        children.push({'id': this.id, 'text': this.text})
+                        children.push({'id': this.id, 'text': this.text});
                     }
-                })
-                data.results.push({'text': section, 'children': children})
+                });
+                data.results.push({'text': section, 'children': children});
             });
             query.callback(data);
           }else{
@@ -283,7 +283,7 @@
                   cache[key] = data;
                   query.callback({results: data.results});
                 }
-              })
+              });
           }
         }
     });
@@ -303,7 +303,7 @@
              url = url.replace('__SUB__',subrepos);
              url = url.replace('__NAME__',title_tmpl);
 
-             s.html(url)
+             s.html(url);
            }
        }
     });
@@ -312,7 +312,7 @@
     %for cnt,archive in enumerate(c.db_repo_scm_instance._get_archives()):
       tmpl_links["${archive['type']}"] = '${h.link_to('__NAME__', h.url('files_archive_home',repo_name=c.db_repo.repo_name, fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_='btn btn-small')}';
     %endfor
-})
+});
 </script>
 
 %if c.show_stats:
--- a/kallithea/tests/__init__.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/__init__.py	Tue Jun 09 22:46:40 2015 +0200
@@ -55,7 +55,7 @@
 from kallithea.lib.compat import unittest
 from kallithea import is_windows
 from kallithea.model.db import User
-from kallithea.tests.nose_parametrized import parameterized
+from kallithea.tests.parameterized import parameterized
 from kallithea.lib.utils2 import safe_str
 
 
--- a/kallithea/tests/api/api_base.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/api/api_base.py	Tue Jun 09 22:46:40 2015 +0200
@@ -88,7 +88,7 @@
     return gr
 
 
-class BaseTestApi(object):
+class _BaseTestApi(object):
     REPO = None
     REPO_TYPE = None
 
@@ -166,7 +166,7 @@
         id_, params = _build_data('trololo', 'get_user')
         response = api_call(self, params)
 
-        expected = 'Invalid API KEY'
+        expected = 'Invalid API key'
         self._compare_error(id_, expected, given=response.body)
 
     def test_api_missing_non_optional_param(self):
--- a/kallithea/tests/api/test_api_git.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/api/test_api_git.py	Tue Jun 09 22:46:40 2015 +0200
@@ -12,10 +12,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from kallithea.tests import *
-from kallithea.tests.api.api_base import BaseTestApi
+from kallithea.tests import TestController, GIT_REPO
+from kallithea.tests.api.api_base import _BaseTestApi
 
 
-class TestGitApi(BaseTestApi, TestController):
+class TestGitApi(_BaseTestApi, TestController):
     REPO = GIT_REPO
     REPO_TYPE = 'git'
--- a/kallithea/tests/api/test_api_hg.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/api/test_api_hg.py	Tue Jun 09 22:46:40 2015 +0200
@@ -12,10 +12,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from kallithea.tests import *
-from kallithea.tests.api.api_base import BaseTestApi
+from kallithea.tests import TestController, HG_REPO
+from kallithea.tests.api.api_base import _BaseTestApi
 
 
-class TestHgApi(BaseTestApi, TestController):
+class TestHgApi(_BaseTestApi, TestController):
     REPO = HG_REPO
     REPO_TYPE = 'hg'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/tests/conftest.py	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,29 @@
+import os
+import sys
+
+import pkg_resources
+from paste.deploy import loadapp
+import pylons.test
+from pylons.i18n.translation import _get_translator
+
+
+def pytest_configure():
+    path = os.getcwd()
+    sys.path.insert(0, path)
+    pkg_resources.working_set.add_entry(path)
+    pylons.test.pylonsapp = loadapp('config:test.ini', relative_to=path)
+
+    # Setup the config and app_globals, only works if we can get
+    # to the config object
+    conf = getattr(pylons.test.pylonsapp, 'config')
+    if conf:
+        pylons.config._push_object(conf)
+
+        if 'pylons.app_globals' in conf:
+            pylons.app_globals._push_object(conf['pylons.app_globals'])
+
+    # Initialize a translator for tests that utilize i18n
+    translator = _get_translator(pylons.config.get('lang'))
+    pylons.translator._push_object(translator)
+
+    return pylons.test.pylonsapp
--- a/kallithea/tests/fixtures/journal_dump.csv	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/fixtures/journal_dump.csv	Tue Jun 09 22:46:40 2015 +0200
@@ -1782,9 +1782,9 @@
 1846,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-11-06 04:15:29.032768
 1847,3,demo,68,aaa-project,"",user_commented_revision:0c33fa58efc5a5541d8d3f1a3d3b77367e3d94f5,2012-11-06 04:17:16.091927
 1848,3,demo,249,abcdefg,"",user_commented_revision:5d80e28538141e322b317168e2367fb03178d58c,2012-11-06 06:10:53.372505
-1849,3,demo,362,Marcin,"",started_following_repo,2012-11-06 10:45:38.505485
-1850,3,demo,362,Marcin,"",user_created_repo,2012-11-06 10:45:38.518969
-1851,3,demo,362,hidden/Marcin,"",user_updated_repo,2012-11-06 10:45:46.281581
+1849,3,demo,362,Username,"",started_following_repo,2012-11-06 10:45:38.505485
+1850,3,demo,362,Username,"",user_created_repo,2012-11-06 10:45:38.518969
+1851,3,demo,362,hidden/Username,"",user_updated_repo,2012-11-06 10:45:46.281581
 1852,3,demo,177,blah,62.200.22.2,push:b369fb18c8d61fe0d3b14c417466680230cabe46,2012-11-06 10:47:55.655029
 1853,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:d5422faf648cc589425cd3b0dbf1f6dbf93036a0,2012-11-06 13:12:05.517155
 1854,3,demo,38,code-review-test,"",user_commented_revision:6d7db5794e8cad7da042b6ae6238116c6e59a4d2,2012-11-06 16:12:59.38977
--- a/kallithea/tests/functional/test_admin_notifications.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/functional/test_admin_notifications.py	Tue Jun 09 22:46:40 2015 +0200
@@ -4,6 +4,7 @@
 from kallithea.model.user import UserModel
 from kallithea.model.notification import NotificationModel
 from kallithea.model.meta import Session
+from kallithea.lib import helpers as h
 
 
 class TestNotificationsController(TestController):
@@ -89,3 +90,39 @@
 
         response.mustcontain(subject)
         response.mustcontain(notif_body)
+
+    def test_description_with_age(self):
+        self.log_user()
+        cur_user = self._get_logged_user()
+        subject = u'test'
+        notify_body = u'hi there'
+        notification = NotificationModel().create(created_by = cur_user,
+                                                  subject    = subject,
+                                                  body       = notify_body)
+
+        description = NotificationModel().make_description(notification)
+        self.assertEqual(
+            description,
+            "{0} sent message {1}".format(
+                cur_user.username,
+                h.age(notification.created_on)
+                )
+            )
+
+    def test_description_with_datetime(self):
+        self.log_user()
+        cur_user = self._get_logged_user()
+        subject = u'test'
+        notify_body = u'hi there'
+        notification = NotificationModel().create(created_by = cur_user,
+                                                  subject    = subject,
+                                                  body       = notify_body)
+
+        description = NotificationModel().make_description(notification, False)
+        self.assertEqual(
+            description,
+            "{0} sent message at {1}".format(
+                cur_user.username,
+                h.fmt_date(notification.created_on)
+                )
+            )
--- a/kallithea/tests/functional/test_admin_repos.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/functional/test_admin_repos.py	Tue Jun 09 22:46:40 2015 +0200
@@ -26,7 +26,7 @@
     return perm
 
 
-class _BaseTest(TestController):
+class _BaseTest(object):
     """
     Write all tests here
     """
@@ -638,7 +638,7 @@
         # repo must not be in filesystem !
         self.assertFalse(os.path.isdir(os.path.join(TESTS_TMP_PATH, repo_name)))
 
-class TestAdminReposControllerGIT(_BaseTest):
+class TestAdminReposControllerGIT(TestController, _BaseTest):
     REPO = GIT_REPO
     REPO_TYPE = 'git'
     NEW_REPO = NEW_GIT_REPO
@@ -646,7 +646,7 @@
     OTHER_TYPE = 'hg'
 
 
-class TestAdminReposControllerHG(_BaseTest):
+class TestAdminReposControllerHG(TestController, _BaseTest):
     REPO = HG_REPO
     REPO_TYPE = 'hg'
     NEW_REPO = NEW_HG_REPO
--- a/kallithea/tests/functional/test_admin_users.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/functional/test_admin_users.py	Tue Jun 09 22:46:40 2015 +0200
@@ -13,6 +13,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from sqlalchemy.orm.exc import NoResultFound
+from webob.exc import HTTPNotFound
 
 from kallithea.tests import *
 from kallithea.tests.fixture import Fixture
@@ -395,7 +396,7 @@
                                 params=dict(new_ip=ip, _authentication_token=self.authentication_token()))
 
         if failure:
-            self.checkSessionFlash(response, 'Please enter a valid IPv4 or IpV6 address')
+            self.checkSessionFlash(response, 'Please enter a valid IPv4 or IPv6 address')
             response = self.app.get(url('edit_user_ips', id=user_id))
             response.mustcontain(no=[ip])
             response.mustcontain(no=[ip_range])
@@ -438,7 +439,7 @@
         user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
         response = self.app.get(url('edit_user_api_keys', id=user.user_id))
         response.mustcontain(user.api_key)
-        response.mustcontain('expires: never')
+        response.mustcontain('Expires: Never')
 
     @parameterized.expand([
         ('forever', -1),
@@ -451,8 +452,8 @@
         user_id = user.user_id
 
         response = self.app.post(url('edit_user_api_keys', id=user_id),
-                 {'_method': 'put', 'description': desc, 'lifetime': lifetime, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully created')
+                 {'description': desc, 'lifetime': lifetime, '_authentication_token': self.authentication_token()})
+        self.checkSessionFlash(response, 'API key successfully created')
         try:
             response = response.follow()
             user = User.get(user_id)
@@ -469,8 +470,8 @@
         user_id = user.user_id
 
         response = self.app.post(url('edit_user_api_keys', id=user_id),
-                {'_method': 'put', 'description': 'desc', 'lifetime': -1, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully created')
+                {'description': 'desc', 'lifetime': -1, '_authentication_token': self.authentication_token()})
+        self.checkSessionFlash(response, 'API key successfully created')
         response = response.follow()
 
         #now delete our key
@@ -479,7 +480,7 @@
 
         response = self.app.post(url('edit_user_api_keys', id=user_id),
                  {'_method': 'delete', 'del_api_key': keys[0].api_key, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully deleted')
+        self.checkSessionFlash(response, 'API key successfully deleted')
         keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all()
         self.assertEqual(0, len(keys))
 
@@ -490,10 +491,106 @@
         api_key = user.api_key
         response = self.app.get(url('edit_user_api_keys', id=user_id))
         response.mustcontain(api_key)
-        response.mustcontain('expires: never')
+        response.mustcontain('Expires: Never')
 
         response = self.app.post(url('edit_user_api_keys', id=user_id),
                  {'_method': 'delete', 'del_api_key_builtin': api_key, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully reset')
+        self.checkSessionFlash(response, 'API key successfully reset')
         response = response.follow()
         response.mustcontain(no=[api_key])
+
+# TODO To be uncommented when pytest is the test runner
+#import pytest
+#from kallithea.controllers.admin.users import UsersController
+#class TestAdminUsersController_unittest(object):
+#    """
+#    Unit tests for the users controller
+#    These are in a separate class, not deriving from TestController (and thus
+#    unittest.TestCase), to be able to benefit from pytest features like
+#    monkeypatch.
+#    """
+#    def test_get_user_or_raise_if_default(self, monkeypatch):
+#        # flash complains about an unexisting session
+#        def flash_mock(*args, **kwargs):
+#            pass
+#        monkeypatch.setattr(h, 'flash', flash_mock)
+#
+#        u = UsersController()
+#        # a regular user should work correctly
+#        user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
+#        assert u._get_user_or_raise_if_default(user.user_id) == user
+#        # the default user should raise
+#        with pytest.raises(HTTPNotFound):
+#            u._get_user_or_raise_if_default(User.get_default_user().user_id)
+
+
+class TestAdminUsersControllerForDefaultUser(TestController):
+    """
+    Edit actions on the default user are not allowed.
+    Validate that they throw a 404 exception.
+    """
+    def test_edit_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.get(url('edit_user', id=user.user_id), status=404)
+
+    def test_edit_advanced_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.get(url('edit_user_advanced', id=user.user_id), status=404)
+
+    # API keys
+    def test_edit_api_keys_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.get(url('edit_user_api_keys', id=user.user_id), status=404)
+
+    def test_add_api_keys_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.post(url('edit_user_api_keys', id=user.user_id),
+                 {'_method': 'put', '_authentication_token': self.authentication_token()}, status=404)
+
+    def test_delete_api_keys_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.post(url('edit_user_api_keys', id=user.user_id),
+                 {'_method': 'delete', '_authentication_token': self.authentication_token()}, status=404)
+
+    # Permissions
+    def test_edit_perms_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.get(url('edit_user_perms', id=user.user_id), status=404)
+
+    def test_update_perms_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.post(url('edit_user_perms', id=user.user_id),
+                 {'_method': 'put', '_authentication_token': self.authentication_token()}, status=404)
+
+    # E-mails
+    def test_edit_emails_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.get(url('edit_user_emails', id=user.user_id), status=404)
+
+    def test_add_emails_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.post(url('edit_user_emails', id=user.user_id),
+                 {'_method': 'put', '_authentication_token': self.authentication_token()}, status=404)
+
+    def test_delete_emails_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.post(url('edit_user_emails', id=user.user_id),
+                 {'_method': 'delete', '_authentication_token': self.authentication_token()}, status=404)
+
+    # IP addresses
+    # Add/delete of IP addresses for the default user is used to maintain
+    # the global IP whitelist and thus allowed. Only 'edit' is forbidden.
+    def test_edit_ip_default_user(self):
+        self.log_user()
+        user = User.get_default_user()
+        response = self.app.get(url('edit_user_ips', id=user.user_id), status=404)
--- a/kallithea/tests/functional/test_files.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/functional/test_files.py	Tue Jun 09 22:46:40 2015 +0200
@@ -63,7 +63,6 @@
         response.mustcontain('<a class="browser-dir ypjax-link" href="/vcs_test_hg/files/7ba66bec8d6dbba14a2155be32408c435c5f4492/tests"><i class="icon-folder-open"></i><span>tests</span></a>')
         response.mustcontain('<a class="browser-file ypjax-link" href="/vcs_test_hg/files/7ba66bec8d6dbba14a2155be32408c435c5f4492/README.rst"><i class="icon-doc"></i><span>README.rst</span></a>')
         response.mustcontain('1.1 KiB')
-        response.mustcontain('text/x-python')
 
     def test_index_different_branch(self):
         self.log_user()
--- a/kallithea/tests/functional/test_forks.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/functional/test_forks.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,4 +1,7 @@
 # -*- coding: utf-8 -*-
+
+import unittest
+
 from kallithea.tests import *
 from kallithea.tests.fixture import Fixture
 
@@ -12,15 +15,7 @@
 from kallithea.tests import *
 
 
-class _BaseTest(TestController):
-    """
-    Write all tests here
-    """
-    REPO = None
-    REPO_TYPE = None
-    NEW_REPO = None
-    REPO_FORK = None
-
+class _BaseFixture(unittest.TestCase):
     @classmethod
     def setup_class(cls):
         pass
@@ -40,6 +35,16 @@
         Session().delete(self.u1)
         Session().commit()
 
+
+class _BaseTestCase(object):
+    """
+    Write all tests here
+    """
+    REPO = None
+    REPO_TYPE = None
+    NEW_REPO = None
+    REPO_FORK = None
+
     def test_index(self):
         self.log_user()
         repo_name = self.REPO
@@ -218,14 +223,14 @@
         response.mustcontain('There are no forks yet')
 
 
-class TestGIT(_BaseTest):
+class TestGIT(TestController, _BaseTestCase, _BaseFixture):
     REPO = GIT_REPO
     NEW_REPO = NEW_GIT_REPO
     REPO_TYPE = 'git'
     REPO_FORK = GIT_FORK
 
 
-class TestHG(_BaseTest):
+class TestHG(TestController, _BaseTestCase, _BaseFixture):
     REPO = HG_REPO
     NEW_REPO = NEW_HG_REPO
     REPO_TYPE = 'hg'
--- a/kallithea/tests/functional/test_login.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/functional/test_login.py	Tue Jun 09 22:46:40 2015 +0200
@@ -66,7 +66,7 @@
           ('mailto:test@example.com',),
           ('file:///etc/passwd',),
           ('ftp://some.ftp.server',),
-          ('http://other.domain',),
+          ('http://other.domain/bl%C3%A5b%C3%A6rgr%C3%B8d',),
     ])
     def test_login_bad_came_froms(self, url_came_from):
         response = self.app.post(url(controller='login', action='index',
@@ -96,6 +96,66 @@
         response.mustcontain('invalid user name')
         response.mustcontain('invalid password')
 
+    # verify that get arguments are correctly passed along login redirection
+
+    @parameterized.expand([
+        ({'foo':'one', 'bar':'two'}, ('foo=one', 'bar=two')),
+        ({'blue': u'blå'.encode('utf-8'), 'green':u'grøn'},
+             ('blue=bl%C3%A5', 'green=gr%C3%B8n')),
+    ])
+    def test_redirection_to_login_form_preserves_get_args(self, args, args_encoded):
+        with fixture.anon_access(False):
+            response = self.app.get(url(controller='summary', action='index',
+                                        repo_name=HG_REPO,
+                                        **args))
+            self.assertEqual(response.status, '302 Found')
+            for encoded in args_encoded:
+                self.assertIn(encoded, response.location)
+
+    @parameterized.expand([
+        ({'foo':'one', 'bar':'two'}, ('foo=one', 'bar=two')),
+        ({'blue': u'blå'.encode('utf-8'), 'green':u'grøn'},
+             ('blue=bl%C3%A5', 'green=gr%C3%B8n')),
+    ])
+    def test_login_form_preserves_get_args(self, args, args_encoded):
+        response = self.app.get(url(controller='login', action='index',
+                                    came_from = '/_admin/users',
+                                    **args))
+        for encoded in args_encoded:
+            self.assertIn(encoded, response.form.action)
+
+    @parameterized.expand([
+        ({'foo':'one', 'bar':'two'}, ('foo=one', 'bar=two')),
+        ({'blue': u'blå'.encode('utf-8'), 'green':u'grøn'},
+             ('blue=bl%C3%A5', 'green=gr%C3%B8n')),
+    ])
+    def test_redirection_after_successful_login_preserves_get_args(self, args, args_encoded):
+        response = self.app.post(url(controller='login', action='index',
+                                     came_from = '/_admin/users',
+                                     **args),
+                                 {'username': 'test_admin',
+                                  'password': 'test12'})
+        self.assertEqual(response.status, '302 Found')
+        for encoded in args_encoded:
+            self.assertIn(encoded, response.location)
+
+    @parameterized.expand([
+        ({'foo':'one', 'bar':'two'}, ('foo=one', 'bar=two')),
+        ({'blue': u'blå'.encode('utf-8'), 'green':u'grøn'},
+             ('blue=bl%C3%A5', 'green=gr%C3%B8n')),
+    ])
+    def test_login_form_after_incorrect_login_preserves_get_args(self, args, args_encoded):
+        response = self.app.post(url(controller='login', action='index',
+                                     came_from = '/_admin/users',
+                                     **args),
+                                 {'username': 'error',
+                                  'password': 'test12'})
+
+        response.mustcontain('invalid user name')
+        response.mustcontain('invalid password')
+        for encoded in args_encoded:
+            self.assertIn(encoded, response.form.action)
+
     #==========================================================================
     # REGISTRATIONS
     #==========================================================================
@@ -208,7 +268,7 @@
     def test_register_ok(self):
         username = 'test_regular4'
         password = 'qweqwe'
-        email = 'marcin@test.com'
+        email = 'username@test.com'
         name = 'testname'
         lastname = 'testlastname'
 
@@ -233,7 +293,7 @@
         self.assertEqual(ret.admin, False)
 
     def test_forgot_password_wrong_mail(self):
-        bad_email = 'marcin@wrongmail.org'
+        bad_email = 'username@wrongmail.org'
         response = self.app.post(
                         url(controller='login', action='password_reset'),
                             {'email': bad_email, }
@@ -250,7 +310,7 @@
 
         username = 'test_password_reset_1'
         password = 'qweqwe'
-        email = 'marcin@python-works.com'
+        email = 'username@python-works.com'
         name = 'passwd'
         lastname = 'reset'
 
@@ -319,7 +379,7 @@
                 self.app.get(url(controller='changeset',
                                  action='changeset_raw',
                                  repo_name=HG_REPO, revision='tip', api_key=api_key),
-                             status=302)
+                             status=403)
 
     @parameterized.expand([
         ('none', None, 302),
@@ -363,7 +423,7 @@
 
             new_api_key = ApiKeyModel().create(TEST_USER_ADMIN_LOGIN, u'test')
             Session().commit()
-            #patch the api key and make it expired
+            #patch the API key and make it expired
             new_api_key.expires = 0
             Session().add(new_api_key)
             Session().commit()
--- a/kallithea/tests/functional/test_my_account.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/functional/test_my_account.py	Tue Jun 09 22:46:40 2015 +0200
@@ -189,7 +189,7 @@
         user = User.get(usr['user_id'])
         response = self.app.get(url('my_account_api_keys'))
         response.mustcontain(user.api_key)
-        response.mustcontain('expires: never')
+        response.mustcontain('Expires: Never')
 
     @parameterized.expand([
         ('forever', -1),
@@ -201,7 +201,7 @@
         user = User.get(usr['user_id'])
         response = self.app.post(url('my_account_api_keys'),
                                  {'description': desc, 'lifetime': lifetime, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully created')
+        self.checkSessionFlash(response, 'API key successfully created')
         try:
             response = response.follow()
             user = User.get(usr['user_id'])
@@ -217,7 +217,7 @@
         user = User.get(usr['user_id'])
         response = self.app.post(url('my_account_api_keys'),
                                  {'description': 'desc', 'lifetime': -1, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully created')
+        self.checkSessionFlash(response, 'API key successfully created')
         response = response.follow()
 
         #now delete our key
@@ -226,7 +226,7 @@
 
         response = self.app.post(url('my_account_api_keys'),
                  {'_method': 'delete', 'del_api_key': keys[0].api_key, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully deleted')
+        self.checkSessionFlash(response, 'API key successfully deleted')
         keys = UserApiKeys.query().all()
         self.assertEqual(0, len(keys))
 
@@ -237,10 +237,10 @@
         api_key = user.api_key
         response = self.app.get(url('my_account_api_keys'))
         response.mustcontain(api_key)
-        response.mustcontain('expires: never')
+        response.mustcontain('Expires: Never')
 
         response = self.app.post(url('my_account_api_keys'),
                  {'_method': 'delete', 'del_api_key_builtin': api_key, '_authentication_token': self.authentication_token()})
-        self.checkSessionFlash(response, 'Api key successfully reset')
+        self.checkSessionFlash(response, 'API key successfully reset')
         response = response.follow()
         response.mustcontain(no=[api_key])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/tests/models/test_changeset_status.py	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,40 @@
+from kallithea.tests import *
+from kallithea.model.changeset_status import ChangesetStatusModel
+from kallithea.model.db import ChangesetStatus as CS
+
+class CSM(object): # ChangesetStatusMock
+
+    def __init__(self, status):
+        self.status = status
+
+class TestChangesetStatusCalculation(BaseTestCase):
+
+    def setUp(self):
+        self.m = ChangesetStatusModel()
+
+    @parameterized.expand([
+        ('empty list', CS.STATUS_UNDER_REVIEW, []),
+        ('approve', CS.STATUS_APPROVED, [CSM(CS.STATUS_APPROVED)]),
+        ('approve2', CS.STATUS_APPROVED, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_APPROVED)]),
+        ('approve_reject', CS.STATUS_REJECTED, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_REJECTED)]),
+        ('approve_underreview', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_UNDER_REVIEW)]),
+        ('approve_notreviewed', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_NOT_REVIEWED)]),
+        ('underreview', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_UNDER_REVIEW), CSM(CS.STATUS_UNDER_REVIEW)]),
+        ('reject', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED)]),
+        ('reject_underreview', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_UNDER_REVIEW)]),
+        ('reject_notreviewed', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_NOT_REVIEWED)]),
+        ('notreviewed', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_NOT_REVIEWED)]),
+        ('approve_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), None]),
+        ('approve2_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_APPROVED), None]),
+        ('approve_reject_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_REJECTED), None]),
+        ('approve_underreview_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_UNDER_REVIEW), None]),
+        ('approve_notreviewed_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_NOT_REVIEWED), None]),
+        ('underreview_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_UNDER_REVIEW), CSM(CS.STATUS_UNDER_REVIEW), None]),
+        ('reject_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), None]),
+        ('reject_underreview_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_UNDER_REVIEW), None]),
+        ('reject_notreviewed_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_NOT_REVIEWED), None]),
+        ('notreviewed_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_NOT_REVIEWED), None]),
+    ])
+    def test_result(self, name, expected_result, statuses):
+        result = self.m._calculate_status(statuses)
+        self.assertEqual(result, expected_result)
--- a/kallithea/tests/models/test_user_group_permissions_on_repo_groups.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/models/test_user_group_permissions_on_repo_groups.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,11 +1,9 @@
 import functools
-from kallithea.tests import *
 
 from kallithea.model.repo_group import RepoGroupModel
 from kallithea.model.db import RepoGroup
 
 from kallithea.model.meta import Session
-from nose.tools import with_setup
 from kallithea.tests.models.common import _create_project_tree, check_tree_perms, \
     _get_perms, _check_expected_count, expected_count, _destroy_project_tree
 from kallithea.model.user_group import UserGroupModel
@@ -26,6 +24,13 @@
     repo_group = RepoGroup.get_by_group_name(group_name=group_name)
     if not repo_group:
         raise Exception('Cannot get group %s' % group_name)
+
+    # Start with a baseline that current group can read recursive
+    perms_updates = [[test_u2_gr_id, 'group.read', 'users_group']]
+    RepoGroupModel()._update_permissions(repo_group,
+                                         perms_updates=perms_updates,
+                                         recursive='all', check_perms=False)
+
     perms_updates = [[test_u2_gr_id, perm, 'users_group']]
     RepoGroupModel()._update_permissions(repo_group,
                                          perms_updates=perms_updates,
@@ -53,9 +58,9 @@
 
 def teardown_module():
     _destroy_project_tree(test_u2_id)
+    fixture.destroy_user_group('perms_group_1')
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_without_recursive_mode():
     # set permission to g0 non-recursive mode
     recursive = 'none'
@@ -75,7 +80,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_without_recursive_mode_subgroup():
     # set permission to g0 non-recursive mode
     recursive = 'none'
@@ -95,7 +99,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode():
 
     # set permission to g0 recursive mode, all children including
@@ -115,7 +118,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode_inner_group():
     ## set permission to g0_3 group to none
     recursive = 'all'
@@ -133,7 +135,6 @@
         yield check_tree_perms, name, perm, group, 'group.none'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode_deepest():
     ## set permission to g0_3 group to none
     recursive = 'all'
@@ -151,7 +152,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode_only_with_repos():
     ## set permission to g0_3 group to none
     recursive = 'all'
@@ -168,7 +168,7 @@
     for name, perm in items:
         yield check_tree_perms, name, perm, group, 'group.admin'
 
-@with_setup(permissions_setup_func)
+
 def test_user_permissions_on_group_with_recursive_mode_on_repos():
     # set permission to g0/g0_1 with recursive mode on just repositories
     recursive = 'repos'
@@ -192,7 +192,7 @@
             old_perm = perm
         yield check_tree_perms, name, perm, group, old_perm
 
-@with_setup(permissions_setup_func)
+
 def test_user_permissions_on_group_with_recursive_mode_on_repo_groups():
     # set permission to g0/g0_1 with recursive mode on just repository groups
     recursive = 'groups'
--- a/kallithea/tests/models/test_user_groups.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/models/test_user_groups.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,6 +1,6 @@
 from kallithea.model.db import User
 
-from kallithea.tests import *
+from kallithea.tests import BaseTestCase, parameterized, TEST_USER_REGULAR_LOGIN
 from kallithea.tests.fixture import Fixture
 
 from kallithea.model.user_group import UserGroupModel
@@ -18,7 +18,6 @@
             fixture.destroy_user_group(gr)
         Session().commit()
 
-
     @parameterized.expand([
         ([], [], [], [], []),
         ([], ['regular'], [], [], ['regular']),  # no changes of regular
--- a/kallithea/tests/models/test_user_permissions_on_repo_groups.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/models/test_user_permissions_on_repo_groups.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,11 +1,9 @@
 import functools
-from kallithea.tests import *
 
 from kallithea.model.repo_group import RepoGroupModel
 from kallithea.model.db import RepoGroup, User
 
 from kallithea.model.meta import Session
-from nose.tools import with_setup
 from kallithea.tests.models.common import _create_project_tree, check_tree_perms, \
     _get_perms, _check_expected_count, expected_count, _destroy_project_tree
 
@@ -22,7 +20,6 @@
     """
     if not user_id:
         user_id = test_u1_id
-        # called by the @with_setup decorator also reset the default user stuff
         permissions_setup_func(group_name, perm, recursive,
                                user_id=User.get_default_user().user_id)
 
@@ -30,12 +27,19 @@
     if not repo_group:
         raise Exception('Cannot get group %s' % group_name)
 
+    # Start with a baseline that current group can read recursive
+    perms_updates = [[user_id, 'group.read', 'user']]
+    RepoGroupModel()._update_permissions(repo_group,
+                                         perms_updates=perms_updates,
+                                         recursive='all', check_perms=False)
+
     perms_updates = [[user_id, perm, 'user']]
     RepoGroupModel()._update_permissions(repo_group,
                                          perms_updates=perms_updates,
                                          recursive=recursive, check_perms=False)
     Session().commit()
 
+
 def setup_module():
     global test_u1_id, _get_repo_perms, _get_group_perms
     test_u1 = _create_project_tree()
@@ -51,7 +55,6 @@
     _destroy_project_tree(test_u1_id)
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_without_recursive_mode():
     # set permission to g0 non-recursive mode
     recursive = 'none'
@@ -71,7 +74,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_without_recursive_mode_subgroup():
     # set permission to g0 non-recursive mode
     recursive = 'none'
@@ -91,7 +93,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode():
 
     # set permission to g0 recursive mode, all children including
@@ -111,7 +112,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode_for_default_user():
 
     # set permission to g0 recursive mode, all children including
@@ -139,7 +139,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode_inner_group():
     ## set permission to g0_3 group to none
     recursive = 'all'
@@ -157,7 +156,6 @@
         yield check_tree_perms, name, perm, group, 'group.none'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode_deepest():
     ## set permission to g0_3 group to none
     recursive = 'all'
@@ -175,7 +173,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_mode_only_with_repos():
     ## set permission to g0_3 group to none
     recursive = 'all'
@@ -193,7 +190,6 @@
         yield check_tree_perms, name, perm, group, 'group.admin'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_repo_mode_for_default_user():
     # set permission to g0/g0_1 recursive repos only mode, all children including
     # other repos should have this permission now set, inner groups are excluded!
@@ -228,7 +224,6 @@
         yield check_tree_perms, name, perm, group, old_perm
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_repo_mode_inner_group():
     ## set permission to g0_3 group to none, with recursive repos only
     recursive = 'repos'
@@ -253,7 +248,6 @@
         yield check_tree_perms, name, perm, group, old_perm
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_group_mode_for_default_user():
     # set permission to g0/g0_1 with recursive groups only mode, all children including
     # other groups should have this permission now set. repositories should
@@ -281,7 +275,6 @@
         yield check_tree_perms, name, perm, group, 'group.write'
 
 
-@with_setup(permissions_setup_func)
 def test_user_permissions_on_group_with_recursive_group_mode_inner_group():
     ## set permission to g0_3 group to none, with recursive mode for groups only
     recursive = 'groups'
--- a/kallithea/tests/nose_parametrized.py	Tue Jun 09 22:12:21 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-import re
-import new
-import inspect
-import logging
-import logging.handlers
-from functools import wraps
-
-from nose.tools import nottest
-from unittest import TestCase
-
-
-def _terrible_magic_get_defining_classes():
-    """ Returns the set of parent classes of the class currently being defined.
-        Will likely only work if called from the ``parameterized`` decorator.
-        This function is entirely @brandon_rhodes's fault, as he suggested
-        the implementation: http://stackoverflow.com/a/8793684/71522
-        """
-    stack = inspect.stack()
-    if len(stack) <= 4:
-        return []
-    frame = stack[3]
-    code_context = frame[4][0].strip()
-    if not code_context.startswith("class "):
-        return []
-    _, parents = code_context.split("(", 1)
-    parents, _ = parents.rsplit(")", 1)
-    return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals)
-
-
-def parameterized(input):
-    """ Parameterize a test case:
-        >>> add1_tests = [(1, 2), (2, 3)]
-        >>> class TestFoo(object):
-        ...     @parameterized(add1_tests)
-        ...     def test_add1(self, input, expected):
-        ...         assert_equal(add1(input), expected)
-        >>> @parameterized(add1_tests)
-        ... def test_add1(input, expected):
-        ...     assert_equal(add1(input), expected)
-        >>>
-        """
-
-    if not hasattr(input, "__iter__"):
-        raise ValueError("expected iterable input; got %r" % (input,))
-
-    def parameterized_helper(f):
-        attached_instance_method = [False]
-
-        parent_classes = _terrible_magic_get_defining_classes()
-        if any(issubclass(cls, TestCase) for cls in parent_classes):
-            raise Exception("Warning: '@parameterized' tests won't work "
-                            "inside subclasses of 'TestCase' - use "
-                            "'@parameterized.expand' instead")
-
-        @wraps(f)
-        def parameterized_helper_method(self=None):
-            if self is not None and not attached_instance_method[0]:
-                # confusingly, we need to create a named instance method and
-                # attach that to the class...
-                cls = self.__class__
-                im_f = new.instancemethod(f, None, cls)
-                setattr(cls, f.__name__, im_f)
-                attached_instance_method[0] = True
-            for args in input:
-                if isinstance(args, basestring):
-                    args = [args]
-                # ... then pull that named instance method off, turning it into
-                # a bound method ...
-                if self is not None:
-                    args = [getattr(self, f.__name__)] + list(args)
-                else:
-                    args = [f] + list(args)
-                # ... then yield that as a tuple. If those steps aren't
-                # followed precicely, Nose gets upset and doesn't run the test
-                # or doesn't run setup methods.
-                yield tuple(args)
-
-        f.__name__ = "_helper_for_%s" % (f.__name__,)
-        parameterized_helper_method.parameterized_input = input
-        parameterized_helper_method.parameterized_func = f
-        return parameterized_helper_method
-
-    return parameterized_helper
-
-
-def to_safe_name(s):
-    return re.sub("[^a-zA-Z0-9_]", "", s)
-
-
-def parameterized_expand_helper(func_name, func, args):
-    def parameterized_expand_helper_helper(self=()):
-        if self != ():
-            self = (self,)
-        return func(*(self + args))
-    parameterized_expand_helper_helper.__name__ = str(func_name)
-    return parameterized_expand_helper_helper
-
-
-def parameterized_expand(input):
-    """ A "brute force" method of parameterizing test cases. Creates new test
-        cases and injects them into the namespace that the wrapped function
-        is being defined in. Useful for parameterizing tests in subclasses
-        of 'UnitTest', where Nose test generators don't work.
-
-        >>> @parameterized.expand([("foo", 1, 2)])
-        ... def test_add1(name, input, expected):
-        ...     actual = add1(input)
-        ...     assert_equal(actual, expected)
-        ...
-        >>> locals()
-        ... 'test_add1_foo_0': <function ...> ...
-        >>>
-        """
-
-    def parameterized_expand_wrapper(f):
-        stack = inspect.stack()
-        frame = stack[1]
-        frame_locals = frame[0].f_locals
-
-        base_name = f.__name__
-        for num, args in enumerate(input):
-            name_suffix = "_%s" % (num,)
-            if len(args) > 0 and isinstance(args[0], basestring):
-                name_suffix += "_" + to_safe_name(args[0])
-            name = base_name + name_suffix
-            new_func = parameterized_expand_helper(name, f, args)
-            frame_locals[name] = new_func
-        return nottest(f)
-    return parameterized_expand_wrapper
-
-parameterized.expand = parameterized_expand
-
-
-def assert_contains(haystack, needle):
-    if needle not in haystack:
-        raise AssertionError("%r not in %r" % (needle, haystack))
-
-
-def assert_not_contains(haystack, needle):
-    if needle in haystack:
-        raise AssertionError("%r in %r" % (needle, haystack))
-
-
-def imported_from_test():
-    """ Returns true if it looks like this module is being imported by unittest
-        or nose. """
-    import re
-    import inspect
-    nose_re = re.compile(r"\bnose\b")
-    unittest_re = re.compile(r"\bunittest2?\b")
-    for frame in inspect.stack():
-        file = frame[1]
-        if nose_re.search(file) or unittest_re.search(file):
-            return True
-    return False
-
-
-def assert_raises(func, exc_type, str_contains=None, repr_contains=None):
-    try:
-        func()
-    except exc_type, e:
-        if str_contains is not None and str_contains not in str(e):
-            raise AssertionError("%s raised, but %r does not contain %r"
-                                 % (exc_type, str(e), str_contains))
-        if repr_contains is not None and repr_contains not in repr(e):
-            raise AssertionError("%s raised, but %r does not contain %r"
-                                 % (exc_type, repr(e), repr_contains))
-        return e
-    else:
-        raise AssertionError("%s not raised" % (exc_type,))
-
-
-log_handler = None
-
-
-def setup_logging():
-    """ Configures a log handler which will capure log messages during a test.
-        The ``logged_messages`` and ``assert_no_errors_logged`` functions can be
-        used to make assertions about these logged messages.
-
-        For example::
-
-            from ensi_common.testing import (
-                setup_logging, teardown_logging, assert_no_errors_logged,
-                assert_logged,
-            )
-
-            class TestWidget(object):
-                def setup(self):
-                    setup_logging()
-
-                def teardown(self):
-                    assert_no_errors_logged()
-                    teardown_logging()
-
-                def test_that_will_fail(self):
-                    log.warning("this warning message will trigger a failure")
-
-                def test_that_will_pass(self):
-                    log.info("but info messages are ok")
-                    assert_logged("info messages are ok")
-        """
-
-    global log_handler
-    if log_handler is not None:
-        logging.getLogger().removeHandler(log_handler)
-    log_handler = logging.handlers.BufferingHandler(1000)
-    formatter = logging.Formatter("%(name)s: %(levelname)s: %(message)s")
-    log_handler.setFormatter(formatter)
-    logging.getLogger().addHandler(log_handler)
-
-
-def teardown_logging():
-    global log_handler
-    if log_handler is not None:
-        logging.getLogger().removeHandler(log_handler)
-        log_handler = None
-
-
-def logged_messages():
-    assert log_handler, "setup_logging not called"
-    return [(log_handler.format(record), record) for record in log_handler.buffer]
-
-
-def assert_no_errors_logged():
-    for _, record in logged_messages():
-        if record.levelno >= logging.WARNING:
-            # Assume that the nose log capture plugin is being used, so it will
-            # show the exception.
-            raise AssertionError("an unexpected error was logged")
-
-
-def assert_logged(expected_msg_contents):
-    for msg, _ in logged_messages():
-        if expected_msg_contents in msg:
-            return
-    raise AssertionError("no logged message contains %r"
-                         % (expected_msg_contents,))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/tests/other/manual_test_vcs_operations.py	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,536 @@
+# -*- coding: utf-8 -*-
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+kallithea.tests.test_scm_operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Test suite for making push/pull operations.
+
+Run it in two terminals::
+ paster serve test.ini
+ KALLITHEA_WHOOSH_TEST_DISABLE=1 KALLITHEA_NO_TMP_PATH=1 nosetests kallithea/tests/other/manual_test_vcs_operations.py
+
+You must have git > 1.8.1 for tests to work fine
+
+This file was forked by the Kallithea project in July 2014.
+Original author and date, and relevant copyright and licensing information is below:
+:created_on: Dec 30, 2010
+:author: marcink
+:copyright: (c) 2013 RhodeCode GmbH, and others.
+:license: GPLv3, see LICENSE.md for more details.
+
+"""
+
+import tempfile
+import time
+from os.path import join as jn
+
+from tempfile import _RandomNameSequence
+from subprocess import Popen, PIPE
+
+from kallithea.tests import *
+from kallithea.model.db import User, Repository, UserIpMap, CacheInvalidation
+from kallithea.model.meta import Session
+from kallithea.model.repo import RepoModel
+from kallithea.model.user import UserModel
+
+DEBUG = True
+HOST = '127.0.0.1:5000'  # test host
+
+
+class Command(object):
+
+    def __init__(self, cwd):
+        self.cwd = cwd
+
+    def execute(self, cmd, *args):
+        """
+        Runs command on the system with given ``args``.
+        """
+
+        command = cmd + ' ' + ' '.join(args)
+        if DEBUG:
+            print '*** CMD %s ***' % command
+        p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
+        stdout, stderr = p.communicate()
+        if DEBUG:
+            print 'stdout:', repr(stdout)
+            print 'stderr:', repr(stderr)
+        return stdout, stderr
+
+
+def _get_tmp_dir():
+    return tempfile.mkdtemp(prefix='rc_integration_test')
+
+
+def _construct_url(repo, dest=None, **kwargs):
+    if dest is None:
+        #make temp clone
+        dest = _get_tmp_dir()
+    params = {
+        'user': TEST_USER_ADMIN_LOGIN,
+        'passwd': TEST_USER_ADMIN_PASS,
+        'host': HOST,
+        'cloned_repo': repo,
+        'dest': dest
+    }
+    params.update(**kwargs)
+    if params['user'] and params['passwd']:
+        _url = 'http://%(user)s:%(passwd)s@%(host)s/%(cloned_repo)s %(dest)s' % params
+    else:
+        _url = 'http://(host)s/%(cloned_repo)s %(dest)s' % params
+    return _url
+
+
+def _add_files_and_push(vcs, DEST, **kwargs):
+    """
+    Generate some files, add it to DEST repo and push back
+    vcs is git or hg and defines what VCS we want to make those files for
+
+    :param vcs:
+    :param DEST:
+    """
+    # commit some stuff into this repo
+    cwd = path = jn(DEST)
+    #added_file = jn(path, '%ssetupążźć.py' % _RandomNameSequence().next())
+    added_file = jn(path, '%ssetup.py' % _RandomNameSequence().next())
+    Command(cwd).execute('touch %s' % added_file)
+    Command(cwd).execute('%s add %s' % (vcs, added_file))
+
+    for i in xrange(kwargs.get('files_no', 3)):
+        cmd = """echo 'added_line%s' >> %s""" % (i, added_file)
+        Command(cwd).execute(cmd)
+        author_str = 'User ǝɯɐᴎ <me@email.com>'
+        if vcs == 'hg':
+            cmd = """hg commit -m 'commited new %s' -u '%s' %s """ % (
+                i, author_str, added_file
+            )
+        elif vcs == 'git':
+            cmd = """EMAIL="me@email.com" git commit -m 'commited new %s' --author '%s' %s """ % (
+                i, author_str, added_file
+            )
+        Command(cwd).execute(cmd)
+
+    # PUSH it back
+    _REPO = None
+    if vcs == 'hg':
+        _REPO = HG_REPO
+    elif vcs == 'git':
+        _REPO = GIT_REPO
+
+    kwargs['dest'] = ''
+    clone_url = _construct_url(_REPO, **kwargs)
+    if 'clone_url' in kwargs:
+        clone_url = kwargs['clone_url']
+    stdout = stderr = None
+    if vcs == 'hg':
+        stdout, stderr = Command(cwd).execute('hg push --verbose', clone_url)
+    elif vcs == 'git':
+        stdout, stderr = Command(cwd).execute('git push --verbose', clone_url + " master")
+
+    return stdout, stderr
+
+
+def set_anonymous_access(enable=True):
+    user = User.get_by_username(User.DEFAULT_USER)
+    user.active = enable
+    Session().add(user)
+    Session().commit()
+    print '\tanonymous access is now:', enable
+    if enable != User.get_by_username(User.DEFAULT_USER).active:
+        raise Exception('Cannot set anonymous access')
+
+
+#==============================================================================
+# TESTS
+#==============================================================================
+
+
+def _check_proper_git_push(stdout, stderr):
+    #WTF Git stderr is output ?!
+    assert 'fatal' not in stderr
+    assert 'rejected' not in stderr
+    assert 'Pushing to' in stderr
+    assert 'master -> master' in stderr
+
+
+class TestVCSOperations(BaseTestCase):
+
+    @classmethod
+    def setup_class(cls):
+        #DISABLE ANONYMOUS ACCESS
+        set_anonymous_access(False)
+
+    def setUp(self):
+        r = Repository.get_by_repo_name(GIT_REPO)
+        Repository.unlock(r)
+        r.enable_locking = False
+        Session().add(r)
+        Session().commit()
+
+        r = Repository.get_by_repo_name(HG_REPO)
+        Repository.unlock(r)
+        r.enable_locking = False
+        Session().add(r)
+        Session().commit()
+
+    def test_clone_hg_repo_by_admin(self):
+        clone_url = _construct_url(HG_REPO)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        assert 'requesting all changes' in stdout
+        assert 'adding changesets' in stdout
+        assert 'adding manifests' in stdout
+        assert 'adding file changes' in stdout
+
+        assert stderr == ''
+
+    def test_clone_git_repo_by_admin(self):
+        clone_url = _construct_url(GIT_REPO)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        assert 'Cloning into' in stdout + stderr
+        assert stderr == '' or stdout == ''
+
+    def test_clone_wrong_credentials_hg(self):
+        clone_url = _construct_url(HG_REPO, passwd='bad!')
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+        assert 'abort: authorization failed' in stderr
+
+    def test_clone_wrong_credentials_git(self):
+        clone_url = _construct_url(GIT_REPO, passwd='bad!')
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+        assert 'fatal: Authentication failed' in stderr
+
+    def test_clone_git_dir_as_hg(self):
+        clone_url = _construct_url(GIT_REPO)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+        assert 'HTTP Error 404: Not Found' in stderr
+
+    def test_clone_hg_repo_as_git(self):
+        clone_url = _construct_url(HG_REPO)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+        assert 'not found' in stderr
+
+    def test_clone_non_existing_path_hg(self):
+        clone_url = _construct_url('trololo')
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+        assert 'HTTP Error 404: Not Found' in stderr
+
+    def test_clone_non_existing_path_git(self):
+        clone_url = _construct_url('trololo')
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+        assert 'not found' in stderr
+
+    def test_push_new_file_hg(self):
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(HG_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        stdout, stderr = _add_files_and_push('hg', DEST)
+
+        assert 'pushing to' in stdout
+        assert 'Repository size' in stdout
+        assert 'Last revision is now' in stdout
+
+    def test_push_new_file_git(self):
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(GIT_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        # commit some stuff into this repo
+        stdout, stderr = _add_files_and_push('git', DEST)
+
+        print [(x.repo_full_path,x.repo_path) for x in Repository.get_all()]
+        _check_proper_git_push(stdout, stderr)
+
+    def test_push_invalidates_cache_hg(self):
+        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
+                                               ==HG_REPO).scalar()
+        if not key:
+            key = CacheInvalidation(HG_REPO, HG_REPO)
+
+        key.cache_active = True
+        Session().add(key)
+        Session().commit()
+
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(HG_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        stdout, stderr = _add_files_and_push('hg', DEST, files_no=1)
+
+        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
+                                               ==HG_REPO).one()
+        self.assertEqual(key.cache_active, False)
+
+    def test_push_invalidates_cache_git(self):
+        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
+                                               ==GIT_REPO).scalar()
+        if not key:
+            key = CacheInvalidation(GIT_REPO, GIT_REPO)
+
+        key.cache_active = True
+        Session().add(key)
+        Session().commit()
+
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(GIT_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        # commit some stuff into this repo
+        stdout, stderr = _add_files_and_push('git', DEST, files_no=1)
+        _check_proper_git_push(stdout, stderr)
+
+        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
+                                               ==GIT_REPO).one()
+        print CacheInvalidation.get_all()
+        self.assertEqual(key.cache_active, False)
+
+    def test_push_wrong_credentials_hg(self):
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(HG_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        stdout, stderr = _add_files_and_push('hg', DEST, user='bad',
+                                             passwd='name')
+
+        assert 'abort: authorization failed' in stderr
+
+    def test_push_wrong_credentials_git(self):
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(GIT_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        stdout, stderr = _add_files_and_push('git', DEST, user='bad',
+                                             passwd='name')
+
+        assert 'fatal: Authentication failed' in stderr
+
+    def test_push_back_to_wrong_url_hg(self):
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(HG_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        stdout, stderr = _add_files_and_push('hg', DEST,
+                                    clone_url='http://127.0.0.1:5000/tmp',)
+
+        assert 'HTTP Error 404: Not Found' in stderr
+
+    def test_push_back_to_wrong_url_git(self):
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(GIT_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        stdout, stderr = _add_files_and_push('git', DEST,
+                                    clone_url='http://127.0.0.1:5000/tmp',)
+
+        assert 'not found' in stderr
+
+    def test_clone_and_create_lock_hg(self):
+        # enable locking
+        r = Repository.get_by_repo_name(HG_REPO)
+        r.enable_locking = True
+        Session().add(r)
+        Session().commit()
+        # clone
+        clone_url = _construct_url(HG_REPO)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        #check if lock was made
+        r = Repository.get_by_repo_name(HG_REPO)
+        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
+
+    def test_clone_and_create_lock_git(self):
+        # enable locking
+        r = Repository.get_by_repo_name(GIT_REPO)
+        r.enable_locking = True
+        Session().add(r)
+        Session().commit()
+        # clone
+        clone_url = _construct_url(GIT_REPO)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        #check if lock was made
+        r = Repository.get_by_repo_name(GIT_REPO)
+        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
+
+    def test_clone_after_repo_was_locked_hg(self):
+        #lock repo
+        r = Repository.get_by_repo_name(HG_REPO)
+        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
+        #pull fails since repo is locked
+        clone_url = _construct_url(HG_REPO)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
+                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
+        assert msg in stderr
+
+    def test_clone_after_repo_was_locked_git(self):
+        #lock repo
+        r = Repository.get_by_repo_name(GIT_REPO)
+        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
+        #pull fails since repo is locked
+        clone_url = _construct_url(GIT_REPO)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+        msg = ("""The requested URL returned error: 423""")
+        assert msg in stderr
+
+    def test_push_on_locked_repo_by_other_user_hg(self):
+        #clone some temp
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(HG_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        #lock repo
+        r = Repository.get_by_repo_name(HG_REPO)
+        # let this user actually push !
+        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
+                                          perm='repository.write')
+        Session().commit()
+        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
+
+        #push fails repo is locked by other user !
+        stdout, stderr = _add_files_and_push('hg', DEST,
+                                             user=TEST_USER_REGULAR_LOGIN,
+                                             passwd=TEST_USER_REGULAR_PASS)
+        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
+                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
+        assert msg in stderr
+
+    def test_push_on_locked_repo_by_other_user_git(self):
+        #clone some temp
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(GIT_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        #lock repo
+        r = Repository.get_by_repo_name(GIT_REPO)
+        # let this user actually push !
+        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
+                                          perm='repository.write')
+        Session().commit()
+        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
+
+        #push fails repo is locked by other user !
+        stdout, stderr = _add_files_and_push('git', DEST,
+                                             user=TEST_USER_REGULAR_LOGIN,
+                                             passwd=TEST_USER_REGULAR_PASS)
+        err = 'Repository `%s` locked by user `%s`' % (GIT_REPO, TEST_USER_ADMIN_LOGIN)
+        assert err in stderr
+
+        #TODO: fix this somehow later on Git, Git is stupid and even if we throw
+        #back 423 to it, it makes ANOTHER request and we fail there with 405 :/
+
+        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
+                % (GIT_REPO, TEST_USER_ADMIN_LOGIN))
+        #msg = "405 Method Not Allowed"
+        #assert msg in stderr
+
+    def test_push_unlocks_repository_hg(self):
+        # enable locking
+        r = Repository.get_by_repo_name(HG_REPO)
+        r.enable_locking = True
+        Session().add(r)
+        Session().commit()
+        #clone some temp
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(HG_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        #check for lock repo after clone
+        r = Repository.get_by_repo_name(HG_REPO)
+        uid = User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
+        assert r.locked[0] == uid
+
+        #push is ok and repo is now unlocked
+        stdout, stderr = _add_files_and_push('hg', DEST)
+        assert ('remote: Released lock on repo `%s`' % HG_REPO) in stdout
+        #we need to cleanup the Session Here !
+        Session.remove()
+        r = Repository.get_by_repo_name(HG_REPO)
+        assert r.locked == [None, None]
+
+    #TODO: fix me ! somehow during tests hooks don't get called on Git
+    def test_push_unlocks_repository_git(self):
+        # enable locking
+        r = Repository.get_by_repo_name(GIT_REPO)
+        r.enable_locking = True
+        Session().add(r)
+        Session().commit()
+        #clone some temp
+        DEST = _get_tmp_dir()
+        clone_url = _construct_url(GIT_REPO, dest=DEST)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        #check for lock repo after clone
+        r = Repository.get_by_repo_name(GIT_REPO)
+        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
+
+        #push is ok and repo is now unlocked
+        stdout, stderr = _add_files_and_push('git', DEST)
+        _check_proper_git_push(stdout, stderr)
+
+        #assert ('remote: Released lock on repo `%s`' % GIT_REPO) in stdout
+        #we need to cleanup the Session Here !
+        Session.remove()
+        r = Repository.get_by_repo_name(GIT_REPO)
+        assert r.locked == [None, None]
+
+    def test_ip_restriction_hg(self):
+        user_model = UserModel()
+        try:
+            user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
+            Session().commit()
+            clone_url = _construct_url(HG_REPO)
+            stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+            assert 'abort: HTTP Error 403: Forbidden' in stderr
+        finally:
+            #release IP restrictions
+            for ip in UserIpMap.getAll():
+                UserIpMap.delete(ip.ip_id)
+            Session().commit()
+
+        time.sleep(2)
+        clone_url = _construct_url(HG_REPO)
+        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
+
+        assert 'requesting all changes' in stdout
+        assert 'adding changesets' in stdout
+        assert 'adding manifests' in stdout
+        assert 'adding file changes' in stdout
+
+        assert stderr == ''
+
+    def test_ip_restriction_git(self):
+        user_model = UserModel()
+        try:
+            user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
+            Session().commit()
+            clone_url = _construct_url(GIT_REPO)
+            stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+            msg = ("""The requested URL returned error: 403""")
+            assert msg in stderr
+        finally:
+            #release IP restrictions
+            for ip in UserIpMap.getAll():
+                UserIpMap.delete(ip.ip_id)
+            Session().commit()
+
+        time.sleep(2)
+        clone_url = _construct_url(GIT_REPO)
+        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
+
+        assert 'Cloning into' in stdout + stderr
+        assert stderr == '' or stdout == ''
--- a/kallithea/tests/other/test_libs.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/other/test_libs.py	Tue Jun 09 22:46:40 2015 +0200
@@ -37,9 +37,9 @@
 TEST_URLS = [
     ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
      '%s://127.0.0.1' % proto),
-    ('%s://marcink@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
+    ('%s://username@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
      '%s://127.0.0.1' % proto),
-    ('%s://marcink:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
+    ('%s://username:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
      '%s://127.0.0.1' % proto),
     ('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
      '%s://127.0.0.1:8080' % proto),
@@ -54,9 +54,9 @@
 TEST_URLS += [
     ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
      '%s://127.0.0.1' % proto),
-    ('%s://marcink@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
+    ('%s://username@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
      '%s://127.0.0.1' % proto),
-    ('%s://marcink:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
+    ('%s://username:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
      '%s://127.0.0.1' % proto),
     ('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
      '%s://127.0.0.1:8080' % proto),
@@ -105,16 +105,16 @@
     def test_mention_extractor(self):
         from kallithea.lib.utils2 import extract_mentioned_users
         sample = (
-            "@first hi there @marcink here's my email marcin@email.com "
+            "@first hi there @world here's my email username@email.com "
             "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three "
-            "@MARCIN    @maRCiN @2one_more22 @john please see this http://org.pl "
+            "@UPPER    @cAmEL @2one_more22 @john please see this http://org.pl "
             "@marian.user just do it @marco-polo and next extract @marco_polo "
             "user.dot  hej ! not-needed maril@domain.org"
         )
 
         s = sorted([
-            '2one_more22', 'first', 'marcink', 'lukaszb', 'one', 'one_more22', 'MARCIN', 'maRCiN', 'john',
-            'marian.user', 'marco-polo', 'marco_polo'], key=lambda k: k.lower())
+            '2one_more22', 'first', 'lukaszb', 'one', 'one_more22', 'UPPER', 'cAmEL', 'john',
+            'marian.user', 'marco-polo', 'marco_polo', 'world'], key=lambda k: k.lower())
         self.assertEqual(s, extract_mentioned_users(sample))
 
     @parameterized.expand([
@@ -251,23 +251,23 @@
 
     @parameterized.expand([
         (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '', 'http://vps1:8000/group/repo1'),
-        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/group/repo1'),
-        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '/rc', 'http://vps1:8000/rc/group/repo1'),
-        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc', 'http://user@vps1:8000/rc/group/repo1'),
-        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc', 'http://marcink@vps1:8000/rc/group/repo1'),
-        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc/', 'http://user@vps1:8000/rc/group/repo1'),
-        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc/', 'http://marcink@vps1:8000/rc/group/repo1'),
+        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/group/repo1'),
+        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '/prefix', 'http://vps1:8000/prefix/group/repo1'),
+        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/prefix', 'http://user@vps1:8000/prefix/group/repo1'),
+        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '/prefix', 'http://username@vps1:8000/prefix/group/repo1'),
+        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/prefix/', 'http://user@vps1:8000/prefix/group/repo1'),
+        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '/prefix/', 'http://username@vps1:8000/prefix/group/repo1'),
         ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {}, '', 'http://vps1:8000/_23'),
-        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'),
-        ('http://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'),
-        ('http://{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://vps1:8000/_23'),
-        ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://marcink@proxy1.server.com/group/repo1'),
+        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/_23'),
+        ('http://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/_23'),
+        ('http://{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://vps1:8000/_23'),
+        ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {'user': 'username'}, '', 'https://username@proxy1.server.com/group/repo1'),
         ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {}, '', 'https://proxy1.server.com/group/repo1'),
-        ('https://proxy1.server.com/{user}/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://proxy1.server.com/marcink/group/repo1'),
+        ('https://proxy1.server.com/{user}/{repo}', 'group/repo1', {'user': 'username'}, '', 'https://proxy1.server.com/username/group/repo1'),
     ])
     def test_clone_url_generator(self, tmpl, repo_name, overrides, prefix, expected):
         from kallithea.lib.utils2 import get_clone_url
-        clone_url = get_clone_url(uri_tmpl=tmpl, qualifed_home_url='http://vps1:8000'+prefix,
+        clone_url = get_clone_url(uri_tmpl=tmpl, qualified_home_url='http://vps1:8000'+prefix,
                                   repo_name=repo_name, repo_id=23, **overrides)
         self.assertEqual(clone_url, expected)
 
@@ -366,7 +366,7 @@
       ("/_21/foobar", '21'),
       ("_21/121", '21'),
       ("/_21/_12", '21'),
-      ("_21/rc/foo", '21'),
+      ("_21/prefix/foo", '21'),
     ])
     def test_get_repo_by_id(self, test, expected):
         from kallithea.lib.utils import _extract_id_from_repo_name
--- a/kallithea/tests/other/test_vcs_operations.py	Tue Jun 09 22:12:21 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,533 +0,0 @@
-# -*- coding: utf-8 -*-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""
-kallithea.tests.test_scm_operations
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Test suite for making push/pull operations.
-Run using after doing paster serve test.ini::
- KALLITHEA_WHOOSH_TEST_DISABLE=1 KALLITHEA_NO_TMP_PATH=1 nosetests kallithea/tests/other/test_vcs_operations.py
-
-You must have git > 1.8.1 for tests to work fine
-
-This file was forked by the Kallithea project in July 2014.
-Original author and date, and relevant copyright and licensing information is below:
-:created_on: Dec 30, 2010
-:author: marcink
-:copyright: (c) 2013 RhodeCode GmbH, and others.
-:license: GPLv3, see LICENSE.md for more details.
-
-"""
-
-import tempfile
-import time
-from os.path import join as jn
-
-from tempfile import _RandomNameSequence
-from subprocess import Popen, PIPE
-
-from kallithea.tests import *
-from kallithea.model.db import User, Repository, UserIpMap, CacheInvalidation
-from kallithea.model.meta import Session
-from kallithea.model.repo import RepoModel
-from kallithea.model.user import UserModel
-
-DEBUG = True
-HOST = '127.0.0.1:5000'  # test host
-
-
-class Command(object):
-
-    def __init__(self, cwd):
-        self.cwd = cwd
-
-    def execute(self, cmd, *args):
-        """
-        Runs command on the system with given ``args``.
-        """
-
-        command = cmd + ' ' + ' '.join(args)
-        if DEBUG:
-            print '*** CMD %s ***' % command
-        p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
-        stdout, stderr = p.communicate()
-        if DEBUG:
-            print stdout, stderr
-        return stdout, stderr
-
-
-def _get_tmp_dir():
-    return tempfile.mkdtemp(prefix='rc_integration_test')
-
-
-def _construct_url(repo, dest=None, **kwargs):
-    if dest is None:
-        #make temp clone
-        dest = _get_tmp_dir()
-    params = {
-        'user': TEST_USER_ADMIN_LOGIN,
-        'passwd': TEST_USER_ADMIN_PASS,
-        'host': HOST,
-        'cloned_repo': repo,
-        'dest': dest
-    }
-    params.update(**kwargs)
-    if params['user'] and params['passwd']:
-        _url = 'http://%(user)s:%(passwd)s@%(host)s/%(cloned_repo)s %(dest)s' % params
-    else:
-        _url = 'http://(host)s/%(cloned_repo)s %(dest)s' % params
-    return _url
-
-
-def _add_files_and_push(vcs, DEST, **kwargs):
-    """
-    Generate some files, add it to DEST repo and push back
-    vcs is git or hg and defines what VCS we want to make those files for
-
-    :param vcs:
-    :param DEST:
-    """
-    # commit some stuff into this repo
-    cwd = path = jn(DEST)
-    #added_file = jn(path, '%ssetupążźć.py' % _RandomNameSequence().next())
-    added_file = jn(path, '%ssetup.py' % _RandomNameSequence().next())
-    Command(cwd).execute('touch %s' % added_file)
-    Command(cwd).execute('%s add %s' % (vcs, added_file))
-
-    for i in xrange(kwargs.get('files_no', 3)):
-        cmd = """echo 'added_line%s' >> %s""" % (i, added_file)
-        Command(cwd).execute(cmd)
-        author_str = 'Marcin Kuźminski <me@email.com>'
-        if vcs == 'hg':
-            cmd = """hg commit -m 'commited new %s' -u '%s' %s """ % (
-                i, author_str, added_file
-            )
-        elif vcs == 'git':
-            cmd = """EMAIL="me@email.com" git commit -m 'commited new %s' --author '%s' %s """ % (
-                i, author_str, added_file
-            )
-        Command(cwd).execute(cmd)
-
-    # PUSH it back
-    _REPO = None
-    if vcs == 'hg':
-        _REPO = HG_REPO
-    elif vcs == 'git':
-        _REPO = GIT_REPO
-
-    kwargs['dest'] = ''
-    clone_url = _construct_url(_REPO, **kwargs)
-    if 'clone_url' in kwargs:
-        clone_url = kwargs['clone_url']
-    stdout = stderr = None
-    if vcs == 'hg':
-        stdout, stderr = Command(cwd).execute('hg push --verbose', clone_url)
-    elif vcs == 'git':
-        stdout, stderr = Command(cwd).execute('git push --verbose', clone_url + " master")
-
-    return stdout, stderr
-
-
-def set_anonymous_access(enable=True):
-    user = User.get_by_username(User.DEFAULT_USER)
-    user.active = enable
-    Session().add(user)
-    Session().commit()
-    print '\tanonymous access is now:', enable
-    if enable != User.get_by_username(User.DEFAULT_USER).active:
-        raise Exception('Cannot set anonymous access')
-
-
-#==============================================================================
-# TESTS
-#==============================================================================
-
-
-def _check_proper_git_push(stdout, stderr):
-    #WTF Git stderr is output ?!
-    assert 'fatal' not in stderr
-    assert 'rejected' not in stderr
-    assert 'Pushing to' in stderr
-    assert 'master -> master' in stderr
-
-
-class TestVCSOperations(BaseTestCase):
-
-    @classmethod
-    def setup_class(cls):
-        #DISABLE ANONYMOUS ACCESS
-        set_anonymous_access(False)
-
-    def setUp(self):
-        r = Repository.get_by_repo_name(GIT_REPO)
-        Repository.unlock(r)
-        r.enable_locking = False
-        Session().add(r)
-        Session().commit()
-
-        r = Repository.get_by_repo_name(HG_REPO)
-        Repository.unlock(r)
-        r.enable_locking = False
-        Session().add(r)
-        Session().commit()
-
-    def test_clone_hg_repo_by_admin(self):
-        clone_url = _construct_url(HG_REPO)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        assert 'requesting all changes' in stdout
-        assert 'adding changesets' in stdout
-        assert 'adding manifests' in stdout
-        assert 'adding file changes' in stdout
-
-        assert stderr == ''
-
-    def test_clone_git_repo_by_admin(self):
-        clone_url = _construct_url(GIT_REPO)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        assert 'Cloning into' in stdout
-        assert stderr == ''
-
-    def test_clone_wrong_credentials_hg(self):
-        clone_url = _construct_url(HG_REPO, passwd='bad!')
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-        assert 'abort: authorization failed' in stderr
-
-    def test_clone_wrong_credentials_git(self):
-        clone_url = _construct_url(GIT_REPO, passwd='bad!')
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-        assert 'fatal: Authentication failed' in stderr
-
-    def test_clone_git_dir_as_hg(self):
-        clone_url = _construct_url(GIT_REPO)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-        assert 'HTTP Error 404: Not Found' in stderr
-
-    def test_clone_hg_repo_as_git(self):
-        clone_url = _construct_url(HG_REPO)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-        assert 'not found' in stderr
-
-    def test_clone_non_existing_path_hg(self):
-        clone_url = _construct_url('trololo')
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-        assert 'HTTP Error 404: Not Found' in stderr
-
-    def test_clone_non_existing_path_git(self):
-        clone_url = _construct_url('trololo')
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-        assert 'not found' in stderr
-
-    def test_push_new_file_hg(self):
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(HG_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        stdout, stderr = _add_files_and_push('hg', DEST)
-
-        assert 'pushing to' in stdout
-        assert 'Repository size' in stdout
-        assert 'Last revision is now' in stdout
-
-    def test_push_new_file_git(self):
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(GIT_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        # commit some stuff into this repo
-        stdout, stderr = _add_files_and_push('git', DEST)
-
-        print [(x.repo_full_path,x.repo_path) for x in Repository.get_all()]
-        _check_proper_git_push(stdout, stderr)
-
-    def test_push_invalidates_cache_hg(self):
-        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
-                                               ==HG_REPO).scalar()
-        if not key:
-            key = CacheInvalidation(HG_REPO, HG_REPO)
-
-        key.cache_active = True
-        Session().add(key)
-        Session().commit()
-
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(HG_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        stdout, stderr = _add_files_and_push('hg', DEST, files_no=1)
-
-        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
-                                               ==HG_REPO).one()
-        self.assertEqual(key.cache_active, False)
-
-    def test_push_invalidates_cache_git(self):
-        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
-                                               ==GIT_REPO).scalar()
-        if not key:
-            key = CacheInvalidation(GIT_REPO, GIT_REPO)
-
-        key.cache_active = True
-        Session().add(key)
-        Session().commit()
-
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(GIT_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        # commit some stuff into this repo
-        stdout, stderr = _add_files_and_push('git', DEST, files_no=1)
-        _check_proper_git_push(stdout, stderr)
-
-        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
-                                               ==GIT_REPO).one()
-        print CacheInvalidation.get_all()
-        self.assertEqual(key.cache_active, False)
-
-    def test_push_wrong_credentials_hg(self):
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(HG_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        stdout, stderr = _add_files_and_push('hg', DEST, user='bad',
-                                             passwd='name')
-
-        assert 'abort: authorization failed' in stderr
-
-    def test_push_wrong_credentials_git(self):
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(GIT_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        stdout, stderr = _add_files_and_push('git', DEST, user='bad',
-                                             passwd='name')
-
-        assert 'fatal: Authentication failed' in stderr
-
-    def test_push_back_to_wrong_url_hg(self):
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(HG_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        stdout, stderr = _add_files_and_push('hg', DEST,
-                                    clone_url='http://127.0.0.1:5000/tmp',)
-
-        assert 'HTTP Error 404: Not Found' in stderr
-
-    def test_push_back_to_wrong_url_git(self):
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(GIT_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        stdout, stderr = _add_files_and_push('git', DEST,
-                                    clone_url='http://127.0.0.1:5000/tmp',)
-
-        assert 'not found' in stderr
-
-    def test_clone_and_create_lock_hg(self):
-        # enable locking
-        r = Repository.get_by_repo_name(HG_REPO)
-        r.enable_locking = True
-        Session().add(r)
-        Session().commit()
-        # clone
-        clone_url = _construct_url(HG_REPO)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        #check if lock was made
-        r = Repository.get_by_repo_name(HG_REPO)
-        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-
-    def test_clone_and_create_lock_git(self):
-        # enable locking
-        r = Repository.get_by_repo_name(GIT_REPO)
-        r.enable_locking = True
-        Session().add(r)
-        Session().commit()
-        # clone
-        clone_url = _construct_url(GIT_REPO)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        #check if lock was made
-        r = Repository.get_by_repo_name(GIT_REPO)
-        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-
-    def test_clone_after_repo_was_locked_hg(self):
-        #lock repo
-        r = Repository.get_by_repo_name(HG_REPO)
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-        #pull fails since repo is locked
-        clone_url = _construct_url(HG_REPO)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
-                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
-        assert msg in stderr
-
-    def test_clone_after_repo_was_locked_git(self):
-        #lock repo
-        r = Repository.get_by_repo_name(GIT_REPO)
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-        #pull fails since repo is locked
-        clone_url = _construct_url(GIT_REPO)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-        msg = ("""The requested URL returned error: 423""")
-        assert msg in stderr
-
-    def test_push_on_locked_repo_by_other_user_hg(self):
-        #clone some temp
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(HG_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        #lock repo
-        r = Repository.get_by_repo_name(HG_REPO)
-        # let this user actually push !
-        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
-                                          perm='repository.write')
-        Session().commit()
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-
-        #push fails repo is locked by other user !
-        stdout, stderr = _add_files_and_push('hg', DEST,
-                                             user=TEST_USER_REGULAR_LOGIN,
-                                             passwd=TEST_USER_REGULAR_PASS)
-        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
-                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
-        assert msg in stderr
-
-    def test_push_on_locked_repo_by_other_user_git(self):
-        #clone some temp
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(GIT_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        #lock repo
-        r = Repository.get_by_repo_name(GIT_REPO)
-        # let this user actually push !
-        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
-                                          perm='repository.write')
-        Session().commit()
-        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
-
-        #push fails repo is locked by other user !
-        stdout, stderr = _add_files_and_push('git', DEST,
-                                             user=TEST_USER_REGULAR_LOGIN,
-                                             passwd=TEST_USER_REGULAR_PASS)
-        err = 'Repository `%s` locked by user `%s`' % (GIT_REPO, TEST_USER_ADMIN_LOGIN)
-        assert err in stderr
-
-        #TODO: fix this somehow later on Git, Git is stupid and even if we throw
-        #back 423 to it, it makes ANOTHER request and we fail there with 405 :/
-
-        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
-                % (GIT_REPO, TEST_USER_ADMIN_LOGIN))
-        #msg = "405 Method Not Allowed"
-        #assert msg in stderr
-
-    def test_push_unlocks_repository_hg(self):
-        # enable locking
-        r = Repository.get_by_repo_name(HG_REPO)
-        r.enable_locking = True
-        Session().add(r)
-        Session().commit()
-        #clone some temp
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(HG_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        #check for lock repo after clone
-        r = Repository.get_by_repo_name(HG_REPO)
-        uid = User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-        assert r.locked[0] == uid
-
-        #push is ok and repo is now unlocked
-        stdout, stderr = _add_files_and_push('hg', DEST)
-        assert ('remote: Released lock on repo `%s`' % HG_REPO) in stdout
-        #we need to cleanup the Session Here !
-        Session.remove()
-        r = Repository.get_by_repo_name(HG_REPO)
-        assert r.locked == [None, None]
-
-    #TODO: fix me ! somehow during tests hooks don't get called on Git
-    def test_push_unlocks_repository_git(self):
-        # enable locking
-        r = Repository.get_by_repo_name(GIT_REPO)
-        r.enable_locking = True
-        Session().add(r)
-        Session().commit()
-        #clone some temp
-        DEST = _get_tmp_dir()
-        clone_url = _construct_url(GIT_REPO, dest=DEST)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        #check for lock repo after clone
-        r = Repository.get_by_repo_name(GIT_REPO)
-        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
-
-        #push is ok and repo is now unlocked
-        stdout, stderr = _add_files_and_push('git', DEST)
-        _check_proper_git_push(stdout, stderr)
-
-        #assert ('remote: Released lock on repo `%s`' % GIT_REPO) in stdout
-        #we need to cleanup the Session Here !
-        Session.remove()
-        r = Repository.get_by_repo_name(GIT_REPO)
-        assert r.locked == [None, None]
-
-    def test_ip_restriction_hg(self):
-        user_model = UserModel()
-        try:
-            user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
-            Session().commit()
-            clone_url = _construct_url(HG_REPO)
-            stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-            assert 'abort: HTTP Error 403: Forbidden' in stderr
-        finally:
-            #release IP restrictions
-            for ip in UserIpMap.getAll():
-                UserIpMap.delete(ip.ip_id)
-            Session().commit()
-
-        time.sleep(2)
-        clone_url = _construct_url(HG_REPO)
-        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
-
-        assert 'requesting all changes' in stdout
-        assert 'adding changesets' in stdout
-        assert 'adding manifests' in stdout
-        assert 'adding file changes' in stdout
-
-        assert stderr == ''
-
-    def test_ip_restriction_git(self):
-        user_model = UserModel()
-        try:
-            user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
-            Session().commit()
-            clone_url = _construct_url(GIT_REPO)
-            stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-            msg = ("""The requested URL returned error: 403""")
-            assert msg in stderr
-        finally:
-            #release IP restrictions
-            for ip in UserIpMap.getAll():
-                UserIpMap.delete(ip.ip_id)
-            Session().commit()
-
-        time.sleep(2)
-        clone_url = _construct_url(GIT_REPO)
-        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
-
-        assert 'Cloning into' in stdout
-        assert stderr == ''
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/tests/parameterized.py	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,241 @@
+import re
+import new
+import inspect
+import logging
+import logging.handlers
+from functools import wraps
+
+from unittest import TestCase
+
+
+def skip_test(func):
+    try:
+        from nose.tools import nottest
+    except ImportError:
+        pass
+    else:
+        func = nottest(func)
+
+    try:
+        import pytest
+    except ImportError:
+        pass
+    else:
+        func = pytest.mark.skipIf(True, func)
+
+    return func
+
+
+def _terrible_magic_get_defining_classes():
+    """ Returns the set of parent classes of the class currently being defined.
+        Will likely only work if called from the ``parameterized`` decorator.
+        This function is entirely @brandon_rhodes's fault, as he suggested
+        the implementation: http://stackoverflow.com/a/8793684/71522
+        """
+    stack = inspect.stack()
+    if len(stack) <= 4:
+        return []
+    frame = stack[3]
+    code_context = frame[4][0].strip()
+    if not code_context.startswith("class "):
+        return []
+    _, parents = code_context.split("(", 1)
+    parents, _ = parents.rsplit(")", 1)
+    return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals)
+
+
+def parameterized(input):
+    """ Parameterize a test case:
+        >>> add1_tests = [(1, 2), (2, 3)]
+        >>> class TestFoo(object):
+        ...     @parameterized(add1_tests)
+        ...     def test_add1(self, input, expected):
+        ...         assert_equal(add1(input), expected)
+        >>> @parameterized(add1_tests)
+        ... def test_add1(input, expected):
+        ...     assert_equal(add1(input), expected)
+        >>>
+        """
+
+    if not hasattr(input, "__iter__"):
+        raise ValueError("expected iterable input; got %r" % (input,))
+
+    def parameterized_helper(f):
+        attached_instance_method = [False]
+
+        parent_classes = _terrible_magic_get_defining_classes()
+        if any(issubclass(cls, TestCase) for cls in parent_classes):
+            raise Exception("Warning: '@parameterized' tests won't work "
+                            "inside subclasses of 'TestCase' - use "
+                            "'@parameterized.expand' instead")
+
+        @wraps(f)
+        def parameterized_helper_method(self=None):
+            if self is not None and not attached_instance_method[0]:
+                # confusingly, we need to create a named instance method and
+                # attach that to the class...
+                cls = self.__class__
+                im_f = new.instancemethod(f, None, cls)
+                setattr(cls, f.__name__, im_f)
+                attached_instance_method[0] = True
+            for args in input:
+                if isinstance(args, basestring):
+                    args = [args]
+                # ... then pull that named instance method off, turning it into
+                # a bound method ...
+                if self is not None:
+                    args = [getattr(self, f.__name__)] + list(args)
+                else:
+                    args = [f] + list(args)
+                # ... then yield that as a tuple. If those steps aren't
+                # followed precicely, Nose gets upset and doesn't run the test
+                # or doesn't run setup methods.
+                yield tuple(args)
+
+        f.__name__ = "_helper_for_%s" % (f.__name__,)
+        parameterized_helper_method.parameterized_input = input
+        parameterized_helper_method.parameterized_func = f
+        return parameterized_helper_method
+
+    return parameterized_helper
+
+
+def to_safe_name(s):
+    return re.sub("[^a-zA-Z0-9_]", "", s)
+
+
+def parameterized_expand_helper(func_name, func, args):
+    def parameterized_expand_helper_helper(self=()):
+        if self != ():
+            self = (self,)
+        return func(*(self + args))
+    parameterized_expand_helper_helper.__name__ = str(func_name)
+    return parameterized_expand_helper_helper
+
+
+def parameterized_expand(input):
+    """ A "brute force" method of parameterizing test cases. Creates new test
+        cases and injects them into the namespace that the wrapped function
+        is being defined in. Useful for parameterizing tests in subclasses
+        of 'UnitTest', where Nose test generators don't work.
+
+        >>> @parameterized.expand([("foo", 1, 2)])
+        ... def test_add1(name, input, expected):
+        ...     actual = add1(input)
+        ...     assert_equal(actual, expected)
+        ...
+        >>> locals()
+        ... 'test_add1_foo_0': <function ...> ...
+        >>>
+        """
+
+    def parameterized_expand_wrapper(f):
+        stack = inspect.stack()
+        frame = stack[1]
+        frame_locals = frame[0].f_locals
+
+        base_name = f.__name__
+        for num, args in enumerate(input):
+            name_suffix = "_%s" % (num,)
+            if len(args) > 0 and isinstance(args[0], basestring):
+                name_suffix += "_" + to_safe_name(args[0])
+            name = base_name + name_suffix
+            new_func = parameterized_expand_helper(name, f, args)
+            frame_locals[name] = new_func
+        return skip_test(f)
+    return parameterized_expand_wrapper
+
+parameterized.expand = parameterized_expand
+
+
+def assert_contains(haystack, needle):
+    if needle not in haystack:
+        raise AssertionError("%r not in %r" % (needle, haystack))
+
+
+def assert_not_contains(haystack, needle):
+    if needle in haystack:
+        raise AssertionError("%r in %r" % (needle, haystack))
+
+
+def assert_raises(func, exc_type, str_contains=None, repr_contains=None):
+    try:
+        func()
+    except exc_type, e:
+        if str_contains is not None and str_contains not in str(e):
+            raise AssertionError("%s raised, but %r does not contain %r"
+                                 % (exc_type, str(e), str_contains))
+        if repr_contains is not None and repr_contains not in repr(e):
+            raise AssertionError("%s raised, but %r does not contain %r"
+                                 % (exc_type, repr(e), repr_contains))
+        return e
+    else:
+        raise AssertionError("%s not raised" % (exc_type,))
+
+
+log_handler = None
+
+
+def setup_logging():
+    """ Configures a log handler which will capure log messages during a test.
+        The ``logged_messages`` and ``assert_no_errors_logged`` functions can be
+        used to make assertions about these logged messages.
+
+        For example::
+
+            from ensi_common.testing import (
+                setup_logging, teardown_logging, assert_no_errors_logged,
+                assert_logged,
+            )
+
+            class TestWidget(object):
+                def setup(self):
+                    setup_logging()
+
+                def teardown(self):
+                    assert_no_errors_logged()
+                    teardown_logging()
+
+                def test_that_will_fail(self):
+                    log.warning("this warning message will trigger a failure")
+
+                def test_that_will_pass(self):
+                    log.info("but info messages are ok")
+                    assert_logged("info messages are ok")
+        """
+
+    global log_handler
+    if log_handler is not None:
+        logging.getLogger().removeHandler(log_handler)
+    log_handler = logging.handlers.BufferingHandler(1000)
+    formatter = logging.Formatter("%(name)s: %(levelname)s: %(message)s")
+    log_handler.setFormatter(formatter)
+    logging.getLogger().addHandler(log_handler)
+
+
+def teardown_logging():
+    global log_handler
+    if log_handler is not None:
+        logging.getLogger().removeHandler(log_handler)
+        log_handler = None
+
+
+def logged_messages():
+    assert log_handler, "setup_logging not called"
+    return [(log_handler.format(record), record) for record in log_handler.buffer]
+
+
+def assert_no_errors_logged():
+    for _, record in logged_messages():
+        if record.levelno >= logging.WARNING:
+            # Assume that the nose log capture plugin is being used, so it will
+            # show the exception.
+            raise AssertionError("an unexpected error was logged")
+
+
+def assert_logged(expected_msg_contents):
+    for msg, _ in logged_messages():
+        if expected_msg_contents in msg:
+            return
+    raise AssertionError("no logged message contains %r"
+                         % (expected_msg_contents,))
--- a/kallithea/tests/scripts/create_rc.sh	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/scripts/create_rc.sh	Tue Jun 09 22:46:40 2015 +0200
@@ -1,10 +1,10 @@
 #!/bin/sh
 psql -U postgres -h localhost -c 'drop database if exists kallithea;'
 psql -U postgres -h localhost -c 'create database kallithea;'
-paster setup-db rc.ini --force-yes --user=username --password=qweqwe --email=username@example.com --repos=/home/username/repos --no-public-access
+paster setup-db server.ini --force-yes --user=username --password=qweqwe --email=username@example.com --repos=/home/username/repos --no-public-access
 API_KEY=`psql -R " " -A -U postgres -h localhost -c "select api_key from users where admin=TRUE" -d kallithea | awk '{print $2}'`
 echo "run those after running server"
-paster serve rc.ini --pid-file=rc.pid --daemon
+paster serve server.ini --pid-file=server.pid --daemon
 sleep 3
 kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 create_user username:demo1 password:qweqwe email:demo1@example.com
 kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 create_user username:demo2 password:qweqwe email:demo2@example.com
@@ -13,5 +13,5 @@
 kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 add_user_to_user_group usergroupid:demo12 userid:demo1
 kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 add_user_to_user_group usergroupid:demo12 userid:demo2
 echo "killing server"
-kill `cat rc.pid`
-rm rc.pid
+kill `cat server.pid`
+rm server.pid
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/tests/scripts/manual_test_concurrency.py	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,222 @@
+# -*- coding: utf-8 -*-
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+kallithea.tests.test_hg_operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Test suite for making push/pull operations
+
+This file was forked by the Kallithea project in July 2014.
+Original author and date, and relevant copyright and licensing information is below:
+:created_on: Dec 30, 2010
+:author: marcink
+:copyright: (c) 2013 RhodeCode GmbH, and others.
+:license: GPLv3, see LICENSE.md for more details.
+
+"""
+
+import os
+import sys
+import shutil
+import logging
+from os.path import join as jn
+from os.path import dirname as dn
+
+from tempfile import _RandomNameSequence
+from subprocess import Popen, PIPE
+
+from paste.deploy import appconfig
+from sqlalchemy import engine_from_config
+
+from kallithea.lib.utils import add_cache
+from kallithea.model import init_model
+from kallithea.model import meta
+from kallithea.model.db import User, Repository
+from kallithea.lib.auth import get_crypt_password
+
+from kallithea.tests import TESTS_TMP_PATH, HG_REPO
+from kallithea.config.environment import load_environment
+
+rel_path = dn(dn(dn(dn(os.path.abspath(__file__)))))
+conf = appconfig('config:development.ini', relative_to=rel_path)
+load_environment(conf.global_conf, conf.local_conf)
+
+add_cache(conf)
+
+USER = 'test_admin'
+PASS = 'test12'
+HOST = 'server.local'
+METHOD = 'pull'
+DEBUG = True
+log = logging.getLogger(__name__)
+
+
+class Command(object):
+
+    def __init__(self, cwd):
+        self.cwd = cwd
+
+    def execute(self, cmd, *args):
+        """Runs command on the system with given ``args``.
+        """
+
+        command = cmd + ' ' + ' '.join(args)
+        log.debug('Executing %s' % command)
+        if DEBUG:
+            print command
+        p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
+        stdout, stderr = p.communicate()
+        if DEBUG:
+            print stdout, stderr
+        return stdout, stderr
+
+
+def get_session():
+    engine = engine_from_config(conf, 'sqlalchemy.db1.')
+    init_model(engine)
+    sa = meta.Session
+    return sa
+
+
+def create_test_user(force=True):
+    print 'creating test user'
+    sa = get_session()
+
+    user = sa.query(User).filter(User.username == USER).scalar()
+
+    if force and user is not None:
+        print 'removing current user'
+        for repo in sa.query(Repository).filter(Repository.user == user).all():
+            sa.delete(repo)
+        sa.delete(user)
+        sa.commit()
+
+    if user is None or force:
+        print 'creating new one'
+        new_usr = User()
+        new_usr.username = USER
+        new_usr.password = get_crypt_password(PASS)
+        new_usr.email = 'mail@mail.com'
+        new_usr.name = 'test'
+        new_usr.lastname = 'lasttestname'
+        new_usr.active = True
+        new_usr.admin = True
+        sa.add(new_usr)
+        sa.commit()
+
+    print 'done'
+
+
+def create_test_repo(force=True):
+    print 'creating test repo'
+    from kallithea.model.repo import RepoModel
+    sa = get_session()
+
+    user = sa.query(User).filter(User.username == USER).scalar()
+    if user is None:
+        raise Exception('user not found')
+
+    repo = sa.query(Repository).filter(Repository.repo_name == HG_REPO).scalar()
+
+    if repo is None:
+        print 'repo not found creating'
+
+        form_data = {'repo_name': HG_REPO,
+                     'repo_type': 'hg',
+                     'private':False,
+                     'clone_uri': '' }
+        rm = RepoModel(sa)
+        rm.base_path = '/home/hg'
+        rm.create(form_data, user)
+
+    print 'done'
+
+
+def set_anonymous_access(enable=True):
+    sa = get_session()
+    user = sa.query(User).filter(User.username == 'default').one()
+    user.active = enable
+    sa.add(user)
+    sa.commit()
+
+
+def get_anonymous_access():
+    sa = get_session()
+    return sa.query(User).filter(User.username == 'default').one().active
+
+
+#==============================================================================
+# TESTS
+#==============================================================================
+def test_clone_with_credentials(no_errors=False, repo=HG_REPO, method=METHOD,
+                                seq=None, backend='hg'):
+    cwd = path = jn(TESTS_TMP_PATH, repo)
+
+    if seq is None:
+        seq = _RandomNameSequence().next()
+
+    try:
+        shutil.rmtree(path, ignore_errors=True)
+        os.makedirs(path)
+        #print 'made dirs %s' % jn(path)
+    except OSError:
+        raise
+
+    clone_url = 'http://%(user)s:%(pass)s@%(host)s/%(cloned_repo)s' % \
+                  {'user': USER,
+                   'pass': PASS,
+                   'host': HOST,
+                   'cloned_repo': repo, }
+
+    dest = path + seq
+    if method == 'pull':
+        stdout, stderr = Command(cwd).execute(backend, method, '--cwd', dest, clone_url)
+    else:
+        stdout, stderr = Command(cwd).execute(backend, method, clone_url, dest)
+        print stdout,'sdasdsadsa'
+        if not no_errors:
+            if backend == 'hg':
+                assert """adding file changes""" in stdout, 'no messages about cloning'
+                assert """abort""" not in stderr , 'got error from clone'
+            elif backend == 'git':
+                assert """Cloning into""" in stdout, 'no messages about cloning'
+
+if __name__ == '__main__':
+    try:
+        create_test_user(force=False)
+        seq = None
+        import time
+
+        try:
+            METHOD = sys.argv[3]
+        except IndexError:
+            pass
+
+        try:
+            backend = sys.argv[4]
+        except IndexError:
+            backend = 'hg'
+
+        if METHOD == 'pull':
+            seq = _RandomNameSequence().next()
+            test_clone_with_credentials(repo=sys.argv[1], method='clone',
+                                        seq=seq, backend=backend)
+        s = time.time()
+        for i in range(1, int(sys.argv[2]) + 1):
+            print 'take', i
+            test_clone_with_credentials(repo=sys.argv[1], method=METHOD,
+                                        seq=seq, backend=backend)
+        print 'time taken %.3f' % (time.time() - s)
+    except Exception, e:
+        sys.exit('stop on %s' % e)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kallithea/tests/scripts/manual_test_crawler.py	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,189 @@
+# -*- coding: utf-8 -*-
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+kallithea.tests.test_crawer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Test for crawling a project for memory usage
+This should be runned just as regular script together
+with a watch script that will show memory usage.
+
+watch -n1 ./kallithea/tests/mem_watch
+
+This file was forked by the Kallithea project in July 2014.
+Original author and date, and relevant copyright and licensing information is below:
+:created_on: Apr 21, 2010
+:author: marcink
+:copyright: (c) 2013 RhodeCode GmbH, and others.
+:license: GPLv3, see LICENSE.md for more details.
+"""
+
+
+import cookielib
+import urllib
+import urllib2
+import time
+import os
+import sys
+from os.path import join as jn
+from os.path import dirname as dn
+
+__here__ = os.path.abspath(__file__)
+__root__ = dn(dn(dn(__here__)))
+sys.path.append(__root__)
+
+from kallithea.lib import vcs
+from kallithea.lib.compat import OrderedSet
+from kallithea.lib.vcs.exceptions import RepositoryError
+
+PASES = 3
+HOST = 'http://127.0.0.1'
+PORT = 5000
+BASE_URI = '%s:%s/' % (HOST, PORT)
+
+if len(sys.argv) == 2:
+    BASE_URI = sys.argv[1]
+
+if not BASE_URI.endswith('/'):
+    BASE_URI += '/'
+
+print 'Crawling @ %s' % BASE_URI
+BASE_URI += '%s'
+PROJECT_PATH = jn('/', 'home', 'username', 'repos')
+PROJECTS = [
+    #'linux-magx-pbranch',
+    'CPython',
+    'kallithea',
+]
+
+
+cj = cookielib.FileCookieJar('/tmp/rc_test_cookie.txt')
+o = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+o.addheaders = [
+    ('User-agent', 'kallithea-crawler'),
+    ('Accept-Language', 'en - us, en;q = 0.5')
+]
+
+urllib2.install_opener(o)
+
+
+def _get_repo(proj):
+    if isinstance(proj, basestring):
+        repo = vcs.get_repo(jn(PROJECT_PATH, proj))
+        proj = proj
+    else:
+        repo = proj
+        proj = repo.name
+
+    return repo, proj
+
+
+def test_changelog_walk(proj, pages=100):
+    repo, proj = _get_repo(proj)
+
+    total_time = 0
+    for i in range(1, pages):
+
+        page = '/'.join((proj, 'changelog',))
+
+        full_uri = (BASE_URI % page) + '?' + urllib.urlencode({'page': i})
+        s = time.time()
+        f = o.open(full_uri)
+
+        assert f.url == full_uri, 'URL:%s does not match %s' % (f.url, full_uri)
+
+        size = len(f.read())
+        e = time.time() - s
+        total_time += e
+        print 'visited %s size:%s req:%s ms' % (full_uri, size, e)
+
+    print 'total_time', total_time
+    print 'average on req', total_time / float(pages)
+
+
+def test_changeset_walk(proj, limit=None):
+    repo, proj = _get_repo(proj)
+
+    print 'processing', jn(PROJECT_PATH, proj)
+    total_time = 0
+
+    cnt = 0
+    for i in repo:
+        cnt += 1
+        raw_cs = '/'.join((proj, 'changeset', i.raw_id))
+        if limit and limit == cnt:
+            break
+
+        full_uri = (BASE_URI % raw_cs)
+        print '%s visiting %s\%s' % (cnt, full_uri, i)
+        s = time.time()
+        f = o.open(full_uri)
+        size = len(f.read())
+        e = time.time() - s
+        total_time += e
+        print '%s visited %s\%s size:%s req:%s ms' % (cnt, full_uri, i, size, e)
+
+    print 'total_time', total_time
+    print 'average on req', total_time / float(cnt)
+
+
+def test_files_walk(proj, limit=100):
+    repo, proj = _get_repo(proj)
+
+    print 'processing', jn(PROJECT_PATH, proj)
+    total_time = 0
+
+    paths_ = OrderedSet([''])
+    try:
+        tip = repo.get_changeset('tip')
+        for topnode, dirs, files in tip.walk('/'):
+
+            for dir in dirs:
+                paths_.add(dir.path)
+                for f in dir:
+                    paths_.add(f.path)
+
+            for f in files:
+                paths_.add(f.path)
+
+    except RepositoryError, e:
+        pass
+
+    cnt = 0
+    for f in paths_:
+        cnt += 1
+        if limit and limit == cnt:
+            break
+
+        file_path = '/'.join((proj, 'files', 'tip', f))
+        full_uri = (BASE_URI % file_path)
+        print '%s visiting %s' % (cnt, full_uri)
+        s = time.time()
+        f = o.open(full_uri)
+        size = len(f.read())
+        e = time.time() - s
+        total_time += e
+        print '%s visited OK size:%s req:%s ms' % (cnt, size, e)
+
+    print 'total_time', total_time
+    print 'average on req', total_time / float(cnt)
+
+if __name__ == '__main__':
+    for path in PROJECTS:
+        repo = vcs.get_repo(jn(PROJECT_PATH, path))
+        for i in range(PASES):
+            print 'PASS %s/%s' % (i, PASES)
+            test_changelog_walk(repo, pages=80)
+            test_changeset_walk(repo, limit=100)
+            test_files_walk(repo, limit=100)
--- a/kallithea/tests/scripts/test_concurency.py	Tue Jun 09 22:12:21 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-# -*- coding: utf-8 -*-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""
-kallithea.tests.test_hg_operations
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Test suite for making push/pull operations
-
-This file was forked by the Kallithea project in July 2014.
-Original author and date, and relevant copyright and licensing information is below:
-:created_on: Dec 30, 2010
-:author: marcink
-:copyright: (c) 2013 RhodeCode GmbH, and others.
-:license: GPLv3, see LICENSE.md for more details.
-
-"""
-
-import os
-import sys
-import shutil
-import logging
-from os.path import join as jn
-from os.path import dirname as dn
-
-from tempfile import _RandomNameSequence
-from subprocess import Popen, PIPE
-
-from paste.deploy import appconfig
-from sqlalchemy import engine_from_config
-
-from kallithea.lib.utils import add_cache
-from kallithea.model import init_model
-from kallithea.model import meta
-from kallithea.model.db import User, Repository
-from kallithea.lib.auth import get_crypt_password
-
-from kallithea.tests import TESTS_TMP_PATH, HG_REPO
-from kallithea.config.environment import load_environment
-
-rel_path = dn(dn(dn(dn(os.path.abspath(__file__)))))
-conf = appconfig('config:rc.ini', relative_to=rel_path)
-load_environment(conf.global_conf, conf.local_conf)
-
-add_cache(conf)
-
-USER = 'test_admin'
-PASS = 'test12'
-HOST = 'rc.local'
-METHOD = 'pull'
-DEBUG = True
-log = logging.getLogger(__name__)
-
-
-class Command(object):
-
-    def __init__(self, cwd):
-        self.cwd = cwd
-
-    def execute(self, cmd, *args):
-        """Runs command on the system with given ``args``.
-        """
-
-        command = cmd + ' ' + ' '.join(args)
-        log.debug('Executing %s' % command)
-        if DEBUG:
-            print command
-        p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
-        stdout, stderr = p.communicate()
-        if DEBUG:
-            print stdout, stderr
-        return stdout, stderr
-
-
-def get_session():
-    engine = engine_from_config(conf, 'sqlalchemy.db1.')
-    init_model(engine)
-    sa = meta.Session
-    return sa
-
-
-def create_test_user(force=True):
-    print 'creating test user'
-    sa = get_session()
-
-    user = sa.query(User).filter(User.username == USER).scalar()
-
-    if force and user is not None:
-        print 'removing current user'
-        for repo in sa.query(Repository).filter(Repository.user == user).all():
-            sa.delete(repo)
-        sa.delete(user)
-        sa.commit()
-
-    if user is None or force:
-        print 'creating new one'
-        new_usr = User()
-        new_usr.username = USER
-        new_usr.password = get_crypt_password(PASS)
-        new_usr.email = 'mail@mail.com'
-        new_usr.name = 'test'
-        new_usr.lastname = 'lasttestname'
-        new_usr.active = True
-        new_usr.admin = True
-        sa.add(new_usr)
-        sa.commit()
-
-    print 'done'
-
-
-def create_test_repo(force=True):
-    print 'creating test repo'
-    from kallithea.model.repo import RepoModel
-    sa = get_session()
-
-    user = sa.query(User).filter(User.username == USER).scalar()
-    if user is None:
-        raise Exception('user not found')
-
-    repo = sa.query(Repository).filter(Repository.repo_name == HG_REPO).scalar()
-
-    if repo is None:
-        print 'repo not found creating'
-
-        form_data = {'repo_name': HG_REPO,
-                     'repo_type': 'hg',
-                     'private':False,
-                     'clone_uri': '' }
-        rm = RepoModel(sa)
-        rm.base_path = '/home/hg'
-        rm.create(form_data, user)
-
-    print 'done'
-
-
-def set_anonymous_access(enable=True):
-    sa = get_session()
-    user = sa.query(User).filter(User.username == 'default').one()
-    user.active = enable
-    sa.add(user)
-    sa.commit()
-
-
-def get_anonymous_access():
-    sa = get_session()
-    return sa.query(User).filter(User.username == 'default').one().active
-
-
-#==============================================================================
-# TESTS
-#==============================================================================
-def test_clone_with_credentials(no_errors=False, repo=HG_REPO, method=METHOD,
-                                seq=None, backend='hg'):
-    cwd = path = jn(TESTS_TMP_PATH, repo)
-
-    if seq is None:
-        seq = _RandomNameSequence().next()
-
-    try:
-        shutil.rmtree(path, ignore_errors=True)
-        os.makedirs(path)
-        #print 'made dirs %s' % jn(path)
-    except OSError:
-        raise
-
-    clone_url = 'http://%(user)s:%(pass)s@%(host)s/%(cloned_repo)s' % \
-                  {'user': USER,
-                   'pass': PASS,
-                   'host': HOST,
-                   'cloned_repo': repo, }
-
-    dest = path + seq
-    if method == 'pull':
-        stdout, stderr = Command(cwd).execute(backend, method, '--cwd', dest, clone_url)
-    else:
-        stdout, stderr = Command(cwd).execute(backend, method, clone_url, dest)
-        print stdout,'sdasdsadsa'
-        if not no_errors:
-            if backend == 'hg':
-                assert """adding file changes""" in stdout, 'no messages about cloning'
-                assert """abort""" not in stderr , 'got error from clone'
-            elif backend == 'git':
-                assert """Cloning into""" in stdout, 'no messages about cloning'
-
-if __name__ == '__main__':
-    try:
-        create_test_user(force=False)
-        seq = None
-        import time
-
-        try:
-            METHOD = sys.argv[3]
-        except IndexError:
-            pass
-
-        try:
-            backend = sys.argv[4]
-        except IndexError:
-            backend = 'hg'
-
-        if METHOD == 'pull':
-            seq = _RandomNameSequence().next()
-            test_clone_with_credentials(repo=sys.argv[1], method='clone',
-                                        seq=seq, backend=backend)
-        s = time.time()
-        for i in range(1, int(sys.argv[2]) + 1):
-            print 'take', i
-            test_clone_with_credentials(repo=sys.argv[1], method=METHOD,
-                                        seq=seq, backend=backend)
-        print 'time taken %.3f' % (time.time() - s)
-    except Exception, e:
-        sys.exit('stop on %s' % e)
--- a/kallithea/tests/scripts/test_crawler.py	Tue Jun 09 22:12:21 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-# -*- coding: utf-8 -*-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""
-kallithea.tests.test_crawer
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Test for crawling a project for memory usage
-This should be runned just as regular script together
-with a watch script that will show memory usage.
-
-watch -n1 ./kallithea/tests/mem_watch
-
-This file was forked by the Kallithea project in July 2014.
-Original author and date, and relevant copyright and licensing information is below:
-:created_on: Apr 21, 2010
-:author: marcink
-:copyright: (c) 2013 RhodeCode GmbH, and others.
-:license: GPLv3, see LICENSE.md for more details.
-"""
-
-
-import cookielib
-import urllib
-import urllib2
-import time
-import os
-import sys
-from os.path import join as jn
-from os.path import dirname as dn
-
-__here__ = os.path.abspath(__file__)
-__root__ = dn(dn(dn(__here__)))
-sys.path.append(__root__)
-
-from kallithea.lib import vcs
-from kallithea.lib.compat import OrderedSet
-from kallithea.lib.vcs.exceptions import RepositoryError
-
-PASES = 3
-HOST = 'http://127.0.0.1'
-PORT = 5000
-BASE_URI = '%s:%s/' % (HOST, PORT)
-
-if len(sys.argv) == 2:
-    BASE_URI = sys.argv[1]
-
-if not BASE_URI.endswith('/'):
-    BASE_URI += '/'
-
-print 'Crawling @ %s' % BASE_URI
-BASE_URI += '%s'
-PROJECT_PATH = jn('/', 'home', 'marcink', 'repos')
-PROJECTS = [
-    #'linux-magx-pbranch',
-    'CPython',
-    'kallithea',
-]
-
-
-cj = cookielib.FileCookieJar('/tmp/rc_test_cookie.txt')
-o = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
-o.addheaders = [
-    ('User-agent', 'kallithea-crawler'),
-    ('Accept-Language', 'en - us, en;q = 0.5')
-]
-
-urllib2.install_opener(o)
-
-
-def _get_repo(proj):
-    if isinstance(proj, basestring):
-        repo = vcs.get_repo(jn(PROJECT_PATH, proj))
-        proj = proj
-    else:
-        repo = proj
-        proj = repo.name
-
-    return repo, proj
-
-
-def test_changelog_walk(proj, pages=100):
-    repo, proj = _get_repo(proj)
-
-    total_time = 0
-    for i in range(1, pages):
-
-        page = '/'.join((proj, 'changelog',))
-
-        full_uri = (BASE_URI % page) + '?' + urllib.urlencode({'page': i})
-        s = time.time()
-        f = o.open(full_uri)
-
-        assert f.url == full_uri, 'URL:%s does not match %s' % (f.url, full_uri)
-
-        size = len(f.read())
-        e = time.time() - s
-        total_time += e
-        print 'visited %s size:%s req:%s ms' % (full_uri, size, e)
-
-    print 'total_time', total_time
-    print 'average on req', total_time / float(pages)
-
-
-def test_changeset_walk(proj, limit=None):
-    repo, proj = _get_repo(proj)
-
-    print 'processing', jn(PROJECT_PATH, proj)
-    total_time = 0
-
-    cnt = 0
-    for i in repo:
-        cnt += 1
-        raw_cs = '/'.join((proj, 'changeset', i.raw_id))
-        if limit and limit == cnt:
-            break
-
-        full_uri = (BASE_URI % raw_cs)
-        print '%s visiting %s\%s' % (cnt, full_uri, i)
-        s = time.time()
-        f = o.open(full_uri)
-        size = len(f.read())
-        e = time.time() - s
-        total_time += e
-        print '%s visited %s\%s size:%s req:%s ms' % (cnt, full_uri, i, size, e)
-
-    print 'total_time', total_time
-    print 'average on req', total_time / float(cnt)
-
-
-def test_files_walk(proj, limit=100):
-    repo, proj = _get_repo(proj)
-
-    print 'processing', jn(PROJECT_PATH, proj)
-    total_time = 0
-
-    paths_ = OrderedSet([''])
-    try:
-        tip = repo.get_changeset('tip')
-        for topnode, dirs, files in tip.walk('/'):
-
-            for dir in dirs:
-                paths_.add(dir.path)
-                for f in dir:
-                    paths_.add(f.path)
-
-            for f in files:
-                paths_.add(f.path)
-
-    except RepositoryError, e:
-        pass
-
-    cnt = 0
-    for f in paths_:
-        cnt += 1
-        if limit and limit == cnt:
-            break
-
-        file_path = '/'.join((proj, 'files', 'tip', f))
-        full_uri = (BASE_URI % file_path)
-        print '%s visiting %s' % (cnt, full_uri)
-        s = time.time()
-        f = o.open(full_uri)
-        size = len(f.read())
-        e = time.time() - s
-        total_time += e
-        print '%s visited OK size:%s req:%s ms' % (cnt, size, e)
-
-    print 'total_time', total_time
-    print 'average on req', total_time / float(cnt)
-
-if __name__ == '__main__':
-    for path in PROJECTS:
-        repo = vcs.get_repo(jn(PROJECT_PATH, path))
-        for i in range(PASES):
-            print 'PASS %s/%s' % (i, PASES)
-            test_changelog_walk(repo, pages=80)
-            test_changeset_walk(repo, limit=100)
-            test_files_walk(repo, limit=100)
--- a/kallithea/tests/vcs/base.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/base.py	Tue Jun 09 22:46:40 2015 +0200
@@ -13,7 +13,7 @@
 from kallithea.lib.vcs.nodes import FileNode
 
 
-class BackendTestMixin(object):
+class _BackendTestMixin(object):
     """
     This is a backend independent test case class which should be created
     with ``type`` method.
@@ -103,7 +103,7 @@
         'backend_alias': alias,
     }
     cls_name = ''.join(('%s base backend test' % alias).title().split())
-    bases = (BackendTestMixin, unittest.TestCase)
+    bases = (_BackendTestMixin, unittest.TestCase)
     globals()[cls_name] = type(cls_name, bases, attrs)
 
 
--- a/kallithea/tests/vcs/test_archives.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_archives.py	Tue Jun 09 22:46:40 2015 +0200
@@ -6,14 +6,14 @@
 import datetime
 import tempfile
 import StringIO
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 from kallithea.lib.vcs.exceptions import VCSError
 from kallithea.lib.vcs.nodes import FileNode
 from kallithea.lib.vcs.utils.compat import unittest
 
 
-class ArchivesTestCaseMixin(BackendTestMixin):
+class ArchivesTestCaseMixin(_BackendTestMixin):
 
     @classmethod
     def _get_commits(cls):
--- a/kallithea/tests/vcs/test_branches.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_branches.py	Tue Jun 09 22:46:40 2015 +0200
@@ -5,11 +5,11 @@
 from kallithea.lib.vcs.utils.compat import unittest
 from kallithea.lib.vcs.nodes import FileNode
 
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 
 
-class BranchesTestCaseMixin(BackendTestMixin):
+class BranchesTestCaseMixin(_BackendTestMixin):
 
     @classmethod
     def _get_commits(cls):
--- a/kallithea/tests/vcs/test_changesets.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_changesets.py	Tue Jun 09 22:46:40 2015 +0200
@@ -4,7 +4,7 @@
 import time
 import datetime
 from kallithea.lib import vcs
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 
 from kallithea.lib.vcs.backends.base import BaseChangeset
@@ -50,7 +50,7 @@
             'removed': [],
         })
 
-class ChangesetsWithCommitsTestCaseixin(BackendTestMixin):
+class _ChangesetsWithCommitsTestCaseixin(_BackendTestMixin):
     recreate_repo_per_test = True
 
     @classmethod
@@ -146,7 +146,7 @@
             self.assertEqual([sha], self.repo.get_changeset(test_rev).children)
 
 
-class ChangesetsTestCaseMixin(BackendTestMixin):
+class _ChangesetsTestCaseMixin(_BackendTestMixin):
     recreate_repo_per_test = False
 
     @classmethod
@@ -301,7 +301,7 @@
             list(self.repo.get_changesets(start=last-1, end=0))
 
 
-class ChangesetsChangesTestCaseMixin(BackendTestMixin):
+class _ChangesetsChangesTestCaseMixin(_BackendTestMixin):
     recreate_repo_per_test = False
 
     @classmethod
@@ -373,17 +373,17 @@
     }
     # tests with additional commits
     cls_name = ''.join(('%s changesets with commits test' % alias).title().split())
-    bases = (ChangesetsWithCommitsTestCaseixin, unittest.TestCase)
+    bases = (_ChangesetsWithCommitsTestCaseixin, unittest.TestCase)
     globals()[cls_name] = type(cls_name, bases, attrs)
 
     # tests without additional commits
     cls_name = ''.join(('%s changesets test' % alias).title().split())
-    bases = (ChangesetsTestCaseMixin, unittest.TestCase)
+    bases = (_ChangesetsTestCaseMixin, unittest.TestCase)
     globals()[cls_name] = type(cls_name, bases, attrs)
 
     # tests changes
     cls_name = ''.join(('%s changesets changes test' % alias).title().split())
-    bases = (ChangesetsChangesTestCaseMixin, unittest.TestCase)
+    bases = (_ChangesetsChangesTestCaseMixin, unittest.TestCase)
     globals()[cls_name] = type(cls_name, bases, attrs)
 
 
--- a/kallithea/tests/vcs/test_getitem.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_getitem.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,13 +1,13 @@
 from __future__ import with_statement
 
 import datetime
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 from kallithea.lib.vcs.nodes import FileNode
 from kallithea.lib.vcs.utils.compat import unittest
 
 
-class GetitemTestCaseMixin(BackendTestMixin):
+class GetitemTestCaseMixin(_BackendTestMixin):
 
     @classmethod
     def _get_commits(cls):
--- a/kallithea/tests/vcs/test_getslice.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_getslice.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,13 +1,13 @@
 from __future__ import with_statement
 
 import datetime
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 from kallithea.lib.vcs.nodes import FileNode
 from kallithea.lib.vcs.utils.compat import unittest
 
 
-class GetsliceTestCaseMixin(BackendTestMixin):
+class GetsliceTestCaseMixin(_BackendTestMixin):
 
     @classmethod
     def _get_commits(cls):
--- a/kallithea/tests/vcs/test_git.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_git.py	Tue Jun 09 22:46:40 2015 +0200
@@ -8,7 +8,7 @@
 from kallithea.lib.vcs.exceptions import RepositoryError, VCSError, NodeDoesNotExistError
 from kallithea.lib.vcs.nodes import NodeKind, FileNode, DirNode, NodeState
 from kallithea.lib.vcs.utils.compat import unittest
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import TEST_GIT_REPO, TEST_GIT_REPO_CLONE, get_new_dir
 
 
@@ -620,7 +620,7 @@
             changeset.added
 
 
-class GitSpecificWithRepoTest(BackendTestMixin, unittest.TestCase):
+class GitSpecificWithRepoTest(_BackendTestMixin, unittest.TestCase):
     backend_alias = 'git'
 
     @classmethod
@@ -688,7 +688,7 @@
             % (3, self.repo._get_revision(0), self.repo._get_revision(1)))
 
 
-class GitRegressionTest(BackendTestMixin, unittest.TestCase):
+class GitRegressionTest(_BackendTestMixin, unittest.TestCase):
     backend_alias = 'git'
 
     @classmethod
--- a/kallithea/tests/vcs/test_repository.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_repository.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,6 +1,6 @@
 from __future__ import with_statement
 import datetime
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 from kallithea.tests.vcs.conf import TEST_USER_CONFIG_FILE
 from kallithea.lib.vcs.nodes import FileNode
@@ -8,7 +8,7 @@
 from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError
 
 
-class RepositoryBaseTest(BackendTestMixin):
+class RepositoryBaseTest(_BackendTestMixin):
     recreate_repo_per_test = False
 
     @classmethod
@@ -46,7 +46,7 @@
         self.assertTrue(self.repo != dummy())
 
 
-class RepositoryGetDiffTest(BackendTestMixin):
+class RepositoryGetDiffTest(_BackendTestMixin):
 
     @classmethod
     def _get_commits(cls):
--- a/kallithea/tests/vcs/test_tags.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_tags.py	Tue Jun 09 22:46:40 2015 +0200
@@ -1,13 +1,13 @@
 from __future__ import with_statement
 
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 from kallithea.lib.vcs.exceptions import TagAlreadyExistError
 from kallithea.lib.vcs.exceptions import TagDoesNotExistError
 from kallithea.lib.vcs.utils.compat import unittest
 
 
-class TagsTestCaseMixin(BackendTestMixin):
+class TagsTestCaseMixin(_BackendTestMixin):
 
     def test_new_tag(self):
         tip = self.repo.get_changeset()
--- a/kallithea/tests/vcs/test_utils.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_utils.py	Tue Jun 09 22:46:40 2015 +0200
@@ -185,14 +185,14 @@
 
 
 class TestAuthorExtractors(unittest.TestCase):
-    TEST_AUTHORS = [('Marcin Kuzminski <marcin@python-works.com>',
-                    ('Marcin Kuzminski', 'marcin@python-works.com')),
-                  ('Marcin Kuzminski Spaces < marcin@python-works.com >',
-                    ('Marcin Kuzminski Spaces', 'marcin@python-works.com')),
-                  ('Marcin Kuzminski <marcin.kuzminski@python-works.com>',
-                    ('Marcin Kuzminski', 'marcin.kuzminski@python-works.com')),
-                  ('mrf RFC_SPEC <marcin+kuzminski@python-works.com>',
-                    ('mrf RFC_SPEC', 'marcin+kuzminski@python-works.com')),
+    TEST_AUTHORS = [("Username Last'o'Name <username@python-works.com>",
+                    ("Username Last'o'Name", "username@python-works.com")),
+                  ("Username Last'o'Name Spaces < username@python-works.com >",
+                    ("Username Last'o'Name Spaces", "username@python-works.com")),
+                  ("Username Last'o'Name <username.lastname@python-works.com>",
+                    ("Username Last'o'Name", "username.lastname@python-works.com")),
+                  ('mrf RFC_SPEC <username+lastname@python-works.com>',
+                    ('mrf RFC_SPEC', 'username+lastname@python-works.com')),
                   ('username <user@email.com>',
                     ('username', 'user@email.com')),
                   ('username <user@email.com',
--- a/kallithea/tests/vcs/test_workdirs.py	Tue Jun 09 22:12:21 2015 +0200
+++ b/kallithea/tests/vcs/test_workdirs.py	Tue Jun 09 22:46:40 2015 +0200
@@ -3,11 +3,11 @@
 import datetime
 from kallithea.lib.vcs.nodes import FileNode
 from kallithea.lib.vcs.utils.compat import unittest
-from kallithea.tests.vcs.base import BackendTestMixin
+from kallithea.tests.vcs.base import _BackendTestMixin
 from kallithea.tests.vcs.conf import SCM_TESTS
 
 
-class WorkdirTestCaseMixin(BackendTestMixin):
+class WorkdirTestCaseMixin(_BackendTestMixin):
 
     @classmethod
     def _get_commits(cls):
--- a/production.ini	Tue Jun 09 22:12:21 2015 +0200
+++ b/production.ini	Tue Jun 09 22:46:40 2015 +0200
@@ -133,7 +133,7 @@
 host = 127.0.0.1
 port = 5000
 
-## prefix middleware for rc
+## middleware for hosting the WSGI application under a URL prefix
 #[filter:proxy-prefix]
 #use = egg:PasteDeploy#prefix
 #prefix = /<your-prefix>
--- a/setup.cfg	Tue Jun 09 22:12:21 2015 +0200
+++ b/setup.cfg	Tue Jun 09 22:46:40 2015 +0200
@@ -10,6 +10,16 @@
 detailed-errors = 1
 nologcapture = 1
 
+[pytest]
+# only look for tests in kallithea/tests
+python_files = kallithea/tests/**/test_*.py
+addopts =
+    # --verbose
+    # show extra test summary info as specified by chars (f)ailed, (E)error, (s)skipped, (x)failed, (X)passed, (w)warnings.
+    -rfEsxXw
+    # Shorter scrollbacks; less stuff to scroll through
+    --tb=short
+
 [compile_catalog]
 domain = kallithea
 directory = kallithea/i18n
--- a/test.ini	Tue Jun 09 22:12:21 2015 +0200
+++ b/test.ini	Tue Jun 09 22:46:40 2015 +0200
@@ -133,7 +133,7 @@
 host = 127.0.0.1
 port = 5000
 
-## prefix middleware for rc
+## middleware for hosting the WSGI application under a URL prefix
 #[filter:proxy-prefix]
 #use = egg:PasteDeploy#prefix
 #prefix = /<your-prefix>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tox.ini	Tue Jun 09 22:46:40 2015 +0200
@@ -0,0 +1,12 @@
+[tox]
+envlist = py{26,27}-{pytest,nose}
+
+[testenv]
+setenv =
+    PYTHONHASHSEED = 0
+deps =
+    nose: nose
+    pytest: pytest
+commands =
+    nose: nosetests {posargs}
+    pytest: py.test {posargs}