##// END OF EJS Templates
release: Merge default into stable for release preparation
marcink -
r3786:3da01d04 merge stable
parent child Browse files
Show More
@@ -0,0 +1,28 b''
1 .. _repo-admin-set:
2 .. _permissions-info-add-group-ref:
3
4 Repository Administration
5 =========================
6
7 Repository permissions in |RCE| can be managed in a number of different ways.
8 This overview should give you an insight into how you could adopt particular
9 settings for your needs:
10
11 * Global |repo| permissions: This allows you to set the default permissions
12 for each new |repo| created within |RCE|, see :ref:`repo-default-ref`. All
13 |repos| created will inherit these permissions unless explicitly configured.
14 * Individual |repo| permissions: To set individual |repo| permissions,
15 see :ref:`set-repo-perms`.
16 * Repository Group permissions: This allows you to define the permissions for
17 a group, and all |repos| created within that group will inherit the same
18 permissions.
19
20 .. toctree::
21
22 repo_admin/repo-perm-steps
23 repo_admin/repo-extra-fields
24 repo_admin/repo-hooks
25 repo_admin/repo-issue-tracker
26 repo_admin/repo-vcs
27 repo_admin/restore-deleted-repositories
28 repo_admin/repo-admin-tasks No newline at end of file
@@ -0,0 +1,24 b''
1 .. _repo-admin-tasks:
2
3 Common Admin Tasks for Repositories
4 -----------------------------------
5
6
7 Manually Force Delete Repository
8 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9
10 In case of attached forks or pull-requests repositories should be archived.
11 Here is how to force delete a repository and remove all dependent objects
12
13
14 .. code-block:: bash
15
16 # starts the ishell interactive prompt
17 $ rccontrol ishell enterprise-1
18
19 .. code-block:: python
20
21 In [4]: from rhodecode.model.repo import RepoModel
22 In [3]: repo = Repository.get_by_repo_name('test_repos/repo_with_prs')
23 In [5]: RepoModel().delete(repo, forks='detach', pull_requests='delete')
24 In [6]: Session().commit()
@@ -0,0 +1,24 b''
1 .. _user-admin-tasks:
2
3 Common Admin Tasks for Users
4 ----------------------------
5
6
7 Manually Set Personal Repository Group
8 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9
10 Here is how to set a repository group as personal for a user using ishell.
11
12
13 .. code-block:: bash
14
15 # starts the ishell interactive prompt
16 $ rccontrol ishell enterprise-1
17
18 .. code-block:: python
19
20 In [1]: repo_group = RepoGroup.get_by_group_name('some_group_name')
21 In [2]: user = User.get_by_username('some_user')
22 In [3]: repo_group.user = user
23 In [4]: repo_group.personal = True
24 In [5]: Session().add(repo_group);Session().commit()
@@ -0,0 +1,35 b''
1 .. _search-methods-ref:
2
3 search methods
4 ==============
5
6 search
7 ------
8
9 .. py:function:: search(apiuser, search_query, search_type, page_limit=<Optional:10>, page=<Optional:1>, search_sort=<Optional:'newfirst'>, repo_name=<Optional:None>, repo_group_name=<Optional:None>)
10
11 Fetch Full Text Search results using API.
12
13 :param apiuser: This is filled automatically from the |authtoken|.
14 :type apiuser: AuthUser
15 :param search_query: Search query.
16 :type search_query: str
17 :param search_type: Search type. The following are valid options:
18 * commit
19 * content
20 * path
21 :type search_type: str
22 :param page_limit: Page item limit, from 1 to 500. Default 10 items.
23 :type page_limit: Optional(int)
24 :param page: Page number. Default first page.
25 :type page: Optional(int)
26 :param search_sort: Search sort order. Default newfirst. The following are valid options:
27 * newfirst
28 * oldfirst
29 :type search_sort: Optional(str)
30 :param repo_name: Filter by one repo. Default is all.
31 :type repo_name: Optional(str)
32 :param repo_group_name: Filter by one repo group. Default is all.
33 :type repo_group_name: Optional(str)
34
35
@@ -0,0 +1,85 b''
1 |RCE| 4.17.0 |RNS|
2 ------------------
3
4 Release Date
5 ^^^^^^^^^^^^
6
7 - 2019-07-04
8
9
10 New Features
11 ^^^^^^^^^^^^
12
13 - New artifacts feature.
14 Ability to store binary artifacts for repository with ACL
15 - UI/UX refresh for most of the pages. This includes multiple fixes and improvements.
16 - Diffs: store wide-diff mode in user sessions to store user preference for diff display.
17 - Mercurial: added support for Mercurial 4.9
18 - API: Added search API methods
19 - Files: adding/editing allows previews for generated content.
20 - Files: allowed multi file upload using UI.
21 - Repository Groups: last change is now smartly calculated based on latest change
22 from all it's children repositories.
23 - Archives: it's now currently possible to download partial directories from files view.
24 - SVN: allowed executing pre-commit code with rcextensions, also added example to
25 validate SVN file size and paths on pre-commit level.
26
27
28 General
29 ^^^^^^^
30 - Exception store: add filter for display and deletion.
31 - Files: loading history doesn't display hidden and obsolete commits anymore.
32 - Repositories: bring back missing watch action in summary view.
33 - Admin: user groups is now using pure DB filtering to speed up display
34 for large number of groups.
35 - Mercurial: enabled full evolve+topic extensions when evolve is enabled.
36 - Dependencies: bumped evolve to 8.5.1
37 - Dependencies: bumped pyramid to 1.10.4
38 - Dependencies: bumped psutil to 5.5.1
39 - Dependencies: bumped pygments to 2.4.2
40 - Dependencies: bumped pyramid to 1.10.4
41 - Dependencies: bumped psycopg2 to 2.8.3
42 - Dependencies [security]: updated colander to 1.7.0
43
44
45 Security
46 ^^^^^^^^
47
48 - SSH: replaced pycrypto with cryptography to generate SSH keys as pycrypto isn't
49 considered safe anymore.
50
51
52 Performance
53 ^^^^^^^^^^^
54
55 - Config: updated header limits on gunicorn to prevent errors on large Mercurial repositories.
56 - User sessions: added option to cleanup redis based sessions in user session interface.
57 - Authentication: reduced usage of raw auth calls inside templates to speed up rendering.
58 - Sessions: don't touch session for API calls. Before each API call created new session
59 object which wasn't required.
60
61
62 Fixes
63 ^^^^^
64
65 - hHooks: fixed more unicode problems with new pull-request link generator.
66 - Mercurial: fix ssh-server support for mercurial custom options.
67 - Pull requests: updated metadata information for failed merges with multiple heads.
68 - Pull requests: calculate ancestor in the same way as creation mode.
69 Fixed problem with updates generating wrong diffs in case of merges.
70 - Pull requests: fixed a bug in removal of multiple reviewers at once.
71 - Summary: fix timeout issues loading summary page without styling.
72 - SSH: fix invocation of custom hgrc.
73 - SSH: call custom hooks via SSH backend
74 - Markup: fix styling for check-lists.
75 - Archives: allows downloading refs that have slashes and special refs. e.g f/feat1 branch names.
76 - Files: ensure we generate archives with consistent hashing (except for .tar.gz which uses temp files names in header)
77 - Files: fixed rendering of readme files under non-ascii paths.
78
79
80 Upgrade notes
81 ^^^^^^^^^^^^^
82
83 - In this release we introduced new UI across the application.
84 In case of problems with the display on your systems please send us info to support@rhodecode.com.
85
@@ -0,0 +1,19 b''
1 # contains not directly required libraries we want to pin the version.
2
3 atomicwrites==1.2.1
4 attrs==18.2.0
5 billiard==3.5.0.3
6 chameleon==2.24
7 cffi==1.12.2
8 ecdsa==0.13.2
9 hupper==1.6.1
10 gnureadline==6.3.8
11 jinja2==2.9.6
12 jsonschema==2.6.0
13 pyramid-jinja2==2.7
14 pluggy==0.11.0
15 setproctitle==1.1.10
16 scandir==1.10.0
17 tempita==0.5.2
18 vine==1.3.0
19 configparser==3.7.4
@@ -0,0 +1,93 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import pytest
22 from rhodecode.tests import HG_REPO
23 from rhodecode.api.tests.utils import (
24 build_data, api_call, assert_error, assert_ok)
25
26
27 @pytest.mark.usefixtures("testuser_api", "app")
28 class TestApiSearch(object):
29
30 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
31 ('todo', 23, [
32 'vcs/backends/hg/inmemory.py',
33 'vcs/tests/test_git.py']),
34 ('extension:rst installation', 6, [
35 'docs/index.rst',
36 'docs/installation.rst']),
37 ('def repo', 87, [
38 'vcs/tests/test_git.py',
39 'vcs/tests/test_changesets.py']),
40 ('repository:%s def test' % HG_REPO, 18, [
41 'vcs/tests/test_git.py',
42 'vcs/tests/test_changesets.py']),
43 ('"def main"', 9, [
44 'vcs/__init__.py',
45 'vcs/tests/__init__.py',
46 'vcs/utils/progressbar.py']),
47 ('owner:test_admin', 358, [
48 'vcs/tests/base.py',
49 'MANIFEST.in',
50 'vcs/utils/termcolors.py',
51 'docs/theme/ADC/static/documentation.png']),
52 ('owner:test_admin def main', 72, [
53 'vcs/__init__.py',
54 'vcs/tests/test_utils_filesize.py',
55 'vcs/tests/test_cli.py']),
56 ('owner:michał test', 0, []),
57 ])
58 def test_search_content_results(self, query, expected_hits, expected_paths):
59 id_, params = build_data(
60 self.apikey_regular, 'search',
61 search_query=query,
62 search_type='content')
63
64 response = api_call(self.app, params)
65 json_response = response.json
66
67 assert json_response['result']['item_count'] == expected_hits
68 paths = [x['f_path'] for x in json_response['result']['results']]
69
70 for expected_path in expected_paths:
71 assert expected_path in paths
72
73 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
74 ('readme.rst', 3, []),
75 ('test*', 75, []),
76 ('*model*', 1, []),
77 ('extension:rst', 48, []),
78 ('extension:rst api', 24, []),
79 ])
80 def test_search_file_paths(self, query, expected_hits, expected_paths):
81 id_, params = build_data(
82 self.apikey_regular, 'search',
83 search_query=query,
84 search_type='path')
85
86 response = api_call(self.app, params)
87 json_response = response.json
88
89 assert json_response['result']['item_count'] == expected_hits
90 paths = [x['f_path'] for x in json_response['result']['results']]
91
92 for expected_path in expected_paths:
93 assert expected_path in paths
@@ -0,0 +1,112 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2011-2019 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21
22 import logging
23
24 from rhodecode.api import jsonrpc_method
25 from rhodecode.api.exc import JSONRPCValidationError
26 from rhodecode.api.utils import Optional
27 from rhodecode.lib.index import searcher_from_config
28 from rhodecode.model import validation_schema
29 from rhodecode.model.validation_schema.schemas import search_schema
30
31 log = logging.getLogger(__name__)
32
33
34 @jsonrpc_method()
35 def search(request, apiuser, search_query, search_type, page_limit=Optional(10),
36 page=Optional(1), search_sort=Optional('newfirst'),
37 repo_name=Optional(None), repo_group_name=Optional(None)):
38 """
39 Fetch Full Text Search results using API.
40
41 :param apiuser: This is filled automatically from the |authtoken|.
42 :type apiuser: AuthUser
43 :param search_query: Search query.
44 :type search_query: str
45 :param search_type: Search type. The following are valid options:
46 * commit
47 * content
48 * path
49 :type search_type: str
50 :param page_limit: Page item limit, from 1 to 500. Default 10 items.
51 :type page_limit: Optional(int)
52 :param page: Page number. Default first page.
53 :type page: Optional(int)
54 :param search_sort: Search sort order. Default newfirst. The following are valid options:
55 * newfirst
56 * oldfirst
57 :type search_sort: Optional(str)
58 :param repo_name: Filter by one repo. Default is all.
59 :type repo_name: Optional(str)
60 :param repo_group_name: Filter by one repo group. Default is all.
61 :type repo_group_name: Optional(str)
62 """
63
64 data = {'execution_time': ''}
65 repo_name = Optional.extract(repo_name)
66 repo_group_name = Optional.extract(repo_group_name)
67
68 schema = search_schema.SearchParamsSchema()
69
70 try:
71 search_params = schema.deserialize(
72 dict(search_query=search_query,
73 search_type=search_type,
74 search_sort=Optional.extract(search_sort),
75 page_limit=Optional.extract(page_limit),
76 requested_page=Optional.extract(page))
77 )
78 except validation_schema.Invalid as err:
79 raise JSONRPCValidationError(colander_exc=err)
80
81 search_query = search_params.get('search_query')
82 search_type = search_params.get('search_type')
83 search_sort = search_params.get('search_sort')
84
85 if search_params.get('search_query'):
86 page_limit = search_params['page_limit']
87 requested_page = search_params['requested_page']
88
89 searcher = searcher_from_config(request.registry.settings)
90
91 try:
92 search_result = searcher.search(
93 search_query, search_type, apiuser, repo_name, repo_group_name,
94 requested_page=requested_page, page_limit=page_limit, sort=search_sort)
95
96 data.update(dict(
97 results=list(search_result['results']), page=requested_page,
98 item_count=search_result['count'],
99 items_per_page=page_limit))
100 finally:
101 searcher.cleanup()
102
103 if not search_result['error']:
104 data['execution_time'] = '%s results (%.3f seconds)' % (
105 search_result['count'],
106 search_result['runtime'])
107 else:
108 node = schema['search_query']
109 raise JSONRPCValidationError(
110 colander_exc=validation_schema.Invalid(node, search_result['error']))
111
112 return data
@@ -0,0 +1,48 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2011-2019 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22
23 from pyramid.view import view_config
24
25 from rhodecode.apps._base import RepoAppView
26 from rhodecode.lib.auth import (
27 LoginRequired, HasRepoPermissionAnyDecorator)
28
29 log = logging.getLogger(__name__)
30
31
32 class RepoArtifactsView(RepoAppView):
33
34 def load_default_context(self):
35 c = self._get_local_tmpl_context(include_app_defaults=True)
36 c.rhodecode_repo = self.rhodecode_vcs_repo
37 return c
38
39 @LoginRequired()
40 @HasRepoPermissionAnyDecorator(
41 'repository.read', 'repository.write', 'repository.admin')
42 @view_config(
43 route_name='repo_artifacts_list', request_method='GET',
44 renderer='rhodecode:templates/artifacts/artifact_list.mako')
45 def repo_artifacts(self):
46 c = self.load_default_context()
47 c.active = 'artifacts'
48 return self._get_template_context(c)
@@ -0,0 +1,55 b''
1 # -*- coding: utf-8 -*-
2
3 import logging
4
5 from alembic.migration import MigrationContext
6 from alembic.operations import Operations
7 from sqlalchemy import String, Column
8 from sqlalchemy.sql import text
9
10 from rhodecode.lib.dbmigrate.versions import _reset_base
11 from rhodecode.lib.utils2 import safe_str
12 from rhodecode.model import meta, init_model_encryption
13 from rhodecode.model.db import RepoGroup
14
15
16 log = logging.getLogger(__name__)
17
18
19 def upgrade(migrate_engine):
20 """
21 Upgrade operations go here.
22 Don't create your own engine; bind migrate_engine to your metadata
23 """
24 _reset_base(migrate_engine)
25 from rhodecode.lib.dbmigrate.schema import db_4_16_0_2
26
27 init_model_encryption(db_4_16_0_2)
28
29 context = MigrationContext.configure(migrate_engine.connect())
30 op = Operations(context)
31
32 repo_group = db_4_16_0_2.RepoGroup.__table__
33
34 with op.batch_alter_table(repo_group.name) as batch_op:
35 batch_op.add_column(
36 Column("repo_group_name_hash", String(1024), nullable=True, unique=False))
37
38 _generate_repo_group_name_hashes(db_4_16_0_2, op, meta.Session)
39
40
41 def downgrade(migrate_engine):
42 pass
43
44
45 def _generate_repo_group_name_hashes(models, op, session):
46 repo_groups = models.RepoGroup.get_all()
47 for repo_group in repo_groups:
48 print(safe_str(repo_group.group_name))
49 hash_ = RepoGroup.hash_repo_group_name(repo_group.group_name)
50 params = {'hash': hash_, 'id': repo_group.group_id}
51 query = text(
52 'UPDATE groups SET repo_group_name_hash = :hash'
53 ' WHERE group_id = :id').bindparams(**params)
54 op.execute(query)
55 session().commit()
@@ -0,0 +1,35 b''
1 # -*- coding: utf-8 -*-
2
3 import logging
4
5 from alembic.migration import MigrationContext
6 from alembic.operations import Operations
7
8 from rhodecode.lib.dbmigrate.versions import _reset_base
9 from rhodecode.model import init_model_encryption
10
11
12 log = logging.getLogger(__name__)
13
14
15 def upgrade(migrate_engine):
16 """
17 Upgrade operations go here.
18 Don't create your own engine; bind migrate_engine to your metadata
19 """
20 _reset_base(migrate_engine)
21 from rhodecode.lib.dbmigrate.schema import db_4_16_0_2
22
23 init_model_encryption(db_4_16_0_2)
24
25 context = MigrationContext.configure(migrate_engine.connect())
26 op = Operations(context)
27
28 repo_group = db_4_16_0_2.RepoGroup.__table__
29
30 with op.batch_alter_table(repo_group.name) as batch_op:
31 batch_op.alter_column("repo_group_name_hash", nullable=False)
32
33
34 def downgrade(migrate_engine):
35 pass
@@ -0,0 +1,37 b''
1 # -*- coding: utf-8 -*-
2
3 import logging
4
5 from alembic.migration import MigrationContext
6 from alembic.operations import Operations
7 from sqlalchemy import Column, LargeBinary
8
9 from rhodecode.lib.dbmigrate.versions import _reset_base
10 from rhodecode.model import init_model_encryption
11
12
13 log = logging.getLogger(__name__)
14
15
16 def upgrade(migrate_engine):
17 """
18 Upgrade operations go here.
19 Don't create your own engine; bind migrate_engine to your metadata
20 """
21 _reset_base(migrate_engine)
22 from rhodecode.lib.dbmigrate.schema import db_4_16_0_2
23
24 init_model_encryption(db_4_16_0_2)
25
26 context = MigrationContext.configure(migrate_engine.connect())
27 op = Operations(context)
28
29 repo_group = db_4_16_0_2.RepoGroup.__table__
30
31 with op.batch_alter_table(repo_group.name) as batch_op:
32 batch_op.add_column(
33 Column("changeset_cache", LargeBinary(1024), nullable=True))
34
35
36 def downgrade(migrate_engine):
37 pass
@@ -0,0 +1,69 b''
1 import os
2 import base64
3 from cryptography.fernet import Fernet, InvalidToken
4 from cryptography.hazmat.backends import default_backend
5 from cryptography.hazmat.primitives import hashes
6 from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
7
8
9 class Encryptor(object):
10 key_format = 'enc2$salt:{}$data:{}'
11 pref_len = 5 # salt:, data:
12
13 def __init__(self, enc_key):
14 self.enc_key = enc_key
15
16 def b64_encode(self, data):
17 return base64.urlsafe_b64encode(data)
18
19 def b64_decode(self, data):
20 return base64.urlsafe_b64decode(data)
21
22 def get_encryptor(self, salt):
23 """
24 Uses Fernet as encryptor with HMAC signature
25 :param salt: random salt used for encrypting the data
26 """
27 kdf = PBKDF2HMAC(
28 algorithm=hashes.SHA512(),
29 length=32,
30 salt=salt,
31 iterations=100000,
32 backend=default_backend()
33 )
34 key = self.b64_encode(kdf.derive(self.enc_key))
35 return Fernet(key)
36
37 def _get_parts(self, enc_data):
38 parts = enc_data.split('$', 3)
39 if len(parts) != 3:
40 raise ValueError('Encrypted Data has invalid format, expected {}'.format(self.key_format))
41 prefix, salt, enc_data = parts
42
43 try:
44 salt = self.b64_decode(salt[self.pref_len:])
45 except TypeError:
46 # bad base64
47 raise ValueError('Encrypted Data salt invalid format, expected base64 format')
48
49 enc_data = enc_data[self.pref_len:]
50 return prefix, salt, enc_data
51
52 def encrypt(self, data):
53 salt = os.urandom(64)
54 encryptor = self.get_encryptor(salt)
55 enc_data = encryptor.encrypt(data)
56 return self.key_format.format(self.b64_encode(salt), enc_data)
57
58 def decrypt(self, data, safe=True):
59 parts = self._get_parts(data)
60 salt = parts[1]
61 enc_data = parts[2]
62 encryptor = self.get_encryptor(salt)
63 try:
64 return encryptor.decrypt(enc_data)
65 except (InvalidToken,):
66 if safe:
67 return ''
68 else:
69 raise
@@ -0,0 +1,200 b''
1 # Copyright (c) 2010 Agendaless Consulting and Contributors.
2 # (http://www.agendaless.com), All Rights Reserved
3 # License: BSD-derived (http://www.repoze.org/LICENSE.txt)
4 # With Patches from RhodeCode GmBH
5
6
7 import os
8
9 from beaker import cache
10 from beaker.session import SessionObject
11 from beaker.util import coerce_cache_params
12 from beaker.util import coerce_session_params
13
14 from pyramid.interfaces import ISession
15 from pyramid.settings import asbool
16 from zope.interface import implementer
17
18 from binascii import hexlify
19
20
21 def BeakerSessionFactoryConfig(**options):
22 """ Return a Pyramid session factory using Beaker session settings
23 supplied directly as ``**options``"""
24
25 class PyramidBeakerSessionObject(SessionObject):
26 _options = options
27 _cookie_on_exception = _options.pop('cookie_on_exception', True)
28 _constant_csrf_token = _options.pop('constant_csrf_token', False)
29
30 def __init__(self, request):
31 SessionObject.__init__(self, request.environ, **self._options)
32
33 def session_callback(request, response):
34 exception = getattr(request, 'exception', None)
35 if (exception is None or self._cookie_on_exception) and self.accessed():
36 self.persist()
37 headers = self.__dict__['_headers']
38 if headers['set_cookie'] and headers['cookie_out']:
39 response.headerlist.append(('Set-Cookie', headers['cookie_out']))
40 request.add_response_callback(session_callback)
41
42 # ISession API
43
44 @property
45 def id(self):
46 # this is as inspected in SessionObject.__init__
47 if self.__dict__['_params'].get('type') != 'cookie':
48 return self._session().id
49 return None
50
51 @property
52 def new(self):
53 return self.last_accessed is None
54
55 changed = SessionObject.save
56
57 # modifying dictionary methods
58
59 @call_save
60 def clear(self):
61 return self._session().clear()
62
63 @call_save
64 def update(self, d, **kw):
65 return self._session().update(d, **kw)
66
67 @call_save
68 def setdefault(self, k, d=None):
69 return self._session().setdefault(k, d)
70
71 @call_save
72 def pop(self, k, d=None):
73 return self._session().pop(k, d)
74
75 @call_save
76 def popitem(self):
77 return self._session().popitem()
78
79 __setitem__ = call_save(SessionObject.__setitem__)
80 __delitem__ = call_save(SessionObject.__delitem__)
81
82 # Flash API methods
83 def flash(self, msg, queue='', allow_duplicate=True):
84 storage = self.setdefault('_f_' + queue, [])
85 if allow_duplicate or (msg not in storage):
86 storage.append(msg)
87
88 def pop_flash(self, queue=''):
89 storage = self.pop('_f_' + queue, [])
90 return storage
91
92 def peek_flash(self, queue=''):
93 storage = self.get('_f_' + queue, [])
94 return storage
95
96 # CSRF API methods
97 def new_csrf_token(self):
98 token = (self._constant_csrf_token
99 or hexlify(os.urandom(20)).decode('ascii'))
100 self['_csrft_'] = token
101 return token
102
103 def get_csrf_token(self):
104 token = self.get('_csrft_', None)
105 if token is None:
106 token = self.new_csrf_token()
107 return token
108
109 return implementer(ISession)(PyramidBeakerSessionObject)
110
111
112 def call_save(wrapped):
113 """ By default, in non-auto-mode beaker badly wants people to
114 call save even though it should know something has changed when
115 a mutating method is called. This hack should be removed if
116 Beaker ever starts to do this by default. """
117 def save(session, *arg, **kw):
118 value = wrapped(session, *arg, **kw)
119 session.save()
120 return value
121 save.__doc__ = wrapped.__doc__
122 return save
123
124
125 def session_factory_from_settings(settings):
126 """ Return a Pyramid session factory using Beaker session settings
127 supplied from a Paste configuration file"""
128 prefixes = ('session.', 'beaker.session.')
129 options = {}
130
131 # Pull out any config args meant for beaker session. if there are any
132 for k, v in settings.items():
133 for prefix in prefixes:
134 if k.startswith(prefix):
135 option_name = k[len(prefix):]
136 if option_name == 'cookie_on_exception':
137 v = asbool(v)
138 options[option_name] = v
139
140 options = coerce_session_params(options)
141 return BeakerSessionFactoryConfig(**options)
142
143
144 def set_cache_regions_from_settings(settings):
145 """ Add cache support to the Pylons application.
146
147 The ``settings`` passed to the configurator are used to setup
148 the cache options. Cache options in the settings should start
149 with either 'beaker.cache.' or 'cache.'.
150
151 """
152 cache_settings = {'regions': []}
153 for key in settings.keys():
154 for prefix in ['beaker.cache.', 'cache.']:
155 if key.startswith(prefix):
156 name = key.split(prefix)[1].strip()
157 cache_settings[name] = settings[key].strip()
158
159 if ('expire' in cache_settings
160 and isinstance(cache_settings['expire'], basestring)
161 and cache_settings['expire'].lower() in ['none', 'no']):
162 cache_settings['expire'] = None
163
164 coerce_cache_params(cache_settings)
165
166 if 'enabled' not in cache_settings:
167 cache_settings['enabled'] = True
168
169 regions = cache_settings['regions']
170 if regions:
171 for region in regions:
172 if not region:
173 continue
174
175 region_settings = {
176 'data_dir': cache_settings.get('data_dir'),
177 'lock_dir': cache_settings.get('lock_dir'),
178 'expire': cache_settings.get('expire', 60),
179 'enabled': cache_settings['enabled'],
180 'key_length': cache_settings.get('key_length', 250),
181 'type': cache_settings.get('type'),
182 'url': cache_settings.get('url'),
183 }
184 region_prefix = '%s.' % region
185 region_len = len(region_prefix)
186 for key in list(cache_settings.keys()):
187 if key.startswith(region_prefix):
188 region_settings[key[region_len:]] = cache_settings.pop(key)
189
190 if (isinstance(region_settings['expire'], basestring)
191 and region_settings['expire'].lower() in ['none', 'no']):
192 region_settings['expire'] = None
193 coerce_cache_params(region_settings)
194 cache.cache_regions[region] = region_settings
195
196
197 def includeme(config):
198 session_factory = session_factory_from_settings(config.registry.settings)
199 config.set_session_factory(session_factory)
200 set_cache_regions_from_settings(config.registry.settings)
This diff has been collapsed as it changes many lines, (11669 lines changed) Show them Hide them
@@ -0,0 +1,11669 b''
1 div.ipynb {
2 /*!
3 *
4 * Twitter Bootstrap
5 *
6 */
7 /*!
8 * Bootstrap v3.3.7 (http://getbootstrap.com)
9 * Copyright 2011-2016 Twitter, Inc.
10 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11 */
12 /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
13 html {
14 font-family: sans-serif;
15 -ms-text-size-adjust: 100%;
16 -webkit-text-size-adjust: 100%;
17 }
18 body {
19 margin: 0;
20 }
21 article,
22 aside,
23 details,
24 figcaption,
25 figure,
26 footer,
27 header,
28 hgroup,
29 main,
30 menu,
31 nav,
32 section,
33 summary {
34 display: block;
35 }
36 audio,
37 canvas,
38 progress,
39 video {
40 display: inline-block;
41 vertical-align: baseline;
42 }
43 audio:not([controls]) {
44 display: none;
45 height: 0;
46 }
47 [hidden],
48 template {
49 display: none;
50 }
51 a {
52 background-color: transparent;
53 }
54 a:active,
55 a:hover {
56 outline: 0;
57 }
58 abbr[title] {
59 border-bottom: 1px dotted;
60 }
61 b,
62 strong {
63 font-weight: bold;
64 }
65 dfn {
66 font-style: italic;
67 }
68 h1 {
69 font-size: 2em;
70 margin: 0.67em 0;
71 }
72 mark {
73 background: #ff0;
74 color: #000;
75 }
76 small {
77 font-size: 80%;
78 }
79 sub,
80 sup {
81 font-size: 75%;
82 line-height: 0;
83 position: relative;
84 vertical-align: baseline;
85 }
86 sup {
87 top: -0.5em;
88 }
89 sub {
90 bottom: -0.25em;
91 }
92 img {
93 border: 0;
94 }
95 svg:not(:root) {
96 overflow: hidden;
97 }
98 figure {
99 margin: 1em 40px;
100 }
101 hr {
102 box-sizing: content-box;
103 height: 0;
104 }
105 pre {
106 overflow: auto;
107 }
108 code,
109 kbd,
110 pre,
111 samp {
112 font-family: monospace, monospace;
113 font-size: 1em;
114 }
115 button,
116 input,
117 optgroup,
118 select,
119 textarea {
120 color: inherit;
121 font: inherit;
122 margin: 0;
123 }
124 button {
125 overflow: visible;
126 }
127 button,
128 select {
129 text-transform: none;
130 }
131 button,
132 html input[type="button"],
133 input[type="reset"],
134 input[type="submit"] {
135 -webkit-appearance: button;
136 cursor: pointer;
137 }
138 button[disabled],
139 html input[disabled] {
140 cursor: default;
141 }
142 button::-moz-focus-inner,
143 input::-moz-focus-inner {
144 border: 0;
145 padding: 0;
146 }
147 input {
148 line-height: normal;
149 }
150 input[type="checkbox"],
151 input[type="radio"] {
152 box-sizing: border-box;
153 padding: 0;
154 }
155 input[type="number"]::-webkit-inner-spin-button,
156 input[type="number"]::-webkit-outer-spin-button {
157 height: auto;
158 }
159 input[type="search"] {
160 -webkit-appearance: textfield;
161 box-sizing: content-box;
162 }
163 input[type="search"]::-webkit-search-cancel-button,
164 input[type="search"]::-webkit-search-decoration {
165 -webkit-appearance: none;
166 }
167 fieldset {
168 border: 1px solid #c0c0c0;
169 margin: 0 2px;
170 padding: 0.35em 0.625em 0.75em;
171 }
172 legend {
173 border: 0;
174 padding: 0;
175 }
176 textarea {
177 overflow: auto;
178 }
179 optgroup {
180 font-weight: bold;
181 }
182 table {
183 border-collapse: collapse;
184 border-spacing: 0;
185 }
186 td,
187 th {
188 padding: 0;
189 }
190 /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
191 @media print {
192 *,
193 *:before,
194 *:after {
195 background: transparent !important;
196 color: #000 !important;
197 box-shadow: none !important;
198 text-shadow: none !important;
199 }
200 a,
201 a:visited {
202 text-decoration: underline;
203 }
204 a[href]:after {
205 content: " (" attr(href) ")";
206 }
207 abbr[title]:after {
208 content: " (" attr(title) ")";
209 }
210 a[href^="#"]:after,
211 a[href^="javascript:"]:after {
212 content: "";
213 }
214 pre,
215 blockquote {
216 border: 1px solid #999;
217 page-break-inside: avoid;
218 }
219 thead {
220 display: table-header-group;
221 }
222 tr,
223 img {
224 page-break-inside: avoid;
225 }
226 img {
227 max-width: 100% !important;
228 }
229 p,
230 h2,
231 h3 {
232 orphans: 3;
233 widows: 3;
234 }
235 h2,
236 h3 {
237 page-break-after: avoid;
238 }
239 .navbar {
240 display: none;
241 }
242 .btn > .caret,
243 .dropup > .btn > .caret {
244 border-top-color: #000 !important;
245 }
246 .label {
247 border: 1px solid #000;
248 }
249 .table {
250 border-collapse: collapse !important;
251 }
252 .table td,
253 .table th {
254 background-color: #fff !important;
255 }
256 .table-bordered th,
257 .table-bordered td {
258 border: 1px solid #ddd !important;
259 }
260 }
261 @font-face {
262 font-family: 'Glyphicons Halflings';
263 src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot');
264 src: url('../components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
265 }
266 .glyphicon {
267 position: relative;
268 top: 1px;
269 display: inline-block;
270 font-family: 'Glyphicons Halflings';
271 font-style: normal;
272 font-weight: normal;
273 line-height: 1;
274 -webkit-font-smoothing: antialiased;
275 -moz-osx-font-smoothing: grayscale;
276 }
277 .glyphicon-asterisk:before {
278 content: "\002a";
279 }
280 .glyphicon-plus:before {
281 content: "\002b";
282 }
283 .glyphicon-euro:before,
284 .glyphicon-eur:before {
285 content: "\20ac";
286 }
287 .glyphicon-minus:before {
288 content: "\2212";
289 }
290 .glyphicon-cloud:before {
291 content: "\2601";
292 }
293 .glyphicon-envelope:before {
294 content: "\2709";
295 }
296 .glyphicon-pencil:before {
297 content: "\270f";
298 }
299 .glyphicon-glass:before {
300 content: "\e001";
301 }
302 .glyphicon-music:before {
303 content: "\e002";
304 }
305 .glyphicon-search:before {
306 content: "\e003";
307 }
308 .glyphicon-heart:before {
309 content: "\e005";
310 }
311 .glyphicon-star:before {
312 content: "\e006";
313 }
314 .glyphicon-star-empty:before {
315 content: "\e007";
316 }
317 .glyphicon-user:before {
318 content: "\e008";
319 }
320 .glyphicon-film:before {
321 content: "\e009";
322 }
323 .glyphicon-th-large:before {
324 content: "\e010";
325 }
326 .glyphicon-th:before {
327 content: "\e011";
328 }
329 .glyphicon-th-list:before {
330 content: "\e012";
331 }
332 .glyphicon-ok:before {
333 content: "\e013";
334 }
335 .glyphicon-remove:before {
336 content: "\e014";
337 }
338 .glyphicon-zoom-in:before {
339 content: "\e015";
340 }
341 .glyphicon-zoom-out:before {
342 content: "\e016";
343 }
344 .glyphicon-off:before {
345 content: "\e017";
346 }
347 .glyphicon-signal:before {
348 content: "\e018";
349 }
350 .glyphicon-cog:before {
351 content: "\e019";
352 }
353 .glyphicon-trash:before {
354 content: "\e020";
355 }
356 .glyphicon-home:before {
357 content: "\e021";
358 }
359 .glyphicon-file:before {
360 content: "\e022";
361 }
362 .glyphicon-time:before {
363 content: "\e023";
364 }
365 .glyphicon-road:before {
366 content: "\e024";
367 }
368 .glyphicon-download-alt:before {
369 content: "\e025";
370 }
371 .glyphicon-download:before {
372 content: "\e026";
373 }
374 .glyphicon-upload:before {
375 content: "\e027";
376 }
377 .glyphicon-inbox:before {
378 content: "\e028";
379 }
380 .glyphicon-play-circle:before {
381 content: "\e029";
382 }
383 .glyphicon-repeat:before {
384 content: "\e030";
385 }
386 .glyphicon-refresh:before {
387 content: "\e031";
388 }
389 .glyphicon-list-alt:before {
390 content: "\e032";
391 }
392 .glyphicon-lock:before {
393 content: "\e033";
394 }
395 .glyphicon-flag:before {
396 content: "\e034";
397 }
398 .glyphicon-headphones:before {
399 content: "\e035";
400 }
401 .glyphicon-volume-off:before {
402 content: "\e036";
403 }
404 .glyphicon-volume-down:before {
405 content: "\e037";
406 }
407 .glyphicon-volume-up:before {
408 content: "\e038";
409 }
410 .glyphicon-qrcode:before {
411 content: "\e039";
412 }
413 .glyphicon-barcode:before {
414 content: "\e040";
415 }
416 .glyphicon-tag:before {
417 content: "\e041";
418 }
419 .glyphicon-tags:before {
420 content: "\e042";
421 }
422 .glyphicon-book:before {
423 content: "\e043";
424 }
425 .glyphicon-bookmark:before {
426 content: "\e044";
427 }
428 .glyphicon-print:before {
429 content: "\e045";
430 }
431 .glyphicon-camera:before {
432 content: "\e046";
433 }
434 .glyphicon-font:before {
435 content: "\e047";
436 }
437 .glyphicon-bold:before {
438 content: "\e048";
439 }
440 .glyphicon-italic:before {
441 content: "\e049";
442 }
443 .glyphicon-text-height:before {
444 content: "\e050";
445 }
446 .glyphicon-text-width:before {
447 content: "\e051";
448 }
449 .glyphicon-align-left:before {
450 content: "\e052";
451 }
452 .glyphicon-align-center:before {
453 content: "\e053";
454 }
455 .glyphicon-align-right:before {
456 content: "\e054";
457 }
458 .glyphicon-align-justify:before {
459 content: "\e055";
460 }
461 .glyphicon-list:before {
462 content: "\e056";
463 }
464 .glyphicon-indent-left:before {
465 content: "\e057";
466 }
467 .glyphicon-indent-right:before {
468 content: "\e058";
469 }
470 .glyphicon-facetime-video:before {
471 content: "\e059";
472 }
473 .glyphicon-picture:before {
474 content: "\e060";
475 }
476 .glyphicon-map-marker:before {
477 content: "\e062";
478 }
479 .glyphicon-adjust:before {
480 content: "\e063";
481 }
482 .glyphicon-tint:before {
483 content: "\e064";
484 }
485 .glyphicon-edit:before {
486 content: "\e065";
487 }
488 .glyphicon-share:before {
489 content: "\e066";
490 }
491 .glyphicon-check:before {
492 content: "\e067";
493 }
494 .glyphicon-move:before {
495 content: "\e068";
496 }
497 .glyphicon-step-backward:before {
498 content: "\e069";
499 }
500 .glyphicon-fast-backward:before {
501 content: "\e070";
502 }
503 .glyphicon-backward:before {
504 content: "\e071";
505 }
506 .glyphicon-play:before {
507 content: "\e072";
508 }
509 .glyphicon-pause:before {
510 content: "\e073";
511 }
512 .glyphicon-stop:before {
513 content: "\e074";
514 }
515 .glyphicon-forward:before {
516 content: "\e075";
517 }
518 .glyphicon-fast-forward:before {
519 content: "\e076";
520 }
521 .glyphicon-step-forward:before {
522 content: "\e077";
523 }
524 .glyphicon-eject:before {
525 content: "\e078";
526 }
527 .glyphicon-chevron-left:before {
528 content: "\e079";
529 }
530 .glyphicon-chevron-right:before {
531 content: "\e080";
532 }
533 .glyphicon-plus-sign:before {
534 content: "\e081";
535 }
536 .glyphicon-minus-sign:before {
537 content: "\e082";
538 }
539 .glyphicon-remove-sign:before {
540 content: "\e083";
541 }
542 .glyphicon-ok-sign:before {
543 content: "\e084";
544 }
545 .glyphicon-question-sign:before {
546 content: "\e085";
547 }
548 .glyphicon-info-sign:before {
549 content: "\e086";
550 }
551 .glyphicon-screenshot:before {
552 content: "\e087";
553 }
554 .glyphicon-remove-circle:before {
555 content: "\e088";
556 }
557 .glyphicon-ok-circle:before {
558 content: "\e089";
559 }
560 .glyphicon-ban-circle:before {
561 content: "\e090";
562 }
563 .glyphicon-arrow-left:before {
564 content: "\e091";
565 }
566 .glyphicon-arrow-right:before {
567 content: "\e092";
568 }
569 .glyphicon-arrow-up:before {
570 content: "\e093";
571 }
572 .glyphicon-arrow-down:before {
573 content: "\e094";
574 }
575 .glyphicon-share-alt:before {
576 content: "\e095";
577 }
578 .glyphicon-resize-full:before {
579 content: "\e096";
580 }
581 .glyphicon-resize-small:before {
582 content: "\e097";
583 }
584 .glyphicon-exclamation-sign:before {
585 content: "\e101";
586 }
587 .glyphicon-gift:before {
588 content: "\e102";
589 }
590 .glyphicon-leaf:before {
591 content: "\e103";
592 }
593 .glyphicon-fire:before {
594 content: "\e104";
595 }
596 .glyphicon-eye-open:before {
597 content: "\e105";
598 }
599 .glyphicon-eye-close:before {
600 content: "\e106";
601 }
602 .glyphicon-warning-sign:before {
603 content: "\e107";
604 }
605 .glyphicon-plane:before {
606 content: "\e108";
607 }
608 .glyphicon-calendar:before {
609 content: "\e109";
610 }
611 .glyphicon-random:before {
612 content: "\e110";
613 }
614 .glyphicon-comment:before {
615 content: "\e111";
616 }
617 .glyphicon-magnet:before {
618 content: "\e112";
619 }
620 .glyphicon-chevron-up:before {
621 content: "\e113";
622 }
623 .glyphicon-chevron-down:before {
624 content: "\e114";
625 }
626 .glyphicon-retweet:before {
627 content: "\e115";
628 }
629 .glyphicon-shopping-cart:before {
630 content: "\e116";
631 }
632 .glyphicon-folder-close:before {
633 content: "\e117";
634 }
635 .glyphicon-folder-open:before {
636 content: "\e118";
637 }
638 .glyphicon-resize-vertical:before {
639 content: "\e119";
640 }
641 .glyphicon-resize-horizontal:before {
642 content: "\e120";
643 }
644 .glyphicon-hdd:before {
645 content: "\e121";
646 }
647 .glyphicon-bullhorn:before {
648 content: "\e122";
649 }
650 .glyphicon-bell:before {
651 content: "\e123";
652 }
653 .glyphicon-certificate:before {
654 content: "\e124";
655 }
656 .glyphicon-thumbs-up:before {
657 content: "\e125";
658 }
659 .glyphicon-thumbs-down:before {
660 content: "\e126";
661 }
662 .glyphicon-hand-right:before {
663 content: "\e127";
664 }
665 .glyphicon-hand-left:before {
666 content: "\e128";
667 }
668 .glyphicon-hand-up:before {
669 content: "\e129";
670 }
671 .glyphicon-hand-down:before {
672 content: "\e130";
673 }
674 .glyphicon-circle-arrow-right:before {
675 content: "\e131";
676 }
677 .glyphicon-circle-arrow-left:before {
678 content: "\e132";
679 }
680 .glyphicon-circle-arrow-up:before {
681 content: "\e133";
682 }
683 .glyphicon-circle-arrow-down:before {
684 content: "\e134";
685 }
686 .glyphicon-globe:before {
687 content: "\e135";
688 }
689 .glyphicon-wrench:before {
690 content: "\e136";
691 }
692 .glyphicon-tasks:before {
693 content: "\e137";
694 }
695 .glyphicon-filter:before {
696 content: "\e138";
697 }
698 .glyphicon-briefcase:before {
699 content: "\e139";
700 }
701 .glyphicon-fullscreen:before {
702 content: "\e140";
703 }
704 .glyphicon-dashboard:before {
705 content: "\e141";
706 }
707 .glyphicon-paperclip:before {
708 content: "\e142";
709 }
710 .glyphicon-heart-empty:before {
711 content: "\e143";
712 }
713 .glyphicon-link:before {
714 content: "\e144";
715 }
716 .glyphicon-phone:before {
717 content: "\e145";
718 }
719 .glyphicon-pushpin:before {
720 content: "\e146";
721 }
722 .glyphicon-usd:before {
723 content: "\e148";
724 }
725 .glyphicon-gbp:before {
726 content: "\e149";
727 }
728 .glyphicon-sort:before {
729 content: "\e150";
730 }
731 .glyphicon-sort-by-alphabet:before {
732 content: "\e151";
733 }
734 .glyphicon-sort-by-alphabet-alt:before {
735 content: "\e152";
736 }
737 .glyphicon-sort-by-order:before {
738 content: "\e153";
739 }
740 .glyphicon-sort-by-order-alt:before {
741 content: "\e154";
742 }
743 .glyphicon-sort-by-attributes:before {
744 content: "\e155";
745 }
746 .glyphicon-sort-by-attributes-alt:before {
747 content: "\e156";
748 }
749 .glyphicon-unchecked:before {
750 content: "\e157";
751 }
752 .glyphicon-expand:before {
753 content: "\e158";
754 }
755 .glyphicon-collapse-down:before {
756 content: "\e159";
757 }
758 .glyphicon-collapse-up:before {
759 content: "\e160";
760 }
761 .glyphicon-log-in:before {
762 content: "\e161";
763 }
764 .glyphicon-flash:before {
765 content: "\e162";
766 }
767 .glyphicon-log-out:before {
768 content: "\e163";
769 }
770 .glyphicon-new-window:before {
771 content: "\e164";
772 }
773 .glyphicon-record:before {
774 content: "\e165";
775 }
776 .glyphicon-save:before {
777 content: "\e166";
778 }
779 .glyphicon-open:before {
780 content: "\e167";
781 }
782 .glyphicon-saved:before {
783 content: "\e168";
784 }
785 .glyphicon-import:before {
786 content: "\e169";
787 }
788 .glyphicon-export:before {
789 content: "\e170";
790 }
791 .glyphicon-send:before {
792 content: "\e171";
793 }
794 .glyphicon-floppy-disk:before {
795 content: "\e172";
796 }
797 .glyphicon-floppy-saved:before {
798 content: "\e173";
799 }
800 .glyphicon-floppy-remove:before {
801 content: "\e174";
802 }
803 .glyphicon-floppy-save:before {
804 content: "\e175";
805 }
806 .glyphicon-floppy-open:before {
807 content: "\e176";
808 }
809 .glyphicon-credit-card:before {
810 content: "\e177";
811 }
812 .glyphicon-transfer:before {
813 content: "\e178";
814 }
815 .glyphicon-cutlery:before {
816 content: "\e179";
817 }
818 .glyphicon-header:before {
819 content: "\e180";
820 }
821 .glyphicon-compressed:before {
822 content: "\e181";
823 }
824 .glyphicon-earphone:before {
825 content: "\e182";
826 }
827 .glyphicon-phone-alt:before {
828 content: "\e183";
829 }
830 .glyphicon-tower:before {
831 content: "\e184";
832 }
833 .glyphicon-stats:before {
834 content: "\e185";
835 }
836 .glyphicon-sd-video:before {
837 content: "\e186";
838 }
839 .glyphicon-hd-video:before {
840 content: "\e187";
841 }
842 .glyphicon-subtitles:before {
843 content: "\e188";
844 }
845 .glyphicon-sound-stereo:before {
846 content: "\e189";
847 }
848 .glyphicon-sound-dolby:before {
849 content: "\e190";
850 }
851 .glyphicon-sound-5-1:before {
852 content: "\e191";
853 }
854 .glyphicon-sound-6-1:before {
855 content: "\e192";
856 }
857 .glyphicon-sound-7-1:before {
858 content: "\e193";
859 }
860 .glyphicon-copyright-mark:before {
861 content: "\e194";
862 }
863 .glyphicon-registration-mark:before {
864 content: "\e195";
865 }
866 .glyphicon-cloud-download:before {
867 content: "\e197";
868 }
869 .glyphicon-cloud-upload:before {
870 content: "\e198";
871 }
872 .glyphicon-tree-conifer:before {
873 content: "\e199";
874 }
875 .glyphicon-tree-deciduous:before {
876 content: "\e200";
877 }
878 .glyphicon-cd:before {
879 content: "\e201";
880 }
881 .glyphicon-save-file:before {
882 content: "\e202";
883 }
884 .glyphicon-open-file:before {
885 content: "\e203";
886 }
887 .glyphicon-level-up:before {
888 content: "\e204";
889 }
890 .glyphicon-copy:before {
891 content: "\e205";
892 }
893 .glyphicon-paste:before {
894 content: "\e206";
895 }
896 .glyphicon-alert:before {
897 content: "\e209";
898 }
899 .glyphicon-equalizer:before {
900 content: "\e210";
901 }
902 .glyphicon-king:before {
903 content: "\e211";
904 }
905 .glyphicon-queen:before {
906 content: "\e212";
907 }
908 .glyphicon-pawn:before {
909 content: "\e213";
910 }
911 .glyphicon-bishop:before {
912 content: "\e214";
913 }
914 .glyphicon-knight:before {
915 content: "\e215";
916 }
917 .glyphicon-baby-formula:before {
918 content: "\e216";
919 }
920 .glyphicon-tent:before {
921 content: "\26fa";
922 }
923 .glyphicon-blackboard:before {
924 content: "\e218";
925 }
926 .glyphicon-bed:before {
927 content: "\e219";
928 }
929 .glyphicon-apple:before {
930 content: "\f8ff";
931 }
932 .glyphicon-erase:before {
933 content: "\e221";
934 }
935 .glyphicon-hourglass:before {
936 content: "\231b";
937 }
938 .glyphicon-lamp:before {
939 content: "\e223";
940 }
941 .glyphicon-duplicate:before {
942 content: "\e224";
943 }
944 .glyphicon-piggy-bank:before {
945 content: "\e225";
946 }
947 .glyphicon-scissors:before {
948 content: "\e226";
949 }
950 .glyphicon-bitcoin:before {
951 content: "\e227";
952 }
953 .glyphicon-btc:before {
954 content: "\e227";
955 }
956 .glyphicon-xbt:before {
957 content: "\e227";
958 }
959 .glyphicon-yen:before {
960 content: "\00a5";
961 }
962 .glyphicon-jpy:before {
963 content: "\00a5";
964 }
965 .glyphicon-ruble:before {
966 content: "\20bd";
967 }
968 .glyphicon-rub:before {
969 content: "\20bd";
970 }
971 .glyphicon-scale:before {
972 content: "\e230";
973 }
974 .glyphicon-ice-lolly:before {
975 content: "\e231";
976 }
977 .glyphicon-ice-lolly-tasted:before {
978 content: "\e232";
979 }
980 .glyphicon-education:before {
981 content: "\e233";
982 }
983 .glyphicon-option-horizontal:before {
984 content: "\e234";
985 }
986 .glyphicon-option-vertical:before {
987 content: "\e235";
988 }
989 .glyphicon-menu-hamburger:before {
990 content: "\e236";
991 }
992 .glyphicon-modal-window:before {
993 content: "\e237";
994 }
995 .glyphicon-oil:before {
996 content: "\e238";
997 }
998 .glyphicon-grain:before {
999 content: "\e239";
1000 }
1001 .glyphicon-sunglasses:before {
1002 content: "\e240";
1003 }
1004 .glyphicon-text-size:before {
1005 content: "\e241";
1006 }
1007 .glyphicon-text-color:before {
1008 content: "\e242";
1009 }
1010 .glyphicon-text-background:before {
1011 content: "\e243";
1012 }
1013 .glyphicon-object-align-top:before {
1014 content: "\e244";
1015 }
1016 .glyphicon-object-align-bottom:before {
1017 content: "\e245";
1018 }
1019 .glyphicon-object-align-horizontal:before {
1020 content: "\e246";
1021 }
1022 .glyphicon-object-align-left:before {
1023 content: "\e247";
1024 }
1025 .glyphicon-object-align-vertical:before {
1026 content: "\e248";
1027 }
1028 .glyphicon-object-align-right:before {
1029 content: "\e249";
1030 }
1031 .glyphicon-triangle-right:before {
1032 content: "\e250";
1033 }
1034 .glyphicon-triangle-left:before {
1035 content: "\e251";
1036 }
1037 .glyphicon-triangle-bottom:before {
1038 content: "\e252";
1039 }
1040 .glyphicon-triangle-top:before {
1041 content: "\e253";
1042 }
1043 .glyphicon-console:before {
1044 content: "\e254";
1045 }
1046 .glyphicon-superscript:before {
1047 content: "\e255";
1048 }
1049 .glyphicon-subscript:before {
1050 content: "\e256";
1051 }
1052 .glyphicon-menu-left:before {
1053 content: "\e257";
1054 }
1055 .glyphicon-menu-right:before {
1056 content: "\e258";
1057 }
1058 .glyphicon-menu-down:before {
1059 content: "\e259";
1060 }
1061 .glyphicon-menu-up:before {
1062 content: "\e260";
1063 }
1064 * {
1065 -webkit-box-sizing: border-box;
1066 -moz-box-sizing: border-box;
1067 box-sizing: border-box;
1068 }
1069 *:before,
1070 *:after {
1071 -webkit-box-sizing: border-box;
1072 -moz-box-sizing: border-box;
1073 box-sizing: border-box;
1074 }
1075 html {
1076 font-size: 10px;
1077 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
1078 }
1079 body {
1080 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1081 font-size: 13px;
1082 line-height: 1.42857143;
1083 color: #000;
1084 background-color: #fff;
1085 }
1086 input,
1087 button,
1088 select,
1089 textarea {
1090 font-family: inherit;
1091 font-size: inherit;
1092 line-height: inherit;
1093 }
1094 a {
1095 color: #337ab7;
1096 text-decoration: none;
1097 }
1098 a:hover,
1099 a:focus {
1100 color: #23527c;
1101 text-decoration: underline;
1102 }
1103 a:focus {
1104 outline: 5px auto -webkit-focus-ring-color;
1105 outline-offset: -2px;
1106 }
1107 figure {
1108 margin: 0;
1109 }
1110 img {
1111 vertical-align: middle;
1112 }
1113 .img-responsive,
1114 .thumbnail > img,
1115 .thumbnail a > img,
1116 .carousel-inner > .item > img,
1117 .carousel-inner > .item > a > img {
1118 display: block;
1119 max-width: 100%;
1120 height: auto;
1121 }
1122 .img-rounded {
1123 border-radius: 3px;
1124 }
1125 .img-thumbnail {
1126 padding: 4px;
1127 line-height: 1.42857143;
1128 background-color: #fff;
1129 border: 1px solid #ddd;
1130 border-radius: 2px;
1131 -webkit-transition: all 0.2s ease-in-out;
1132 -o-transition: all 0.2s ease-in-out;
1133 transition: all 0.2s ease-in-out;
1134 display: inline-block;
1135 max-width: 100%;
1136 height: auto;
1137 }
1138 .img-circle {
1139 border-radius: 50%;
1140 }
1141 hr {
1142 margin-top: 18px;
1143 margin-bottom: 18px;
1144 border: 0;
1145 border-top: 1px solid #eeeeee;
1146 }
1147 .sr-only {
1148 position: absolute;
1149 width: 1px;
1150 height: 1px;
1151 margin: -1px;
1152 padding: 0;
1153 overflow: hidden;
1154 clip: rect(0, 0, 0, 0);
1155 border: 0;
1156 }
1157 .sr-only-focusable:active,
1158 .sr-only-focusable:focus {
1159 position: static;
1160 width: auto;
1161 height: auto;
1162 margin: 0;
1163 overflow: visible;
1164 clip: auto;
1165 }
1166 [role="button"] {
1167 cursor: pointer;
1168 }
1169 h1,
1170 h2,
1171 h3,
1172 h4,
1173 h5,
1174 h6,
1175 .h1,
1176 .h2,
1177 .h3,
1178 .h4,
1179 .h5,
1180 .h6 {
1181 font-family: inherit;
1182 font-weight: 500;
1183 line-height: 1.1;
1184 color: inherit;
1185 }
1186 h1 small,
1187 h2 small,
1188 h3 small,
1189 h4 small,
1190 h5 small,
1191 h6 small,
1192 .h1 small,
1193 .h2 small,
1194 .h3 small,
1195 .h4 small,
1196 .h5 small,
1197 .h6 small,
1198 h1 .small,
1199 h2 .small,
1200 h3 .small,
1201 h4 .small,
1202 h5 .small,
1203 h6 .small,
1204 .h1 .small,
1205 .h2 .small,
1206 .h3 .small,
1207 .h4 .small,
1208 .h5 .small,
1209 .h6 .small {
1210 font-weight: normal;
1211 line-height: 1;
1212 color: #777777;
1213 }
1214 h1,
1215 .h1,
1216 h2,
1217 .h2,
1218 h3,
1219 .h3 {
1220 margin-top: 18px;
1221 margin-bottom: 9px;
1222 }
1223 h1 small,
1224 .h1 small,
1225 h2 small,
1226 .h2 small,
1227 h3 small,
1228 .h3 small,
1229 h1 .small,
1230 .h1 .small,
1231 h2 .small,
1232 .h2 .small,
1233 h3 .small,
1234 .h3 .small {
1235 font-size: 65%;
1236 }
1237 h4,
1238 .h4,
1239 h5,
1240 .h5,
1241 h6,
1242 .h6 {
1243 margin-top: 9px;
1244 margin-bottom: 9px;
1245 }
1246 h4 small,
1247 .h4 small,
1248 h5 small,
1249 .h5 small,
1250 h6 small,
1251 .h6 small,
1252 h4 .small,
1253 .h4 .small,
1254 h5 .small,
1255 .h5 .small,
1256 h6 .small,
1257 .h6 .small {
1258 font-size: 75%;
1259 }
1260 h1,
1261 .h1 {
1262 font-size: 33px;
1263 }
1264 h2,
1265 .h2 {
1266 font-size: 27px;
1267 }
1268 h3,
1269 .h3 {
1270 font-size: 23px;
1271 }
1272 h4,
1273 .h4 {
1274 font-size: 17px;
1275 }
1276 h5,
1277 .h5 {
1278 font-size: 13px;
1279 }
1280 h6,
1281 .h6 {
1282 font-size: 12px;
1283 }
1284 p {
1285 margin: 0 0 9px;
1286 }
1287 .lead {
1288 margin-bottom: 18px;
1289 font-size: 14px;
1290 font-weight: 300;
1291 line-height: 1.4;
1292 }
1293 @media (min-width: 768px) {
1294 .lead {
1295 font-size: 19.5px;
1296 }
1297 }
1298 small,
1299 .small {
1300 font-size: 92%;
1301 }
1302 mark,
1303 .mark {
1304 background-color: #fcf8e3;
1305 padding: .2em;
1306 }
1307 .text-left {
1308 text-align: left;
1309 }
1310 .text-right {
1311 text-align: right;
1312 }
1313 .text-center {
1314 text-align: center;
1315 }
1316 .text-justify {
1317 text-align: justify;
1318 }
1319 .text-nowrap {
1320 white-space: nowrap;
1321 }
1322 .text-lowercase {
1323 text-transform: lowercase;
1324 }
1325 .text-uppercase {
1326 text-transform: uppercase;
1327 }
1328 .text-capitalize {
1329 text-transform: capitalize;
1330 }
1331 .text-muted {
1332 color: #777777;
1333 }
1334 .text-primary {
1335 color: #337ab7;
1336 }
1337 a.text-primary:hover,
1338 a.text-primary:focus {
1339 color: #286090;
1340 }
1341 .text-success {
1342 color: #3c763d;
1343 }
1344 a.text-success:hover,
1345 a.text-success:focus {
1346 color: #2b542c;
1347 }
1348 .text-info {
1349 color: #31708f;
1350 }
1351 a.text-info:hover,
1352 a.text-info:focus {
1353 color: #245269;
1354 }
1355 .text-warning {
1356 color: #8a6d3b;
1357 }
1358 a.text-warning:hover,
1359 a.text-warning:focus {
1360 color: #66512c;
1361 }
1362 .text-danger {
1363 color: #a94442;
1364 }
1365 a.text-danger:hover,
1366 a.text-danger:focus {
1367 color: #843534;
1368 }
1369 .bg-primary {
1370 color: #fff;
1371 background-color: #337ab7;
1372 }
1373 a.bg-primary:hover,
1374 a.bg-primary:focus {
1375 background-color: #286090;
1376 }
1377 .bg-success {
1378 background-color: #dff0d8;
1379 }
1380 a.bg-success:hover,
1381 a.bg-success:focus {
1382 background-color: #c1e2b3;
1383 }
1384 .bg-info {
1385 background-color: #d9edf7;
1386 }
1387 a.bg-info:hover,
1388 a.bg-info:focus {
1389 background-color: #afd9ee;
1390 }
1391 .bg-warning {
1392 background-color: #fcf8e3;
1393 }
1394 a.bg-warning:hover,
1395 a.bg-warning:focus {
1396 background-color: #f7ecb5;
1397 }
1398 .bg-danger {
1399 background-color: #f2dede;
1400 }
1401 a.bg-danger:hover,
1402 a.bg-danger:focus {
1403 background-color: #e4b9b9;
1404 }
1405 .page-header {
1406 padding-bottom: 8px;
1407 margin: 36px 0 18px;
1408 border-bottom: 1px solid #eeeeee;
1409 }
1410 ul,
1411 ol {
1412 margin-top: 0;
1413 margin-bottom: 9px;
1414 }
1415 ul ul,
1416 ol ul,
1417 ul ol,
1418 ol ol {
1419 margin-bottom: 0;
1420 }
1421 .list-unstyled {
1422 padding-left: 0;
1423 list-style: none;
1424 }
1425 .list-inline {
1426 padding-left: 0;
1427 list-style: none;
1428 margin-left: -5px;
1429 }
1430 .list-inline > li {
1431 display: inline-block;
1432 padding-left: 5px;
1433 padding-right: 5px;
1434 }
1435 dl {
1436 margin-top: 0;
1437 margin-bottom: 18px;
1438 }
1439 dt,
1440 dd {
1441 line-height: 1.42857143;
1442 }
1443 dt {
1444 font-weight: bold;
1445 }
1446 dd {
1447 margin-left: 0;
1448 }
1449 @media (min-width: 541px) {
1450 .dl-horizontal dt {
1451 float: left;
1452 width: 160px;
1453 clear: left;
1454 text-align: right;
1455 overflow: hidden;
1456 text-overflow: ellipsis;
1457 white-space: nowrap;
1458 }
1459 .dl-horizontal dd {
1460 margin-left: 180px;
1461 }
1462 }
1463 abbr[title],
1464 abbr[data-original-title] {
1465 cursor: help;
1466 border-bottom: 1px dotted #777777;
1467 }
1468 .initialism {
1469 font-size: 90%;
1470 text-transform: uppercase;
1471 }
1472 blockquote {
1473 padding: 9px 18px;
1474 margin: 0 0 18px;
1475 font-size: inherit;
1476 border-left: 5px solid #eeeeee;
1477 }
1478 blockquote p:last-child,
1479 blockquote ul:last-child,
1480 blockquote ol:last-child {
1481 margin-bottom: 0;
1482 }
1483 blockquote footer,
1484 blockquote small,
1485 blockquote .small {
1486 display: block;
1487 font-size: 80%;
1488 line-height: 1.42857143;
1489 color: #777777;
1490 }
1491 blockquote footer:before,
1492 blockquote small:before,
1493 blockquote .small:before {
1494 content: '\2014 \00A0';
1495 }
1496 .blockquote-reverse,
1497 blockquote.pull-right {
1498 padding-right: 15px;
1499 padding-left: 0;
1500 border-right: 5px solid #eeeeee;
1501 border-left: 0;
1502 text-align: right;
1503 }
1504 .blockquote-reverse footer:before,
1505 blockquote.pull-right footer:before,
1506 .blockquote-reverse small:before,
1507 blockquote.pull-right small:before,
1508 .blockquote-reverse .small:before,
1509 blockquote.pull-right .small:before {
1510 content: '';
1511 }
1512 .blockquote-reverse footer:after,
1513 blockquote.pull-right footer:after,
1514 .blockquote-reverse small:after,
1515 blockquote.pull-right small:after,
1516 .blockquote-reverse .small:after,
1517 blockquote.pull-right .small:after {
1518 content: '\00A0 \2014';
1519 }
1520 address {
1521 margin-bottom: 18px;
1522 font-style: normal;
1523 line-height: 1.42857143;
1524 }
1525 code,
1526 kbd,
1527 pre,
1528 samp {
1529 font-family: monospace;
1530 }
1531 code {
1532 padding: 2px 4px;
1533 font-size: 90%;
1534 color: #c7254e;
1535 background-color: #f9f2f4;
1536 border-radius: 2px;
1537 }
1538 kbd {
1539 padding: 2px 4px;
1540 font-size: 90%;
1541 color: #888;
1542 background-color: transparent;
1543 border-radius: 1px;
1544 box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
1545 }
1546 kbd kbd {
1547 padding: 0;
1548 font-size: 100%;
1549 font-weight: bold;
1550 box-shadow: none;
1551 }
1552 pre {
1553 display: block;
1554 padding: 8.5px;
1555 margin: 0 0 9px;
1556 font-size: 12px;
1557 line-height: 1.42857143;
1558 word-break: break-all;
1559 word-wrap: break-word;
1560 color: #333333;
1561 background-color: #f5f5f5;
1562 border: 1px solid #ccc;
1563 border-radius: 2px;
1564 }
1565 pre code {
1566 padding: 0;
1567 font-size: inherit;
1568 color: inherit;
1569 white-space: pre-wrap;
1570 background-color: transparent;
1571 border-radius: 0;
1572 }
1573 .pre-scrollable {
1574 max-height: 340px;
1575 overflow-y: scroll;
1576 }
1577 .container {
1578 margin-right: auto;
1579 margin-left: auto;
1580 padding-left: 0px;
1581 padding-right: 0px;
1582 }
1583 @media (min-width: 768px) {
1584 .container {
1585 width: 768px;
1586 }
1587 }
1588 @media (min-width: 992px) {
1589 .container {
1590 width: 940px;
1591 }
1592 }
1593 @media (min-width: 1200px) {
1594 .container {
1595 width: 1140px;
1596 }
1597 }
1598 .container-fluid {
1599 margin-right: auto;
1600 margin-left: auto;
1601 padding-left: 0px;
1602 padding-right: 0px;
1603 }
1604 .row {
1605 margin-left: 0px;
1606 margin-right: 0px;
1607 }
1608 .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
1609 position: relative;
1610 min-height: 1px;
1611 padding-left: 0px;
1612 padding-right: 0px;
1613 }
1614 .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
1615 float: left;
1616 }
1617 .col-xs-12 {
1618 width: 100%;
1619 }
1620 .col-xs-11 {
1621 width: 91.66666667%;
1622 }
1623 .col-xs-10 {
1624 width: 83.33333333%;
1625 }
1626 .col-xs-9 {
1627 width: 75%;
1628 }
1629 .col-xs-8 {
1630 width: 66.66666667%;
1631 }
1632 .col-xs-7 {
1633 width: 58.33333333%;
1634 }
1635 .col-xs-6 {
1636 width: 50%;
1637 }
1638 .col-xs-5 {
1639 width: 41.66666667%;
1640 }
1641 .col-xs-4 {
1642 width: 33.33333333%;
1643 }
1644 .col-xs-3 {
1645 width: 25%;
1646 }
1647 .col-xs-2 {
1648 width: 16.66666667%;
1649 }
1650 .col-xs-1 {
1651 width: 8.33333333%;
1652 }
1653 .col-xs-pull-12 {
1654 right: 100%;
1655 }
1656 .col-xs-pull-11 {
1657 right: 91.66666667%;
1658 }
1659 .col-xs-pull-10 {
1660 right: 83.33333333%;
1661 }
1662 .col-xs-pull-9 {
1663 right: 75%;
1664 }
1665 .col-xs-pull-8 {
1666 right: 66.66666667%;
1667 }
1668 .col-xs-pull-7 {
1669 right: 58.33333333%;
1670 }
1671 .col-xs-pull-6 {
1672 right: 50%;
1673 }
1674 .col-xs-pull-5 {
1675 right: 41.66666667%;
1676 }
1677 .col-xs-pull-4 {
1678 right: 33.33333333%;
1679 }
1680 .col-xs-pull-3 {
1681 right: 25%;
1682 }
1683 .col-xs-pull-2 {
1684 right: 16.66666667%;
1685 }
1686 .col-xs-pull-1 {
1687 right: 8.33333333%;
1688 }
1689 .col-xs-pull-0 {
1690 right: auto;
1691 }
1692 .col-xs-push-12 {
1693 left: 100%;
1694 }
1695 .col-xs-push-11 {
1696 left: 91.66666667%;
1697 }
1698 .col-xs-push-10 {
1699 left: 83.33333333%;
1700 }
1701 .col-xs-push-9 {
1702 left: 75%;
1703 }
1704 .col-xs-push-8 {
1705 left: 66.66666667%;
1706 }
1707 .col-xs-push-7 {
1708 left: 58.33333333%;
1709 }
1710 .col-xs-push-6 {
1711 left: 50%;
1712 }
1713 .col-xs-push-5 {
1714 left: 41.66666667%;
1715 }
1716 .col-xs-push-4 {
1717 left: 33.33333333%;
1718 }
1719 .col-xs-push-3 {
1720 left: 25%;
1721 }
1722 .col-xs-push-2 {
1723 left: 16.66666667%;
1724 }
1725 .col-xs-push-1 {
1726 left: 8.33333333%;
1727 }
1728 .col-xs-push-0 {
1729 left: auto;
1730 }
1731 .col-xs-offset-12 {
1732 margin-left: 100%;
1733 }
1734 .col-xs-offset-11 {
1735 margin-left: 91.66666667%;
1736 }
1737 .col-xs-offset-10 {
1738 margin-left: 83.33333333%;
1739 }
1740 .col-xs-offset-9 {
1741 margin-left: 75%;
1742 }
1743 .col-xs-offset-8 {
1744 margin-left: 66.66666667%;
1745 }
1746 .col-xs-offset-7 {
1747 margin-left: 58.33333333%;
1748 }
1749 .col-xs-offset-6 {
1750 margin-left: 50%;
1751 }
1752 .col-xs-offset-5 {
1753 margin-left: 41.66666667%;
1754 }
1755 .col-xs-offset-4 {
1756 margin-left: 33.33333333%;
1757 }
1758 .col-xs-offset-3 {
1759 margin-left: 25%;
1760 }
1761 .col-xs-offset-2 {
1762 margin-left: 16.66666667%;
1763 }
1764 .col-xs-offset-1 {
1765 margin-left: 8.33333333%;
1766 }
1767 .col-xs-offset-0 {
1768 margin-left: 0%;
1769 }
1770 @media (min-width: 768px) {
1771 .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
1772 float: left;
1773 }
1774 .col-sm-12 {
1775 width: 100%;
1776 }
1777 .col-sm-11 {
1778 width: 91.66666667%;
1779 }
1780 .col-sm-10 {
1781 width: 83.33333333%;
1782 }
1783 .col-sm-9 {
1784 width: 75%;
1785 }
1786 .col-sm-8 {
1787 width: 66.66666667%;
1788 }
1789 .col-sm-7 {
1790 width: 58.33333333%;
1791 }
1792 .col-sm-6 {
1793 width: 50%;
1794 }
1795 .col-sm-5 {
1796 width: 41.66666667%;
1797 }
1798 .col-sm-4 {
1799 width: 33.33333333%;
1800 }
1801 .col-sm-3 {
1802 width: 25%;
1803 }
1804 .col-sm-2 {
1805 width: 16.66666667%;
1806 }
1807 .col-sm-1 {
1808 width: 8.33333333%;
1809 }
1810 .col-sm-pull-12 {
1811 right: 100%;
1812 }
1813 .col-sm-pull-11 {
1814 right: 91.66666667%;
1815 }
1816 .col-sm-pull-10 {
1817 right: 83.33333333%;
1818 }
1819 .col-sm-pull-9 {
1820 right: 75%;
1821 }
1822 .col-sm-pull-8 {
1823 right: 66.66666667%;
1824 }
1825 .col-sm-pull-7 {
1826 right: 58.33333333%;
1827 }
1828 .col-sm-pull-6 {
1829 right: 50%;
1830 }
1831 .col-sm-pull-5 {
1832 right: 41.66666667%;
1833 }
1834 .col-sm-pull-4 {
1835 right: 33.33333333%;
1836 }
1837 .col-sm-pull-3 {
1838 right: 25%;
1839 }
1840 .col-sm-pull-2 {
1841 right: 16.66666667%;
1842 }
1843 .col-sm-pull-1 {
1844 right: 8.33333333%;
1845 }
1846 .col-sm-pull-0 {
1847 right: auto;
1848 }
1849 .col-sm-push-12 {
1850 left: 100%;
1851 }
1852 .col-sm-push-11 {
1853 left: 91.66666667%;
1854 }
1855 .col-sm-push-10 {
1856 left: 83.33333333%;
1857 }
1858 .col-sm-push-9 {
1859 left: 75%;
1860 }
1861 .col-sm-push-8 {
1862 left: 66.66666667%;
1863 }
1864 .col-sm-push-7 {
1865 left: 58.33333333%;
1866 }
1867 .col-sm-push-6 {
1868 left: 50%;
1869 }
1870 .col-sm-push-5 {
1871 left: 41.66666667%;
1872 }
1873 .col-sm-push-4 {
1874 left: 33.33333333%;
1875 }
1876 .col-sm-push-3 {
1877 left: 25%;
1878 }
1879 .col-sm-push-2 {
1880 left: 16.66666667%;
1881 }
1882 .col-sm-push-1 {
1883 left: 8.33333333%;
1884 }
1885 .col-sm-push-0 {
1886 left: auto;
1887 }
1888 .col-sm-offset-12 {
1889 margin-left: 100%;
1890 }
1891 .col-sm-offset-11 {
1892 margin-left: 91.66666667%;
1893 }
1894 .col-sm-offset-10 {
1895 margin-left: 83.33333333%;
1896 }
1897 .col-sm-offset-9 {
1898 margin-left: 75%;
1899 }
1900 .col-sm-offset-8 {
1901 margin-left: 66.66666667%;
1902 }
1903 .col-sm-offset-7 {
1904 margin-left: 58.33333333%;
1905 }
1906 .col-sm-offset-6 {
1907 margin-left: 50%;
1908 }
1909 .col-sm-offset-5 {
1910 margin-left: 41.66666667%;
1911 }
1912 .col-sm-offset-4 {
1913 margin-left: 33.33333333%;
1914 }
1915 .col-sm-offset-3 {
1916 margin-left: 25%;
1917 }
1918 .col-sm-offset-2 {
1919 margin-left: 16.66666667%;
1920 }
1921 .col-sm-offset-1 {
1922 margin-left: 8.33333333%;
1923 }
1924 .col-sm-offset-0 {
1925 margin-left: 0%;
1926 }
1927 }
1928 @media (min-width: 992px) {
1929 .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
1930 float: left;
1931 }
1932 .col-md-12 {
1933 width: 100%;
1934 }
1935 .col-md-11 {
1936 width: 91.66666667%;
1937 }
1938 .col-md-10 {
1939 width: 83.33333333%;
1940 }
1941 .col-md-9 {
1942 width: 75%;
1943 }
1944 .col-md-8 {
1945 width: 66.66666667%;
1946 }
1947 .col-md-7 {
1948 width: 58.33333333%;
1949 }
1950 .col-md-6 {
1951 width: 50%;
1952 }
1953 .col-md-5 {
1954 width: 41.66666667%;
1955 }
1956 .col-md-4 {
1957 width: 33.33333333%;
1958 }
1959 .col-md-3 {
1960 width: 25%;
1961 }
1962 .col-md-2 {
1963 width: 16.66666667%;
1964 }
1965 .col-md-1 {
1966 width: 8.33333333%;
1967 }
1968 .col-md-pull-12 {
1969 right: 100%;
1970 }
1971 .col-md-pull-11 {
1972 right: 91.66666667%;
1973 }
1974 .col-md-pull-10 {
1975 right: 83.33333333%;
1976 }
1977 .col-md-pull-9 {
1978 right: 75%;
1979 }
1980 .col-md-pull-8 {
1981 right: 66.66666667%;
1982 }
1983 .col-md-pull-7 {
1984 right: 58.33333333%;
1985 }
1986 .col-md-pull-6 {
1987 right: 50%;
1988 }
1989 .col-md-pull-5 {
1990 right: 41.66666667%;
1991 }
1992 .col-md-pull-4 {
1993 right: 33.33333333%;
1994 }
1995 .col-md-pull-3 {
1996 right: 25%;
1997 }
1998 .col-md-pull-2 {
1999 right: 16.66666667%;
2000 }
2001 .col-md-pull-1 {
2002 right: 8.33333333%;
2003 }
2004 .col-md-pull-0 {
2005 right: auto;
2006 }
2007 .col-md-push-12 {
2008 left: 100%;
2009 }
2010 .col-md-push-11 {
2011 left: 91.66666667%;
2012 }
2013 .col-md-push-10 {
2014 left: 83.33333333%;
2015 }
2016 .col-md-push-9 {
2017 left: 75%;
2018 }
2019 .col-md-push-8 {
2020 left: 66.66666667%;
2021 }
2022 .col-md-push-7 {
2023 left: 58.33333333%;
2024 }
2025 .col-md-push-6 {
2026 left: 50%;
2027 }
2028 .col-md-push-5 {
2029 left: 41.66666667%;
2030 }
2031 .col-md-push-4 {
2032 left: 33.33333333%;
2033 }
2034 .col-md-push-3 {
2035 left: 25%;
2036 }
2037 .col-md-push-2 {
2038 left: 16.66666667%;
2039 }
2040 .col-md-push-1 {
2041 left: 8.33333333%;
2042 }
2043 .col-md-push-0 {
2044 left: auto;
2045 }
2046 .col-md-offset-12 {
2047 margin-left: 100%;
2048 }
2049 .col-md-offset-11 {
2050 margin-left: 91.66666667%;
2051 }
2052 .col-md-offset-10 {
2053 margin-left: 83.33333333%;
2054 }
2055 .col-md-offset-9 {
2056 margin-left: 75%;
2057 }
2058 .col-md-offset-8 {
2059 margin-left: 66.66666667%;
2060 }
2061 .col-md-offset-7 {
2062 margin-left: 58.33333333%;
2063 }
2064 .col-md-offset-6 {
2065 margin-left: 50%;
2066 }
2067 .col-md-offset-5 {
2068 margin-left: 41.66666667%;
2069 }
2070 .col-md-offset-4 {
2071 margin-left: 33.33333333%;
2072 }
2073 .col-md-offset-3 {
2074 margin-left: 25%;
2075 }
2076 .col-md-offset-2 {
2077 margin-left: 16.66666667%;
2078 }
2079 .col-md-offset-1 {
2080 margin-left: 8.33333333%;
2081 }
2082 .col-md-offset-0 {
2083 margin-left: 0%;
2084 }
2085 }
2086 @media (min-width: 1200px) {
2087 .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
2088 float: left;
2089 }
2090 .col-lg-12 {
2091 width: 100%;
2092 }
2093 .col-lg-11 {
2094 width: 91.66666667%;
2095 }
2096 .col-lg-10 {
2097 width: 83.33333333%;
2098 }
2099 .col-lg-9 {
2100 width: 75%;
2101 }
2102 .col-lg-8 {
2103 width: 66.66666667%;
2104 }
2105 .col-lg-7 {
2106 width: 58.33333333%;
2107 }
2108 .col-lg-6 {
2109 width: 50%;
2110 }
2111 .col-lg-5 {
2112 width: 41.66666667%;
2113 }
2114 .col-lg-4 {
2115 width: 33.33333333%;
2116 }
2117 .col-lg-3 {
2118 width: 25%;
2119 }
2120 .col-lg-2 {
2121 width: 16.66666667%;
2122 }
2123 .col-lg-1 {
2124 width: 8.33333333%;
2125 }
2126 .col-lg-pull-12 {
2127 right: 100%;
2128 }
2129 .col-lg-pull-11 {
2130 right: 91.66666667%;
2131 }
2132 .col-lg-pull-10 {
2133 right: 83.33333333%;
2134 }
2135 .col-lg-pull-9 {
2136 right: 75%;
2137 }
2138 .col-lg-pull-8 {
2139 right: 66.66666667%;
2140 }
2141 .col-lg-pull-7 {
2142 right: 58.33333333%;
2143 }
2144 .col-lg-pull-6 {
2145 right: 50%;
2146 }
2147 .col-lg-pull-5 {
2148 right: 41.66666667%;
2149 }
2150 .col-lg-pull-4 {
2151 right: 33.33333333%;
2152 }
2153 .col-lg-pull-3 {
2154 right: 25%;
2155 }
2156 .col-lg-pull-2 {
2157 right: 16.66666667%;
2158 }
2159 .col-lg-pull-1 {
2160 right: 8.33333333%;
2161 }
2162 .col-lg-pull-0 {
2163 right: auto;
2164 }
2165 .col-lg-push-12 {
2166 left: 100%;
2167 }
2168 .col-lg-push-11 {
2169 left: 91.66666667%;
2170 }
2171 .col-lg-push-10 {
2172 left: 83.33333333%;
2173 }
2174 .col-lg-push-9 {
2175 left: 75%;
2176 }
2177 .col-lg-push-8 {
2178 left: 66.66666667%;
2179 }
2180 .col-lg-push-7 {
2181 left: 58.33333333%;
2182 }
2183 .col-lg-push-6 {
2184 left: 50%;
2185 }
2186 .col-lg-push-5 {
2187 left: 41.66666667%;
2188 }
2189 .col-lg-push-4 {
2190 left: 33.33333333%;
2191 }
2192 .col-lg-push-3 {
2193 left: 25%;
2194 }
2195 .col-lg-push-2 {
2196 left: 16.66666667%;
2197 }
2198 .col-lg-push-1 {
2199 left: 8.33333333%;
2200 }
2201 .col-lg-push-0 {
2202 left: auto;
2203 }
2204 .col-lg-offset-12 {
2205 margin-left: 100%;
2206 }
2207 .col-lg-offset-11 {
2208 margin-left: 91.66666667%;
2209 }
2210 .col-lg-offset-10 {
2211 margin-left: 83.33333333%;
2212 }
2213 .col-lg-offset-9 {
2214 margin-left: 75%;
2215 }
2216 .col-lg-offset-8 {
2217 margin-left: 66.66666667%;
2218 }
2219 .col-lg-offset-7 {
2220 margin-left: 58.33333333%;
2221 }
2222 .col-lg-offset-6 {
2223 margin-left: 50%;
2224 }
2225 .col-lg-offset-5 {
2226 margin-left: 41.66666667%;
2227 }
2228 .col-lg-offset-4 {
2229 margin-left: 33.33333333%;
2230 }
2231 .col-lg-offset-3 {
2232 margin-left: 25%;
2233 }
2234 .col-lg-offset-2 {
2235 margin-left: 16.66666667%;
2236 }
2237 .col-lg-offset-1 {
2238 margin-left: 8.33333333%;
2239 }
2240 .col-lg-offset-0 {
2241 margin-left: 0%;
2242 }
2243 }
2244 table {
2245 background-color: transparent;
2246 }
2247 caption {
2248 padding-top: 8px;
2249 padding-bottom: 8px;
2250 color: #777777;
2251 text-align: left;
2252 }
2253 th {
2254 text-align: left;
2255 }
2256 .table {
2257 width: 100%;
2258 max-width: 100%;
2259 margin-bottom: 18px;
2260 }
2261 .table > thead > tr > th,
2262 .table > tbody > tr > th,
2263 .table > tfoot > tr > th,
2264 .table > thead > tr > td,
2265 .table > tbody > tr > td,
2266 .table > tfoot > tr > td {
2267 padding: 8px;
2268 line-height: 1.42857143;
2269 vertical-align: top;
2270 border-top: 1px solid #ddd;
2271 }
2272 .table > thead > tr > th {
2273 vertical-align: bottom;
2274 border-bottom: 2px solid #ddd;
2275 }
2276 .table > caption + thead > tr:first-child > th,
2277 .table > colgroup + thead > tr:first-child > th,
2278 .table > thead:first-child > tr:first-child > th,
2279 .table > caption + thead > tr:first-child > td,
2280 .table > colgroup + thead > tr:first-child > td,
2281 .table > thead:first-child > tr:first-child > td {
2282 border-top: 0;
2283 }
2284 .table > tbody + tbody {
2285 border-top: 2px solid #ddd;
2286 }
2287 .table .table {
2288 background-color: #fff;
2289 }
2290 .table-condensed > thead > tr > th,
2291 .table-condensed > tbody > tr > th,
2292 .table-condensed > tfoot > tr > th,
2293 .table-condensed > thead > tr > td,
2294 .table-condensed > tbody > tr > td,
2295 .table-condensed > tfoot > tr > td {
2296 padding: 5px;
2297 }
2298 .table-bordered {
2299 border: 1px solid #ddd;
2300 }
2301 .table-bordered > thead > tr > th,
2302 .table-bordered > tbody > tr > th,
2303 .table-bordered > tfoot > tr > th,
2304 .table-bordered > thead > tr > td,
2305 .table-bordered > tbody > tr > td,
2306 .table-bordered > tfoot > tr > td {
2307 border: 1px solid #ddd;
2308 }
2309 .table-bordered > thead > tr > th,
2310 .table-bordered > thead > tr > td {
2311 border-bottom-width: 2px;
2312 }
2313 .table-striped > tbody > tr:nth-of-type(odd) {
2314 background-color: #f9f9f9;
2315 }
2316 .table-hover > tbody > tr:hover {
2317 background-color: #f5f5f5;
2318 }
2319 table col[class*="col-"] {
2320 position: static;
2321 float: none;
2322 display: table-column;
2323 }
2324 table td[class*="col-"],
2325 table th[class*="col-"] {
2326 position: static;
2327 float: none;
2328 display: table-cell;
2329 }
2330 .table > thead > tr > td.active,
2331 .table > tbody > tr > td.active,
2332 .table > tfoot > tr > td.active,
2333 .table > thead > tr > th.active,
2334 .table > tbody > tr > th.active,
2335 .table > tfoot > tr > th.active,
2336 .table > thead > tr.active > td,
2337 .table > tbody > tr.active > td,
2338 .table > tfoot > tr.active > td,
2339 .table > thead > tr.active > th,
2340 .table > tbody > tr.active > th,
2341 .table > tfoot > tr.active > th {
2342 background-color: #f5f5f5;
2343 }
2344 .table-hover > tbody > tr > td.active:hover,
2345 .table-hover > tbody > tr > th.active:hover,
2346 .table-hover > tbody > tr.active:hover > td,
2347 .table-hover > tbody > tr:hover > .active,
2348 .table-hover > tbody > tr.active:hover > th {
2349 background-color: #e8e8e8;
2350 }
2351 .table > thead > tr > td.success,
2352 .table > tbody > tr > td.success,
2353 .table > tfoot > tr > td.success,
2354 .table > thead > tr > th.success,
2355 .table > tbody > tr > th.success,
2356 .table > tfoot > tr > th.success,
2357 .table > thead > tr.success > td,
2358 .table > tbody > tr.success > td,
2359 .table > tfoot > tr.success > td,
2360 .table > thead > tr.success > th,
2361 .table > tbody > tr.success > th,
2362 .table > tfoot > tr.success > th {
2363 background-color: #dff0d8;
2364 }
2365 .table-hover > tbody > tr > td.success:hover,
2366 .table-hover > tbody > tr > th.success:hover,
2367 .table-hover > tbody > tr.success:hover > td,
2368 .table-hover > tbody > tr:hover > .success,
2369 .table-hover > tbody > tr.success:hover > th {
2370 background-color: #d0e9c6;
2371 }
2372 .table > thead > tr > td.info,
2373 .table > tbody > tr > td.info,
2374 .table > tfoot > tr > td.info,
2375 .table > thead > tr > th.info,
2376 .table > tbody > tr > th.info,
2377 .table > tfoot > tr > th.info,
2378 .table > thead > tr.info > td,
2379 .table > tbody > tr.info > td,
2380 .table > tfoot > tr.info > td,
2381 .table > thead > tr.info > th,
2382 .table > tbody > tr.info > th,
2383 .table > tfoot > tr.info > th {
2384 background-color: #d9edf7;
2385 }
2386 .table-hover > tbody > tr > td.info:hover,
2387 .table-hover > tbody > tr > th.info:hover,
2388 .table-hover > tbody > tr.info:hover > td,
2389 .table-hover > tbody > tr:hover > .info,
2390 .table-hover > tbody > tr.info:hover > th {
2391 background-color: #c4e3f3;
2392 }
2393 .table > thead > tr > td.warning,
2394 .table > tbody > tr > td.warning,
2395 .table > tfoot > tr > td.warning,
2396 .table > thead > tr > th.warning,
2397 .table > tbody > tr > th.warning,
2398 .table > tfoot > tr > th.warning,
2399 .table > thead > tr.warning > td,
2400 .table > tbody > tr.warning > td,
2401 .table > tfoot > tr.warning > td,
2402 .table > thead > tr.warning > th,
2403 .table > tbody > tr.warning > th,
2404 .table > tfoot > tr.warning > th {
2405 background-color: #fcf8e3;
2406 }
2407 .table-hover > tbody > tr > td.warning:hover,
2408 .table-hover > tbody > tr > th.warning:hover,
2409 .table-hover > tbody > tr.warning:hover > td,
2410 .table-hover > tbody > tr:hover > .warning,
2411 .table-hover > tbody > tr.warning:hover > th {
2412 background-color: #faf2cc;
2413 }
2414 .table > thead > tr > td.danger,
2415 .table > tbody > tr > td.danger,
2416 .table > tfoot > tr > td.danger,
2417 .table > thead > tr > th.danger,
2418 .table > tbody > tr > th.danger,
2419 .table > tfoot > tr > th.danger,
2420 .table > thead > tr.danger > td,
2421 .table > tbody > tr.danger > td,
2422 .table > tfoot > tr.danger > td,
2423 .table > thead > tr.danger > th,
2424 .table > tbody > tr.danger > th,
2425 .table > tfoot > tr.danger > th {
2426 background-color: #f2dede;
2427 }
2428 .table-hover > tbody > tr > td.danger:hover,
2429 .table-hover > tbody > tr > th.danger:hover,
2430 .table-hover > tbody > tr.danger:hover > td,
2431 .table-hover > tbody > tr:hover > .danger,
2432 .table-hover > tbody > tr.danger:hover > th {
2433 background-color: #ebcccc;
2434 }
2435 .table-responsive {
2436 overflow-x: auto;
2437 min-height: 0.01%;
2438 }
2439 @media screen and (max-width: 767px) {
2440 .table-responsive {
2441 width: 100%;
2442 margin-bottom: 13.5px;
2443 overflow-y: hidden;
2444 -ms-overflow-style: -ms-autohiding-scrollbar;
2445 border: 1px solid #ddd;
2446 }
2447 .table-responsive > .table {
2448 margin-bottom: 0;
2449 }
2450 .table-responsive > .table > thead > tr > th,
2451 .table-responsive > .table > tbody > tr > th,
2452 .table-responsive > .table > tfoot > tr > th,
2453 .table-responsive > .table > thead > tr > td,
2454 .table-responsive > .table > tbody > tr > td,
2455 .table-responsive > .table > tfoot > tr > td {
2456 white-space: nowrap;
2457 }
2458 .table-responsive > .table-bordered {
2459 border: 0;
2460 }
2461 .table-responsive > .table-bordered > thead > tr > th:first-child,
2462 .table-responsive > .table-bordered > tbody > tr > th:first-child,
2463 .table-responsive > .table-bordered > tfoot > tr > th:first-child,
2464 .table-responsive > .table-bordered > thead > tr > td:first-child,
2465 .table-responsive > .table-bordered > tbody > tr > td:first-child,
2466 .table-responsive > .table-bordered > tfoot > tr > td:first-child {
2467 border-left: 0;
2468 }
2469 .table-responsive > .table-bordered > thead > tr > th:last-child,
2470 .table-responsive > .table-bordered > tbody > tr > th:last-child,
2471 .table-responsive > .table-bordered > tfoot > tr > th:last-child,
2472 .table-responsive > .table-bordered > thead > tr > td:last-child,
2473 .table-responsive > .table-bordered > tbody > tr > td:last-child,
2474 .table-responsive > .table-bordered > tfoot > tr > td:last-child {
2475 border-right: 0;
2476 }
2477 .table-responsive > .table-bordered > tbody > tr:last-child > th,
2478 .table-responsive > .table-bordered > tfoot > tr:last-child > th,
2479 .table-responsive > .table-bordered > tbody > tr:last-child > td,
2480 .table-responsive > .table-bordered > tfoot > tr:last-child > td {
2481 border-bottom: 0;
2482 }
2483 }
2484 fieldset {
2485 padding: 0;
2486 margin: 0;
2487 border: 0;
2488 min-width: 0;
2489 }
2490 legend {
2491 display: block;
2492 width: 100%;
2493 padding: 0;
2494 margin-bottom: 18px;
2495 font-size: 19.5px;
2496 line-height: inherit;
2497 color: #333333;
2498 border: 0;
2499 border-bottom: 1px solid #e5e5e5;
2500 }
2501 label {
2502 display: inline-block;
2503 max-width: 100%;
2504 margin-bottom: 5px;
2505 font-weight: bold;
2506 }
2507 input[type="search"] {
2508 -webkit-box-sizing: border-box;
2509 -moz-box-sizing: border-box;
2510 box-sizing: border-box;
2511 }
2512 input[type="radio"],
2513 input[type="checkbox"] {
2514 margin: 4px 0 0;
2515 margin-top: 1px \9;
2516 line-height: normal;
2517 }
2518 input[type="file"] {
2519 display: block;
2520 }
2521 input[type="range"] {
2522 display: block;
2523 width: 100%;
2524 }
2525 select[multiple],
2526 select[size] {
2527 height: auto;
2528 }
2529 input[type="file"]:focus,
2530 input[type="radio"]:focus,
2531 input[type="checkbox"]:focus {
2532 outline: 5px auto -webkit-focus-ring-color;
2533 outline-offset: -2px;
2534 }
2535 output {
2536 display: block;
2537 padding-top: 7px;
2538 font-size: 13px;
2539 line-height: 1.42857143;
2540 color: #555555;
2541 }
2542 .form-control {
2543 display: block;
2544 width: 100%;
2545 height: 32px;
2546 padding: 6px 12px;
2547 font-size: 13px;
2548 line-height: 1.42857143;
2549 color: #555555;
2550 background-color: #fff;
2551 background-image: none;
2552 border: 1px solid #ccc;
2553 border-radius: 2px;
2554 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2555 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2556 -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2557 -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2558 transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
2559 }
2560 .form-control:focus {
2561 border-color: #66afe9;
2562 outline: 0;
2563 -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
2564 box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
2565 }
2566 .form-control::-moz-placeholder {
2567 color: #999;
2568 opacity: 1;
2569 }
2570 .form-control:-ms-input-placeholder {
2571 color: #999;
2572 }
2573 .form-control::-webkit-input-placeholder {
2574 color: #999;
2575 }
2576 .form-control::-ms-expand {
2577 border: 0;
2578 background-color: transparent;
2579 }
2580 .form-control[disabled],
2581 .form-control[readonly],
2582 fieldset[disabled] .form-control {
2583 background-color: #eeeeee;
2584 opacity: 1;
2585 }
2586 .form-control[disabled],
2587 fieldset[disabled] .form-control {
2588 cursor: not-allowed;
2589 }
2590 textarea.form-control {
2591 height: auto;
2592 }
2593 input[type="search"] {
2594 -webkit-appearance: none;
2595 }
2596 @media screen and (-webkit-min-device-pixel-ratio: 0) {
2597 input[type="date"].form-control,
2598 input[type="time"].form-control,
2599 input[type="datetime-local"].form-control,
2600 input[type="month"].form-control {
2601 line-height: 32px;
2602 }
2603 input[type="date"].input-sm,
2604 input[type="time"].input-sm,
2605 input[type="datetime-local"].input-sm,
2606 input[type="month"].input-sm,
2607 .input-group-sm input[type="date"],
2608 .input-group-sm input[type="time"],
2609 .input-group-sm input[type="datetime-local"],
2610 .input-group-sm input[type="month"] {
2611 line-height: 30px;
2612 }
2613 input[type="date"].input-lg,
2614 input[type="time"].input-lg,
2615 input[type="datetime-local"].input-lg,
2616 input[type="month"].input-lg,
2617 .input-group-lg input[type="date"],
2618 .input-group-lg input[type="time"],
2619 .input-group-lg input[type="datetime-local"],
2620 .input-group-lg input[type="month"] {
2621 line-height: 45px;
2622 }
2623 }
2624 .form-group {
2625 margin-bottom: 15px;
2626 }
2627 .radio,
2628 .checkbox {
2629 position: relative;
2630 display: block;
2631 margin-top: 10px;
2632 margin-bottom: 10px;
2633 }
2634 .radio label,
2635 .checkbox label {
2636 min-height: 18px;
2637 padding-left: 20px;
2638 margin-bottom: 0;
2639 font-weight: normal;
2640 cursor: pointer;
2641 }
2642 .radio input[type="radio"],
2643 .radio-inline input[type="radio"],
2644 .checkbox input[type="checkbox"],
2645 .checkbox-inline input[type="checkbox"] {
2646 position: absolute;
2647 margin-left: -20px;
2648 margin-top: 4px \9;
2649 }
2650 .radio + .radio,
2651 .checkbox + .checkbox {
2652 margin-top: -5px;
2653 }
2654 .radio-inline,
2655 .checkbox-inline {
2656 position: relative;
2657 display: inline-block;
2658 padding-left: 20px;
2659 margin-bottom: 0;
2660 vertical-align: middle;
2661 font-weight: normal;
2662 cursor: pointer;
2663 }
2664 .radio-inline + .radio-inline,
2665 .checkbox-inline + .checkbox-inline {
2666 margin-top: 0;
2667 margin-left: 10px;
2668 }
2669 input[type="radio"][disabled],
2670 input[type="checkbox"][disabled],
2671 input[type="radio"].disabled,
2672 input[type="checkbox"].disabled,
2673 fieldset[disabled] input[type="radio"],
2674 fieldset[disabled] input[type="checkbox"] {
2675 cursor: not-allowed;
2676 }
2677 .radio-inline.disabled,
2678 .checkbox-inline.disabled,
2679 fieldset[disabled] .radio-inline,
2680 fieldset[disabled] .checkbox-inline {
2681 cursor: not-allowed;
2682 }
2683 .radio.disabled label,
2684 .checkbox.disabled label,
2685 fieldset[disabled] .radio label,
2686 fieldset[disabled] .checkbox label {
2687 cursor: not-allowed;
2688 }
2689 .form-control-static {
2690 padding-top: 7px;
2691 padding-bottom: 7px;
2692 margin-bottom: 0;
2693 min-height: 31px;
2694 }
2695 .form-control-static.input-lg,
2696 .form-control-static.input-sm {
2697 padding-left: 0;
2698 padding-right: 0;
2699 }
2700 .input-sm {
2701 height: 30px;
2702 padding: 5px 10px;
2703 font-size: 12px;
2704 line-height: 1.5;
2705 border-radius: 1px;
2706 }
2707 select.input-sm {
2708 height: 30px;
2709 line-height: 30px;
2710 }
2711 textarea.input-sm,
2712 select[multiple].input-sm {
2713 height: auto;
2714 }
2715 .form-group-sm .form-control {
2716 height: 30px;
2717 padding: 5px 10px;
2718 font-size: 12px;
2719 line-height: 1.5;
2720 border-radius: 1px;
2721 }
2722 .form-group-sm select.form-control {
2723 height: 30px;
2724 line-height: 30px;
2725 }
2726 .form-group-sm textarea.form-control,
2727 .form-group-sm select[multiple].form-control {
2728 height: auto;
2729 }
2730 .form-group-sm .form-control-static {
2731 height: 30px;
2732 min-height: 30px;
2733 padding: 6px 10px;
2734 font-size: 12px;
2735 line-height: 1.5;
2736 }
2737 .input-lg {
2738 height: 45px;
2739 padding: 10px 16px;
2740 font-size: 17px;
2741 line-height: 1.3333333;
2742 border-radius: 3px;
2743 }
2744 select.input-lg {
2745 height: 45px;
2746 line-height: 45px;
2747 }
2748 textarea.input-lg,
2749 select[multiple].input-lg {
2750 height: auto;
2751 }
2752 .form-group-lg .form-control {
2753 height: 45px;
2754 padding: 10px 16px;
2755 font-size: 17px;
2756 line-height: 1.3333333;
2757 border-radius: 3px;
2758 }
2759 .form-group-lg select.form-control {
2760 height: 45px;
2761 line-height: 45px;
2762 }
2763 .form-group-lg textarea.form-control,
2764 .form-group-lg select[multiple].form-control {
2765 height: auto;
2766 }
2767 .form-group-lg .form-control-static {
2768 height: 45px;
2769 min-height: 35px;
2770 padding: 11px 16px;
2771 font-size: 17px;
2772 line-height: 1.3333333;
2773 }
2774 .has-feedback {
2775 position: relative;
2776 }
2777 .has-feedback .form-control {
2778 padding-right: 40px;
2779 }
2780 .form-control-feedback {
2781 position: absolute;
2782 top: 0;
2783 right: 0;
2784 z-index: 2;
2785 display: block;
2786 width: 32px;
2787 height: 32px;
2788 line-height: 32px;
2789 text-align: center;
2790 pointer-events: none;
2791 }
2792 .input-lg + .form-control-feedback,
2793 .input-group-lg + .form-control-feedback,
2794 .form-group-lg .form-control + .form-control-feedback {
2795 width: 45px;
2796 height: 45px;
2797 line-height: 45px;
2798 }
2799 .input-sm + .form-control-feedback,
2800 .input-group-sm + .form-control-feedback,
2801 .form-group-sm .form-control + .form-control-feedback {
2802 width: 30px;
2803 height: 30px;
2804 line-height: 30px;
2805 }
2806 .has-success .help-block,
2807 .has-success .control-label,
2808 .has-success .radio,
2809 .has-success .checkbox,
2810 .has-success .radio-inline,
2811 .has-success .checkbox-inline,
2812 .has-success.radio label,
2813 .has-success.checkbox label,
2814 .has-success.radio-inline label,
2815 .has-success.checkbox-inline label {
2816 color: #3c763d;
2817 }
2818 .has-success .form-control {
2819 border-color: #3c763d;
2820 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2821 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2822 }
2823 .has-success .form-control:focus {
2824 border-color: #2b542c;
2825 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
2826 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
2827 }
2828 .has-success .input-group-addon {
2829 color: #3c763d;
2830 border-color: #3c763d;
2831 background-color: #dff0d8;
2832 }
2833 .has-success .form-control-feedback {
2834 color: #3c763d;
2835 }
2836 .has-warning .help-block,
2837 .has-warning .control-label,
2838 .has-warning .radio,
2839 .has-warning .checkbox,
2840 .has-warning .radio-inline,
2841 .has-warning .checkbox-inline,
2842 .has-warning.radio label,
2843 .has-warning.checkbox label,
2844 .has-warning.radio-inline label,
2845 .has-warning.checkbox-inline label {
2846 color: #8a6d3b;
2847 }
2848 .has-warning .form-control {
2849 border-color: #8a6d3b;
2850 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2851 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2852 }
2853 .has-warning .form-control:focus {
2854 border-color: #66512c;
2855 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
2856 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
2857 }
2858 .has-warning .input-group-addon {
2859 color: #8a6d3b;
2860 border-color: #8a6d3b;
2861 background-color: #fcf8e3;
2862 }
2863 .has-warning .form-control-feedback {
2864 color: #8a6d3b;
2865 }
2866 .has-error .help-block,
2867 .has-error .control-label,
2868 .has-error .radio,
2869 .has-error .checkbox,
2870 .has-error .radio-inline,
2871 .has-error .checkbox-inline,
2872 .has-error.radio label,
2873 .has-error.checkbox label,
2874 .has-error.radio-inline label,
2875 .has-error.checkbox-inline label {
2876 color: #a94442;
2877 }
2878 .has-error .form-control {
2879 border-color: #a94442;
2880 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2881 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
2882 }
2883 .has-error .form-control:focus {
2884 border-color: #843534;
2885 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
2886 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
2887 }
2888 .has-error .input-group-addon {
2889 color: #a94442;
2890 border-color: #a94442;
2891 background-color: #f2dede;
2892 }
2893 .has-error .form-control-feedback {
2894 color: #a94442;
2895 }
2896 .has-feedback label ~ .form-control-feedback {
2897 top: 23px;
2898 }
2899 .has-feedback label.sr-only ~ .form-control-feedback {
2900 top: 0;
2901 }
2902 .help-block {
2903 display: block;
2904 margin-top: 5px;
2905 margin-bottom: 10px;
2906 color: #404040;
2907 }
2908 @media (min-width: 768px) {
2909 .form-inline .form-group {
2910 display: inline-block;
2911 margin-bottom: 0;
2912 vertical-align: middle;
2913 }
2914 .form-inline .form-control {
2915 display: inline-block;
2916 width: auto;
2917 vertical-align: middle;
2918 }
2919 .form-inline .form-control-static {
2920 display: inline-block;
2921 }
2922 .form-inline .input-group {
2923 display: inline-table;
2924 vertical-align: middle;
2925 }
2926 .form-inline .input-group .input-group-addon,
2927 .form-inline .input-group .input-group-btn,
2928 .form-inline .input-group .form-control {
2929 width: auto;
2930 }
2931 .form-inline .input-group > .form-control {
2932 width: 100%;
2933 }
2934 .form-inline .control-label {
2935 margin-bottom: 0;
2936 vertical-align: middle;
2937 }
2938 .form-inline .radio,
2939 .form-inline .checkbox {
2940 display: inline-block;
2941 margin-top: 0;
2942 margin-bottom: 0;
2943 vertical-align: middle;
2944 }
2945 .form-inline .radio label,
2946 .form-inline .checkbox label {
2947 padding-left: 0;
2948 }
2949 .form-inline .radio input[type="radio"],
2950 .form-inline .checkbox input[type="checkbox"] {
2951 position: relative;
2952 margin-left: 0;
2953 }
2954 .form-inline .has-feedback .form-control-feedback {
2955 top: 0;
2956 }
2957 }
2958 .form-horizontal .radio,
2959 .form-horizontal .checkbox,
2960 .form-horizontal .radio-inline,
2961 .form-horizontal .checkbox-inline {
2962 margin-top: 0;
2963 margin-bottom: 0;
2964 padding-top: 7px;
2965 }
2966 .form-horizontal .radio,
2967 .form-horizontal .checkbox {
2968 min-height: 25px;
2969 }
2970 .form-horizontal .form-group {
2971 margin-left: 0px;
2972 margin-right: 0px;
2973 }
2974 @media (min-width: 768px) {
2975 .form-horizontal .control-label {
2976 text-align: right;
2977 margin-bottom: 0;
2978 padding-top: 7px;
2979 }
2980 }
2981 .form-horizontal .has-feedback .form-control-feedback {
2982 right: 0px;
2983 }
2984 @media (min-width: 768px) {
2985 .form-horizontal .form-group-lg .control-label {
2986 padding-top: 11px;
2987 font-size: 17px;
2988 }
2989 }
2990 @media (min-width: 768px) {
2991 .form-horizontal .form-group-sm .control-label {
2992 padding-top: 6px;
2993 font-size: 12px;
2994 }
2995 }
2996 .btn {
2997 display: inline-block;
2998 margin-bottom: 0;
2999 font-weight: normal;
3000 text-align: center;
3001 vertical-align: middle;
3002 touch-action: manipulation;
3003 cursor: pointer;
3004 background-image: none;
3005 border: 1px solid transparent;
3006 white-space: nowrap;
3007 padding: 6px 12px;
3008 font-size: 13px;
3009 line-height: 1.42857143;
3010 border-radius: 2px;
3011 -webkit-user-select: none;
3012 -moz-user-select: none;
3013 -ms-user-select: none;
3014 user-select: none;
3015 }
3016 .btn:focus,
3017 .btn:active:focus,
3018 .btn.active:focus,
3019 .btn.focus,
3020 .btn:active.focus,
3021 .btn.active.focus {
3022 outline: 5px auto -webkit-focus-ring-color;
3023 outline-offset: -2px;
3024 }
3025 .btn:hover,
3026 .btn:focus,
3027 .btn.focus {
3028 color: #333;
3029 text-decoration: none;
3030 }
3031 .btn:active,
3032 .btn.active {
3033 outline: 0;
3034 background-image: none;
3035 -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3036 box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3037 }
3038 .btn.disabled,
3039 .btn[disabled],
3040 fieldset[disabled] .btn {
3041 cursor: not-allowed;
3042 opacity: 0.65;
3043 filter: alpha(opacity=65);
3044 -webkit-box-shadow: none;
3045 box-shadow: none;
3046 }
3047 a.btn.disabled,
3048 fieldset[disabled] a.btn {
3049 pointer-events: none;
3050 }
3051 .btn-default {
3052 color: #333;
3053 background-color: #fff;
3054 border-color: #ccc;
3055 }
3056 .btn-default:focus,
3057 .btn-default.focus {
3058 color: #333;
3059 background-color: #e6e6e6;
3060 border-color: #8c8c8c;
3061 }
3062 .btn-default:hover {
3063 color: #333;
3064 background-color: #e6e6e6;
3065 border-color: #adadad;
3066 }
3067 .btn-default:active,
3068 .btn-default.active,
3069 .open > .dropdown-toggle.btn-default {
3070 color: #333;
3071 background-color: #e6e6e6;
3072 border-color: #adadad;
3073 }
3074 .btn-default:active:hover,
3075 .btn-default.active:hover,
3076 .open > .dropdown-toggle.btn-default:hover,
3077 .btn-default:active:focus,
3078 .btn-default.active:focus,
3079 .open > .dropdown-toggle.btn-default:focus,
3080 .btn-default:active.focus,
3081 .btn-default.active.focus,
3082 .open > .dropdown-toggle.btn-default.focus {
3083 color: #333;
3084 background-color: #d4d4d4;
3085 border-color: #8c8c8c;
3086 }
3087 .btn-default:active,
3088 .btn-default.active,
3089 .open > .dropdown-toggle.btn-default {
3090 background-image: none;
3091 }
3092 .btn-default.disabled:hover,
3093 .btn-default[disabled]:hover,
3094 fieldset[disabled] .btn-default:hover,
3095 .btn-default.disabled:focus,
3096 .btn-default[disabled]:focus,
3097 fieldset[disabled] .btn-default:focus,
3098 .btn-default.disabled.focus,
3099 .btn-default[disabled].focus,
3100 fieldset[disabled] .btn-default.focus {
3101 background-color: #fff;
3102 border-color: #ccc;
3103 }
3104 .btn-default .badge {
3105 color: #fff;
3106 background-color: #333;
3107 }
3108 .btn-primary {
3109 color: #fff;
3110 background-color: #337ab7;
3111 border-color: #2e6da4;
3112 }
3113 .btn-primary:focus,
3114 .btn-primary.focus {
3115 color: #fff;
3116 background-color: #286090;
3117 border-color: #122b40;
3118 }
3119 .btn-primary:hover {
3120 color: #fff;
3121 background-color: #286090;
3122 border-color: #204d74;
3123 }
3124 .btn-primary:active,
3125 .btn-primary.active,
3126 .open > .dropdown-toggle.btn-primary {
3127 color: #fff;
3128 background-color: #286090;
3129 border-color: #204d74;
3130 }
3131 .btn-primary:active:hover,
3132 .btn-primary.active:hover,
3133 .open > .dropdown-toggle.btn-primary:hover,
3134 .btn-primary:active:focus,
3135 .btn-primary.active:focus,
3136 .open > .dropdown-toggle.btn-primary:focus,
3137 .btn-primary:active.focus,
3138 .btn-primary.active.focus,
3139 .open > .dropdown-toggle.btn-primary.focus {
3140 color: #fff;
3141 background-color: #204d74;
3142 border-color: #122b40;
3143 }
3144 .btn-primary:active,
3145 .btn-primary.active,
3146 .open > .dropdown-toggle.btn-primary {
3147 background-image: none;
3148 }
3149 .btn-primary.disabled:hover,
3150 .btn-primary[disabled]:hover,
3151 fieldset[disabled] .btn-primary:hover,
3152 .btn-primary.disabled:focus,
3153 .btn-primary[disabled]:focus,
3154 fieldset[disabled] .btn-primary:focus,
3155 .btn-primary.disabled.focus,
3156 .btn-primary[disabled].focus,
3157 fieldset[disabled] .btn-primary.focus {
3158 background-color: #337ab7;
3159 border-color: #2e6da4;
3160 }
3161 .btn-primary .badge {
3162 color: #337ab7;
3163 background-color: #fff;
3164 }
3165 .btn-success {
3166 color: #fff;
3167 background-color: #5cb85c;
3168 border-color: #4cae4c;
3169 }
3170 .btn-success:focus,
3171 .btn-success.focus {
3172 color: #fff;
3173 background-color: #449d44;
3174 border-color: #255625;
3175 }
3176 .btn-success:hover {
3177 color: #fff;
3178 background-color: #449d44;
3179 border-color: #398439;
3180 }
3181 .btn-success:active,
3182 .btn-success.active,
3183 .open > .dropdown-toggle.btn-success {
3184 color: #fff;
3185 background-color: #449d44;
3186 border-color: #398439;
3187 }
3188 .btn-success:active:hover,
3189 .btn-success.active:hover,
3190 .open > .dropdown-toggle.btn-success:hover,
3191 .btn-success:active:focus,
3192 .btn-success.active:focus,
3193 .open > .dropdown-toggle.btn-success:focus,
3194 .btn-success:active.focus,
3195 .btn-success.active.focus,
3196 .open > .dropdown-toggle.btn-success.focus {
3197 color: #fff;
3198 background-color: #398439;
3199 border-color: #255625;
3200 }
3201 .btn-success:active,
3202 .btn-success.active,
3203 .open > .dropdown-toggle.btn-success {
3204 background-image: none;
3205 }
3206 .btn-success.disabled:hover,
3207 .btn-success[disabled]:hover,
3208 fieldset[disabled] .btn-success:hover,
3209 .btn-success.disabled:focus,
3210 .btn-success[disabled]:focus,
3211 fieldset[disabled] .btn-success:focus,
3212 .btn-success.disabled.focus,
3213 .btn-success[disabled].focus,
3214 fieldset[disabled] .btn-success.focus {
3215 background-color: #5cb85c;
3216 border-color: #4cae4c;
3217 }
3218 .btn-success .badge {
3219 color: #5cb85c;
3220 background-color: #fff;
3221 }
3222 .btn-info {
3223 color: #fff;
3224 background-color: #5bc0de;
3225 border-color: #46b8da;
3226 }
3227 .btn-info:focus,
3228 .btn-info.focus {
3229 color: #fff;
3230 background-color: #31b0d5;
3231 border-color: #1b6d85;
3232 }
3233 .btn-info:hover {
3234 color: #fff;
3235 background-color: #31b0d5;
3236 border-color: #269abc;
3237 }
3238 .btn-info:active,
3239 .btn-info.active,
3240 .open > .dropdown-toggle.btn-info {
3241 color: #fff;
3242 background-color: #31b0d5;
3243 border-color: #269abc;
3244 }
3245 .btn-info:active:hover,
3246 .btn-info.active:hover,
3247 .open > .dropdown-toggle.btn-info:hover,
3248 .btn-info:active:focus,
3249 .btn-info.active:focus,
3250 .open > .dropdown-toggle.btn-info:focus,
3251 .btn-info:active.focus,
3252 .btn-info.active.focus,
3253 .open > .dropdown-toggle.btn-info.focus {
3254 color: #fff;
3255 background-color: #269abc;
3256 border-color: #1b6d85;
3257 }
3258 .btn-info:active,
3259 .btn-info.active,
3260 .open > .dropdown-toggle.btn-info {
3261 background-image: none;
3262 }
3263 .btn-info.disabled:hover,
3264 .btn-info[disabled]:hover,
3265 fieldset[disabled] .btn-info:hover,
3266 .btn-info.disabled:focus,
3267 .btn-info[disabled]:focus,
3268 fieldset[disabled] .btn-info:focus,
3269 .btn-info.disabled.focus,
3270 .btn-info[disabled].focus,
3271 fieldset[disabled] .btn-info.focus {
3272 background-color: #5bc0de;
3273 border-color: #46b8da;
3274 }
3275 .btn-info .badge {
3276 color: #5bc0de;
3277 background-color: #fff;
3278 }
3279 .btn-warning {
3280 color: #fff;
3281 background-color: #f0ad4e;
3282 border-color: #eea236;
3283 }
3284 .btn-warning:focus,
3285 .btn-warning.focus {
3286 color: #fff;
3287 background-color: #ec971f;
3288 border-color: #985f0d;
3289 }
3290 .btn-warning:hover {
3291 color: #fff;
3292 background-color: #ec971f;
3293 border-color: #d58512;
3294 }
3295 .btn-warning:active,
3296 .btn-warning.active,
3297 .open > .dropdown-toggle.btn-warning {
3298 color: #fff;
3299 background-color: #ec971f;
3300 border-color: #d58512;
3301 }
3302 .btn-warning:active:hover,
3303 .btn-warning.active:hover,
3304 .open > .dropdown-toggle.btn-warning:hover,
3305 .btn-warning:active:focus,
3306 .btn-warning.active:focus,
3307 .open > .dropdown-toggle.btn-warning:focus,
3308 .btn-warning:active.focus,
3309 .btn-warning.active.focus,
3310 .open > .dropdown-toggle.btn-warning.focus {
3311 color: #fff;
3312 background-color: #d58512;
3313 border-color: #985f0d;
3314 }
3315 .btn-warning:active,
3316 .btn-warning.active,
3317 .open > .dropdown-toggle.btn-warning {
3318 background-image: none;
3319 }
3320 .btn-warning.disabled:hover,
3321 .btn-warning[disabled]:hover,
3322 fieldset[disabled] .btn-warning:hover,
3323 .btn-warning.disabled:focus,
3324 .btn-warning[disabled]:focus,
3325 fieldset[disabled] .btn-warning:focus,
3326 .btn-warning.disabled.focus,
3327 .btn-warning[disabled].focus,
3328 fieldset[disabled] .btn-warning.focus {
3329 background-color: #f0ad4e;
3330 border-color: #eea236;
3331 }
3332 .btn-warning .badge {
3333 color: #f0ad4e;
3334 background-color: #fff;
3335 }
3336 .btn-danger {
3337 color: #fff;
3338 background-color: #d9534f;
3339 border-color: #d43f3a;
3340 }
3341 .btn-danger:focus,
3342 .btn-danger.focus {
3343 color: #fff;
3344 background-color: #c9302c;
3345 border-color: #761c19;
3346 }
3347 .btn-danger:hover {
3348 color: #fff;
3349 background-color: #c9302c;
3350 border-color: #ac2925;
3351 }
3352 .btn-danger:active,
3353 .btn-danger.active,
3354 .open > .dropdown-toggle.btn-danger {
3355 color: #fff;
3356 background-color: #c9302c;
3357 border-color: #ac2925;
3358 }
3359 .btn-danger:active:hover,
3360 .btn-danger.active:hover,
3361 .open > .dropdown-toggle.btn-danger:hover,
3362 .btn-danger:active:focus,
3363 .btn-danger.active:focus,
3364 .open > .dropdown-toggle.btn-danger:focus,
3365 .btn-danger:active.focus,
3366 .btn-danger.active.focus,
3367 .open > .dropdown-toggle.btn-danger.focus {
3368 color: #fff;
3369 background-color: #ac2925;
3370 border-color: #761c19;
3371 }
3372 .btn-danger:active,
3373 .btn-danger.active,
3374 .open > .dropdown-toggle.btn-danger {
3375 background-image: none;
3376 }
3377 .btn-danger.disabled:hover,
3378 .btn-danger[disabled]:hover,
3379 fieldset[disabled] .btn-danger:hover,
3380 .btn-danger.disabled:focus,
3381 .btn-danger[disabled]:focus,
3382 fieldset[disabled] .btn-danger:focus,
3383 .btn-danger.disabled.focus,
3384 .btn-danger[disabled].focus,
3385 fieldset[disabled] .btn-danger.focus {
3386 background-color: #d9534f;
3387 border-color: #d43f3a;
3388 }
3389 .btn-danger .badge {
3390 color: #d9534f;
3391 background-color: #fff;
3392 }
3393 .btn-link {
3394 color: #337ab7;
3395 font-weight: normal;
3396 border-radius: 0;
3397 }
3398 .btn-link,
3399 .btn-link:active,
3400 .btn-link.active,
3401 .btn-link[disabled],
3402 fieldset[disabled] .btn-link {
3403 background-color: transparent;
3404 -webkit-box-shadow: none;
3405 box-shadow: none;
3406 }
3407 .btn-link,
3408 .btn-link:hover,
3409 .btn-link:focus,
3410 .btn-link:active {
3411 border-color: transparent;
3412 }
3413 .btn-link:hover,
3414 .btn-link:focus {
3415 color: #23527c;
3416 text-decoration: underline;
3417 background-color: transparent;
3418 }
3419 .btn-link[disabled]:hover,
3420 fieldset[disabled] .btn-link:hover,
3421 .btn-link[disabled]:focus,
3422 fieldset[disabled] .btn-link:focus {
3423 color: #777777;
3424 text-decoration: none;
3425 }
3426 .btn-lg,
3427 .btn-group-lg > .btn {
3428 padding: 10px 16px;
3429 font-size: 17px;
3430 line-height: 1.3333333;
3431 border-radius: 3px;
3432 }
3433 .btn-sm,
3434 .btn-group-sm > .btn {
3435 padding: 5px 10px;
3436 font-size: 12px;
3437 line-height: 1.5;
3438 border-radius: 1px;
3439 }
3440 .btn-xs,
3441 .btn-group-xs > .btn {
3442 padding: 1px 5px;
3443 font-size: 12px;
3444 line-height: 1.5;
3445 border-radius: 1px;
3446 }
3447 .btn-block {
3448 display: block;
3449 width: 100%;
3450 }
3451 .btn-block + .btn-block {
3452 margin-top: 5px;
3453 }
3454 input[type="submit"].btn-block,
3455 input[type="reset"].btn-block,
3456 input[type="button"].btn-block {
3457 width: 100%;
3458 }
3459 .fade {
3460 opacity: 0;
3461 -webkit-transition: opacity 0.15s linear;
3462 -o-transition: opacity 0.15s linear;
3463 transition: opacity 0.15s linear;
3464 }
3465 .fade.in {
3466 opacity: 1;
3467 }
3468 .collapse {
3469 display: none;
3470 }
3471 .collapse.in {
3472 display: block;
3473 }
3474 tr.collapse.in {
3475 display: table-row;
3476 }
3477 tbody.collapse.in {
3478 display: table-row-group;
3479 }
3480 .collapsing {
3481 position: relative;
3482 height: 0;
3483 overflow: hidden;
3484 -webkit-transition-property: height, visibility;
3485 transition-property: height, visibility;
3486 -webkit-transition-duration: 0.35s;
3487 transition-duration: 0.35s;
3488 -webkit-transition-timing-function: ease;
3489 transition-timing-function: ease;
3490 }
3491 .caret {
3492 display: inline-block;
3493 width: 0;
3494 height: 0;
3495 margin-left: 2px;
3496 vertical-align: middle;
3497 border-top: 4px dashed;
3498 border-top: 4px solid \9;
3499 border-right: 4px solid transparent;
3500 border-left: 4px solid transparent;
3501 }
3502 .dropup,
3503 .dropdown {
3504 position: relative;
3505 }
3506 .dropdown-toggle:focus {
3507 outline: 0;
3508 }
3509 .dropdown-menu {
3510 position: absolute;
3511 top: 100%;
3512 left: 0;
3513 z-index: 1000;
3514 display: none;
3515 float: left;
3516 min-width: 160px;
3517 padding: 5px 0;
3518 margin: 2px 0 0;
3519 list-style: none;
3520 font-size: 13px;
3521 text-align: left;
3522 background-color: #fff;
3523 border: 1px solid #ccc;
3524 border: 1px solid rgba(0, 0, 0, 0.15);
3525 border-radius: 2px;
3526 -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
3527 box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
3528 background-clip: padding-box;
3529 }
3530 .dropdown-menu.pull-right {
3531 right: 0;
3532 left: auto;
3533 }
3534 .dropdown-menu .divider {
3535 height: 1px;
3536 margin: 8px 0;
3537 overflow: hidden;
3538 background-color: #e5e5e5;
3539 }
3540 .dropdown-menu > li > a {
3541 display: block;
3542 padding: 3px 20px;
3543 clear: both;
3544 font-weight: normal;
3545 line-height: 1.42857143;
3546 color: #333333;
3547 white-space: nowrap;
3548 }
3549 .dropdown-menu > li > a:hover,
3550 .dropdown-menu > li > a:focus {
3551 text-decoration: none;
3552 color: #262626;
3553 background-color: #f5f5f5;
3554 }
3555 .dropdown-menu > .active > a,
3556 .dropdown-menu > .active > a:hover,
3557 .dropdown-menu > .active > a:focus {
3558 color: #fff;
3559 text-decoration: none;
3560 outline: 0;
3561 background-color: #337ab7;
3562 }
3563 .dropdown-menu > .disabled > a,
3564 .dropdown-menu > .disabled > a:hover,
3565 .dropdown-menu > .disabled > a:focus {
3566 color: #777777;
3567 }
3568 .dropdown-menu > .disabled > a:hover,
3569 .dropdown-menu > .disabled > a:focus {
3570 text-decoration: none;
3571 background-color: transparent;
3572 background-image: none;
3573 filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
3574 cursor: not-allowed;
3575 }
3576 .open > .dropdown-menu {
3577 display: block;
3578 }
3579 .open > a {
3580 outline: 0;
3581 }
3582 .dropdown-menu-right {
3583 left: auto;
3584 right: 0;
3585 }
3586 .dropdown-menu-left {
3587 left: 0;
3588 right: auto;
3589 }
3590 .dropdown-header {
3591 display: block;
3592 padding: 3px 20px;
3593 font-size: 12px;
3594 line-height: 1.42857143;
3595 color: #777777;
3596 white-space: nowrap;
3597 }
3598 .dropdown-backdrop {
3599 position: fixed;
3600 left: 0;
3601 right: 0;
3602 bottom: 0;
3603 top: 0;
3604 z-index: 990;
3605 }
3606 .pull-right > .dropdown-menu {
3607 right: 0;
3608 left: auto;
3609 }
3610 .dropup .caret,
3611 .navbar-fixed-bottom .dropdown .caret {
3612 border-top: 0;
3613 border-bottom: 4px dashed;
3614 border-bottom: 4px solid \9;
3615 content: "";
3616 }
3617 .dropup .dropdown-menu,
3618 .navbar-fixed-bottom .dropdown .dropdown-menu {
3619 top: auto;
3620 bottom: 100%;
3621 margin-bottom: 2px;
3622 }
3623 @media (min-width: 541px) {
3624 .navbar-right .dropdown-menu {
3625 left: auto;
3626 right: 0;
3627 }
3628 .navbar-right .dropdown-menu-left {
3629 left: 0;
3630 right: auto;
3631 }
3632 }
3633 .btn-group,
3634 .btn-group-vertical {
3635 position: relative;
3636 display: inline-block;
3637 vertical-align: middle;
3638 }
3639 .btn-group > .btn,
3640 .btn-group-vertical > .btn {
3641 position: relative;
3642 float: left;
3643 }
3644 .btn-group > .btn:hover,
3645 .btn-group-vertical > .btn:hover,
3646 .btn-group > .btn:focus,
3647 .btn-group-vertical > .btn:focus,
3648 .btn-group > .btn:active,
3649 .btn-group-vertical > .btn:active,
3650 .btn-group > .btn.active,
3651 .btn-group-vertical > .btn.active {
3652 z-index: 2;
3653 }
3654 .btn-group .btn + .btn,
3655 .btn-group .btn + .btn-group,
3656 .btn-group .btn-group + .btn,
3657 .btn-group .btn-group + .btn-group {
3658 margin-left: -1px;
3659 }
3660 .btn-toolbar {
3661 margin-left: -5px;
3662 }
3663 .btn-toolbar .btn,
3664 .btn-toolbar .btn-group,
3665 .btn-toolbar .input-group {
3666 float: left;
3667 }
3668 .btn-toolbar > .btn,
3669 .btn-toolbar > .btn-group,
3670 .btn-toolbar > .input-group {
3671 margin-left: 5px;
3672 }
3673 .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
3674 border-radius: 0;
3675 }
3676 .btn-group > .btn:first-child {
3677 margin-left: 0;
3678 }
3679 .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
3680 border-bottom-right-radius: 0;
3681 border-top-right-radius: 0;
3682 }
3683 .btn-group > .btn:last-child:not(:first-child),
3684 .btn-group > .dropdown-toggle:not(:first-child) {
3685 border-bottom-left-radius: 0;
3686 border-top-left-radius: 0;
3687 }
3688 .btn-group > .btn-group {
3689 float: left;
3690 }
3691 .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
3692 border-radius: 0;
3693 }
3694 .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
3695 .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
3696 border-bottom-right-radius: 0;
3697 border-top-right-radius: 0;
3698 }
3699 .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
3700 border-bottom-left-radius: 0;
3701 border-top-left-radius: 0;
3702 }
3703 .btn-group .dropdown-toggle:active,
3704 .btn-group.open .dropdown-toggle {
3705 outline: 0;
3706 }
3707 .btn-group > .btn + .dropdown-toggle {
3708 padding-left: 8px;
3709 padding-right: 8px;
3710 }
3711 .btn-group > .btn-lg + .dropdown-toggle {
3712 padding-left: 12px;
3713 padding-right: 12px;
3714 }
3715 .btn-group.open .dropdown-toggle {
3716 -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3717 box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
3718 }
3719 .btn-group.open .dropdown-toggle.btn-link {
3720 -webkit-box-shadow: none;
3721 box-shadow: none;
3722 }
3723 .btn .caret {
3724 margin-left: 0;
3725 }
3726 .btn-lg .caret {
3727 border-width: 5px 5px 0;
3728 border-bottom-width: 0;
3729 }
3730 .dropup .btn-lg .caret {
3731 border-width: 0 5px 5px;
3732 }
3733 .btn-group-vertical > .btn,
3734 .btn-group-vertical > .btn-group,
3735 .btn-group-vertical > .btn-group > .btn {
3736 display: block;
3737 float: none;
3738 width: 100%;
3739 max-width: 100%;
3740 }
3741 .btn-group-vertical > .btn-group > .btn {
3742 float: none;
3743 }
3744 .btn-group-vertical > .btn + .btn,
3745 .btn-group-vertical > .btn + .btn-group,
3746 .btn-group-vertical > .btn-group + .btn,
3747 .btn-group-vertical > .btn-group + .btn-group {
3748 margin-top: -1px;
3749 margin-left: 0;
3750 }
3751 .btn-group-vertical > .btn:not(:first-child):not(:last-child) {
3752 border-radius: 0;
3753 }
3754 .btn-group-vertical > .btn:first-child:not(:last-child) {
3755 border-top-right-radius: 2px;
3756 border-top-left-radius: 2px;
3757 border-bottom-right-radius: 0;
3758 border-bottom-left-radius: 0;
3759 }
3760 .btn-group-vertical > .btn:last-child:not(:first-child) {
3761 border-top-right-radius: 0;
3762 border-top-left-radius: 0;
3763 border-bottom-right-radius: 2px;
3764 border-bottom-left-radius: 2px;
3765 }
3766 .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
3767 border-radius: 0;
3768 }
3769 .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
3770 .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
3771 border-bottom-right-radius: 0;
3772 border-bottom-left-radius: 0;
3773 }
3774 .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
3775 border-top-right-radius: 0;
3776 border-top-left-radius: 0;
3777 }
3778 .btn-group-justified {
3779 display: table;
3780 width: 100%;
3781 table-layout: fixed;
3782 border-collapse: separate;
3783 }
3784 .btn-group-justified > .btn,
3785 .btn-group-justified > .btn-group {
3786 float: none;
3787 display: table-cell;
3788 width: 1%;
3789 }
3790 .btn-group-justified > .btn-group .btn {
3791 width: 100%;
3792 }
3793 .btn-group-justified > .btn-group .dropdown-menu {
3794 left: auto;
3795 }
3796 [data-toggle="buttons"] > .btn input[type="radio"],
3797 [data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
3798 [data-toggle="buttons"] > .btn input[type="checkbox"],
3799 [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
3800 position: absolute;
3801 clip: rect(0, 0, 0, 0);
3802 pointer-events: none;
3803 }
3804 .input-group {
3805 position: relative;
3806 display: table;
3807 border-collapse: separate;
3808 }
3809 .input-group[class*="col-"] {
3810 float: none;
3811 padding-left: 0;
3812 padding-right: 0;
3813 }
3814 .input-group .form-control {
3815 position: relative;
3816 z-index: 2;
3817 float: left;
3818 width: 100%;
3819 margin-bottom: 0;
3820 }
3821 .input-group .form-control:focus {
3822 z-index: 3;
3823 }
3824 .input-group-lg > .form-control,
3825 .input-group-lg > .input-group-addon,
3826 .input-group-lg > .input-group-btn > .btn {
3827 height: 45px;
3828 padding: 10px 16px;
3829 font-size: 17px;
3830 line-height: 1.3333333;
3831 border-radius: 3px;
3832 }
3833 select.input-group-lg > .form-control,
3834 select.input-group-lg > .input-group-addon,
3835 select.input-group-lg > .input-group-btn > .btn {
3836 height: 45px;
3837 line-height: 45px;
3838 }
3839 textarea.input-group-lg > .form-control,
3840 textarea.input-group-lg > .input-group-addon,
3841 textarea.input-group-lg > .input-group-btn > .btn,
3842 select[multiple].input-group-lg > .form-control,
3843 select[multiple].input-group-lg > .input-group-addon,
3844 select[multiple].input-group-lg > .input-group-btn > .btn {
3845 height: auto;
3846 }
3847 .input-group-sm > .form-control,
3848 .input-group-sm > .input-group-addon,
3849 .input-group-sm > .input-group-btn > .btn {
3850 height: 30px;
3851 padding: 5px 10px;
3852 font-size: 12px;
3853 line-height: 1.5;
3854 border-radius: 1px;
3855 }
3856 select.input-group-sm > .form-control,
3857 select.input-group-sm > .input-group-addon,
3858 select.input-group-sm > .input-group-btn > .btn {
3859 height: 30px;
3860 line-height: 30px;
3861 }
3862 textarea.input-group-sm > .form-control,
3863 textarea.input-group-sm > .input-group-addon,
3864 textarea.input-group-sm > .input-group-btn > .btn,
3865 select[multiple].input-group-sm > .form-control,
3866 select[multiple].input-group-sm > .input-group-addon,
3867 select[multiple].input-group-sm > .input-group-btn > .btn {
3868 height: auto;
3869 }
3870 .input-group-addon,
3871 .input-group-btn,
3872 .input-group .form-control {
3873 display: table-cell;
3874 }
3875 .input-group-addon:not(:first-child):not(:last-child),
3876 .input-group-btn:not(:first-child):not(:last-child),
3877 .input-group .form-control:not(:first-child):not(:last-child) {
3878 border-radius: 0;
3879 }
3880 .input-group-addon,
3881 .input-group-btn {
3882 width: 1%;
3883 white-space: nowrap;
3884 vertical-align: middle;
3885 }
3886 .input-group-addon {
3887 padding: 6px 12px;
3888 font-size: 13px;
3889 font-weight: normal;
3890 line-height: 1;
3891 color: #555555;
3892 text-align: center;
3893 background-color: #eeeeee;
3894 border: 1px solid #ccc;
3895 border-radius: 2px;
3896 }
3897 .input-group-addon.input-sm {
3898 padding: 5px 10px;
3899 font-size: 12px;
3900 border-radius: 1px;
3901 }
3902 .input-group-addon.input-lg {
3903 padding: 10px 16px;
3904 font-size: 17px;
3905 border-radius: 3px;
3906 }
3907 .input-group-addon input[type="radio"],
3908 .input-group-addon input[type="checkbox"] {
3909 margin-top: 0;
3910 }
3911 .input-group .form-control:first-child,
3912 .input-group-addon:first-child,
3913 .input-group-btn:first-child > .btn,
3914 .input-group-btn:first-child > .btn-group > .btn,
3915 .input-group-btn:first-child > .dropdown-toggle,
3916 .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
3917 .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
3918 border-bottom-right-radius: 0;
3919 border-top-right-radius: 0;
3920 }
3921 .input-group-addon:first-child {
3922 border-right: 0;
3923 }
3924 .input-group .form-control:last-child,
3925 .input-group-addon:last-child,
3926 .input-group-btn:last-child > .btn,
3927 .input-group-btn:last-child > .btn-group > .btn,
3928 .input-group-btn:last-child > .dropdown-toggle,
3929 .input-group-btn:first-child > .btn:not(:first-child),
3930 .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
3931 border-bottom-left-radius: 0;
3932 border-top-left-radius: 0;
3933 }
3934 .input-group-addon:last-child {
3935 border-left: 0;
3936 }
3937 .input-group-btn {
3938 position: relative;
3939 font-size: 0;
3940 white-space: nowrap;
3941 }
3942 .input-group-btn > .btn {
3943 position: relative;
3944 }
3945 .input-group-btn > .btn + .btn {
3946 margin-left: -1px;
3947 }
3948 .input-group-btn > .btn:hover,
3949 .input-group-btn > .btn:focus,
3950 .input-group-btn > .btn:active {
3951 z-index: 2;
3952 }
3953 .input-group-btn:first-child > .btn,
3954 .input-group-btn:first-child > .btn-group {
3955 margin-right: -1px;
3956 }
3957 .input-group-btn:last-child > .btn,
3958 .input-group-btn:last-child > .btn-group {
3959 z-index: 2;
3960 margin-left: -1px;
3961 }
3962 .nav {
3963 margin-bottom: 0;
3964 padding-left: 0;
3965 list-style: none;
3966 }
3967 .nav > li {
3968 position: relative;
3969 display: block;
3970 }
3971 .nav > li > a {
3972 position: relative;
3973 display: block;
3974 padding: 10px 15px;
3975 }
3976 .nav > li > a:hover,
3977 .nav > li > a:focus {
3978 text-decoration: none;
3979 background-color: #eeeeee;
3980 }
3981 .nav > li.disabled > a {
3982 color: #777777;
3983 }
3984 .nav > li.disabled > a:hover,
3985 .nav > li.disabled > a:focus {
3986 color: #777777;
3987 text-decoration: none;
3988 background-color: transparent;
3989 cursor: not-allowed;
3990 }
3991 .nav .open > a,
3992 .nav .open > a:hover,
3993 .nav .open > a:focus {
3994 background-color: #eeeeee;
3995 border-color: #337ab7;
3996 }
3997 .nav .nav-divider {
3998 height: 1px;
3999 margin: 8px 0;
4000 overflow: hidden;
4001 background-color: #e5e5e5;
4002 }
4003 .nav > li > a > img {
4004 max-width: none;
4005 }
4006 .nav-tabs {
4007 border-bottom: 1px solid #ddd;
4008 }
4009 .nav-tabs > li {
4010 float: left;
4011 margin-bottom: -1px;
4012 }
4013 .nav-tabs > li > a {
4014 margin-right: 2px;
4015 line-height: 1.42857143;
4016 border: 1px solid transparent;
4017 border-radius: 2px 2px 0 0;
4018 }
4019 .nav-tabs > li > a:hover {
4020 border-color: #eeeeee #eeeeee #ddd;
4021 }
4022 .nav-tabs > li.active > a,
4023 .nav-tabs > li.active > a:hover,
4024 .nav-tabs > li.active > a:focus {
4025 color: #555555;
4026 background-color: #fff;
4027 border: 1px solid #ddd;
4028 border-bottom-color: transparent;
4029 cursor: default;
4030 }
4031 .nav-tabs.nav-justified {
4032 width: 100%;
4033 border-bottom: 0;
4034 }
4035 .nav-tabs.nav-justified > li {
4036 float: none;
4037 }
4038 .nav-tabs.nav-justified > li > a {
4039 text-align: center;
4040 margin-bottom: 5px;
4041 }
4042 .nav-tabs.nav-justified > .dropdown .dropdown-menu {
4043 top: auto;
4044 left: auto;
4045 }
4046 @media (min-width: 768px) {
4047 .nav-tabs.nav-justified > li {
4048 display: table-cell;
4049 width: 1%;
4050 }
4051 .nav-tabs.nav-justified > li > a {
4052 margin-bottom: 0;
4053 }
4054 }
4055 .nav-tabs.nav-justified > li > a {
4056 margin-right: 0;
4057 border-radius: 2px;
4058 }
4059 .nav-tabs.nav-justified > .active > a,
4060 .nav-tabs.nav-justified > .active > a:hover,
4061 .nav-tabs.nav-justified > .active > a:focus {
4062 border: 1px solid #ddd;
4063 }
4064 @media (min-width: 768px) {
4065 .nav-tabs.nav-justified > li > a {
4066 border-bottom: 1px solid #ddd;
4067 border-radius: 2px 2px 0 0;
4068 }
4069 .nav-tabs.nav-justified > .active > a,
4070 .nav-tabs.nav-justified > .active > a:hover,
4071 .nav-tabs.nav-justified > .active > a:focus {
4072 border-bottom-color: #fff;
4073 }
4074 }
4075 .nav-pills > li {
4076 float: left;
4077 }
4078 .nav-pills > li > a {
4079 border-radius: 2px;
4080 }
4081 .nav-pills > li + li {
4082 margin-left: 2px;
4083 }
4084 .nav-pills > li.active > a,
4085 .nav-pills > li.active > a:hover,
4086 .nav-pills > li.active > a:focus {
4087 color: #fff;
4088 background-color: #337ab7;
4089 }
4090 .nav-stacked > li {
4091 float: none;
4092 }
4093 .nav-stacked > li + li {
4094 margin-top: 2px;
4095 margin-left: 0;
4096 }
4097 .nav-justified {
4098 width: 100%;
4099 }
4100 .nav-justified > li {
4101 float: none;
4102 }
4103 .nav-justified > li > a {
4104 text-align: center;
4105 margin-bottom: 5px;
4106 }
4107 .nav-justified > .dropdown .dropdown-menu {
4108 top: auto;
4109 left: auto;
4110 }
4111 @media (min-width: 768px) {
4112 .nav-justified > li {
4113 display: table-cell;
4114 width: 1%;
4115 }
4116 .nav-justified > li > a {
4117 margin-bottom: 0;
4118 }
4119 }
4120 .nav-tabs-justified {
4121 border-bottom: 0;
4122 }
4123 .nav-tabs-justified > li > a {
4124 margin-right: 0;
4125 border-radius: 2px;
4126 }
4127 .nav-tabs-justified > .active > a,
4128 .nav-tabs-justified > .active > a:hover,
4129 .nav-tabs-justified > .active > a:focus {
4130 border: 1px solid #ddd;
4131 }
4132 @media (min-width: 768px) {
4133 .nav-tabs-justified > li > a {
4134 border-bottom: 1px solid #ddd;
4135 border-radius: 2px 2px 0 0;
4136 }
4137 .nav-tabs-justified > .active > a,
4138 .nav-tabs-justified > .active > a:hover,
4139 .nav-tabs-justified > .active > a:focus {
4140 border-bottom-color: #fff;
4141 }
4142 }
4143 .tab-content > .tab-pane {
4144 display: none;
4145 }
4146 .tab-content > .active {
4147 display: block;
4148 }
4149 .nav-tabs .dropdown-menu {
4150 margin-top: -1px;
4151 border-top-right-radius: 0;
4152 border-top-left-radius: 0;
4153 }
4154 .navbar {
4155 position: relative;
4156 min-height: 30px;
4157 margin-bottom: 18px;
4158 border: 1px solid transparent;
4159 }
4160 @media (min-width: 541px) {
4161 .navbar {
4162 border-radius: 2px;
4163 }
4164 }
4165 @media (min-width: 541px) {
4166 .navbar-header {
4167 float: left;
4168 }
4169 }
4170 .navbar-collapse {
4171 overflow-x: visible;
4172 padding-right: 0px;
4173 padding-left: 0px;
4174 border-top: 1px solid transparent;
4175 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
4176 -webkit-overflow-scrolling: touch;
4177 }
4178 .navbar-collapse.in {
4179 overflow-y: auto;
4180 }
4181 @media (min-width: 541px) {
4182 .navbar-collapse {
4183 width: auto;
4184 border-top: 0;
4185 box-shadow: none;
4186 }
4187 .navbar-collapse.collapse {
4188 display: block !important;
4189 height: auto !important;
4190 padding-bottom: 0;
4191 overflow: visible !important;
4192 }
4193 .navbar-collapse.in {
4194 overflow-y: visible;
4195 }
4196 .navbar-fixed-top .navbar-collapse,
4197 .navbar-static-top .navbar-collapse,
4198 .navbar-fixed-bottom .navbar-collapse {
4199 padding-left: 0;
4200 padding-right: 0;
4201 }
4202 }
4203 .navbar-fixed-top .navbar-collapse,
4204 .navbar-fixed-bottom .navbar-collapse {
4205 max-height: 340px;
4206 }
4207 @media (max-device-width: 540px) and (orientation: landscape) {
4208 .navbar-fixed-top .navbar-collapse,
4209 .navbar-fixed-bottom .navbar-collapse {
4210 max-height: 200px;
4211 }
4212 }
4213 .container > .navbar-header,
4214 .container-fluid > .navbar-header,
4215 .container > .navbar-collapse,
4216 .container-fluid > .navbar-collapse {
4217 margin-right: 0px;
4218 margin-left: 0px;
4219 }
4220 @media (min-width: 541px) {
4221 .container > .navbar-header,
4222 .container-fluid > .navbar-header,
4223 .container > .navbar-collapse,
4224 .container-fluid > .navbar-collapse {
4225 margin-right: 0;
4226 margin-left: 0;
4227 }
4228 }
4229 .navbar-static-top {
4230 z-index: 1000;
4231 border-width: 0 0 1px;
4232 }
4233 @media (min-width: 541px) {
4234 .navbar-static-top {
4235 border-radius: 0;
4236 }
4237 }
4238 .navbar-fixed-top,
4239 .navbar-fixed-bottom {
4240 position: fixed;
4241 right: 0;
4242 left: 0;
4243 z-index: 1030;
4244 }
4245 @media (min-width: 541px) {
4246 .navbar-fixed-top,
4247 .navbar-fixed-bottom {
4248 border-radius: 0;
4249 }
4250 }
4251 .navbar-fixed-top {
4252 top: 0;
4253 border-width: 0 0 1px;
4254 }
4255 .navbar-fixed-bottom {
4256 bottom: 0;
4257 margin-bottom: 0;
4258 border-width: 1px 0 0;
4259 }
4260 .navbar-brand {
4261 float: left;
4262 padding: 6px 0px;
4263 font-size: 17px;
4264 line-height: 18px;
4265 height: 30px;
4266 }
4267 .navbar-brand:hover,
4268 .navbar-brand:focus {
4269 text-decoration: none;
4270 }
4271 .navbar-brand > img {
4272 display: block;
4273 }
4274 @media (min-width: 541px) {
4275 .navbar > .container .navbar-brand,
4276 .navbar > .container-fluid .navbar-brand {
4277 margin-left: 0px;
4278 }
4279 }
4280 .navbar-toggle {
4281 position: relative;
4282 float: right;
4283 margin-right: 0px;
4284 padding: 9px 10px;
4285 margin-top: -2px;
4286 margin-bottom: -2px;
4287 background-color: transparent;
4288 background-image: none;
4289 border: 1px solid transparent;
4290 border-radius: 2px;
4291 }
4292 .navbar-toggle:focus {
4293 outline: 0;
4294 }
4295 .navbar-toggle .icon-bar {
4296 display: block;
4297 width: 22px;
4298 height: 2px;
4299 border-radius: 1px;
4300 }
4301 .navbar-toggle .icon-bar + .icon-bar {
4302 margin-top: 4px;
4303 }
4304 @media (min-width: 541px) {
4305 .navbar-toggle {
4306 display: none;
4307 }
4308 }
4309 .navbar-nav {
4310 margin: 3px 0px;
4311 }
4312 .navbar-nav > li > a {
4313 padding-top: 10px;
4314 padding-bottom: 10px;
4315 line-height: 18px;
4316 }
4317 @media (max-width: 540px) {
4318 .navbar-nav .open .dropdown-menu {
4319 position: static;
4320 float: none;
4321 width: auto;
4322 margin-top: 0;
4323 background-color: transparent;
4324 border: 0;
4325 box-shadow: none;
4326 }
4327 .navbar-nav .open .dropdown-menu > li > a,
4328 .navbar-nav .open .dropdown-menu .dropdown-header {
4329 padding: 5px 15px 5px 25px;
4330 }
4331 .navbar-nav .open .dropdown-menu > li > a {
4332 line-height: 18px;
4333 }
4334 .navbar-nav .open .dropdown-menu > li > a:hover,
4335 .navbar-nav .open .dropdown-menu > li > a:focus {
4336 background-image: none;
4337 }
4338 }
4339 @media (min-width: 541px) {
4340 .navbar-nav {
4341 float: left;
4342 margin: 0;
4343 }
4344 .navbar-nav > li {
4345 float: left;
4346 }
4347 .navbar-nav > li > a {
4348 padding-top: 6px;
4349 padding-bottom: 6px;
4350 }
4351 }
4352 .navbar-form {
4353 margin-left: 0px;
4354 margin-right: 0px;
4355 padding: 10px 0px;
4356 border-top: 1px solid transparent;
4357 border-bottom: 1px solid transparent;
4358 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
4359 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
4360 margin-top: -1px;
4361 margin-bottom: -1px;
4362 }
4363 @media (min-width: 768px) {
4364 .navbar-form .form-group {
4365 display: inline-block;
4366 margin-bottom: 0;
4367 vertical-align: middle;
4368 }
4369 .navbar-form .form-control {
4370 display: inline-block;
4371 width: auto;
4372 vertical-align: middle;
4373 }
4374 .navbar-form .form-control-static {
4375 display: inline-block;
4376 }
4377 .navbar-form .input-group {
4378 display: inline-table;
4379 vertical-align: middle;
4380 }
4381 .navbar-form .input-group .input-group-addon,
4382 .navbar-form .input-group .input-group-btn,
4383 .navbar-form .input-group .form-control {
4384 width: auto;
4385 }
4386 .navbar-form .input-group > .form-control {
4387 width: 100%;
4388 }
4389 .navbar-form .control-label {
4390 margin-bottom: 0;
4391 vertical-align: middle;
4392 }
4393 .navbar-form .radio,
4394 .navbar-form .checkbox {
4395 display: inline-block;
4396 margin-top: 0;
4397 margin-bottom: 0;
4398 vertical-align: middle;
4399 }
4400 .navbar-form .radio label,
4401 .navbar-form .checkbox label {
4402 padding-left: 0;
4403 }
4404 .navbar-form .radio input[type="radio"],
4405 .navbar-form .checkbox input[type="checkbox"] {
4406 position: relative;
4407 margin-left: 0;
4408 }
4409 .navbar-form .has-feedback .form-control-feedback {
4410 top: 0;
4411 }
4412 }
4413 @media (max-width: 540px) {
4414 .navbar-form .form-group {
4415 margin-bottom: 5px;
4416 }
4417 .navbar-form .form-group:last-child {
4418 margin-bottom: 0;
4419 }
4420 }
4421 @media (min-width: 541px) {
4422 .navbar-form {
4423 width: auto;
4424 border: 0;
4425 margin-left: 0;
4426 margin-right: 0;
4427 padding-top: 0;
4428 padding-bottom: 0;
4429 -webkit-box-shadow: none;
4430 box-shadow: none;
4431 }
4432 }
4433 .navbar-nav > li > .dropdown-menu {
4434 margin-top: 0;
4435 border-top-right-radius: 0;
4436 border-top-left-radius: 0;
4437 }
4438 .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
4439 margin-bottom: 0;
4440 border-top-right-radius: 2px;
4441 border-top-left-radius: 2px;
4442 border-bottom-right-radius: 0;
4443 border-bottom-left-radius: 0;
4444 }
4445 .navbar-btn {
4446 margin-top: -1px;
4447 margin-bottom: -1px;
4448 }
4449 .navbar-btn.btn-sm {
4450 margin-top: 0px;
4451 margin-bottom: 0px;
4452 }
4453 .navbar-btn.btn-xs {
4454 margin-top: 4px;
4455 margin-bottom: 4px;
4456 }
4457 .navbar-text {
4458 margin-top: 6px;
4459 margin-bottom: 6px;
4460 }
4461 @media (min-width: 541px) {
4462 .navbar-text {
4463 float: left;
4464 margin-left: 0px;
4465 margin-right: 0px;
4466 }
4467 }
4468 @media (min-width: 541px) {
4469 .navbar-left {
4470 float: left !important;
4471 float: left;
4472 }
4473 .navbar-right {
4474 float: right !important;
4475 float: right;
4476 margin-right: 0px;
4477 }
4478 .navbar-right ~ .navbar-right {
4479 margin-right: 0;
4480 }
4481 }
4482 .navbar-default {
4483 background-color: #f8f8f8;
4484 border-color: #e7e7e7;
4485 }
4486 .navbar-default .navbar-brand {
4487 color: #777;
4488 }
4489 .navbar-default .navbar-brand:hover,
4490 .navbar-default .navbar-brand:focus {
4491 color: #5e5e5e;
4492 background-color: transparent;
4493 }
4494 .navbar-default .navbar-text {
4495 color: #777;
4496 }
4497 .navbar-default .navbar-nav > li > a {
4498 color: #777;
4499 }
4500 .navbar-default .navbar-nav > li > a:hover,
4501 .navbar-default .navbar-nav > li > a:focus {
4502 color: #333;
4503 background-color: transparent;
4504 }
4505 .navbar-default .navbar-nav > .active > a,
4506 .navbar-default .navbar-nav > .active > a:hover,
4507 .navbar-default .navbar-nav > .active > a:focus {
4508 color: #555;
4509 background-color: #e7e7e7;
4510 }
4511 .navbar-default .navbar-nav > .disabled > a,
4512 .navbar-default .navbar-nav > .disabled > a:hover,
4513 .navbar-default .navbar-nav > .disabled > a:focus {
4514 color: #ccc;
4515 background-color: transparent;
4516 }
4517 .navbar-default .navbar-toggle {
4518 border-color: #ddd;
4519 }
4520 .navbar-default .navbar-toggle:hover,
4521 .navbar-default .navbar-toggle:focus {
4522 background-color: #ddd;
4523 }
4524 .navbar-default .navbar-toggle .icon-bar {
4525 background-color: #888;
4526 }
4527 .navbar-default .navbar-collapse,
4528 .navbar-default .navbar-form {
4529 border-color: #e7e7e7;
4530 }
4531 .navbar-default .navbar-nav > .open > a,
4532 .navbar-default .navbar-nav > .open > a:hover,
4533 .navbar-default .navbar-nav > .open > a:focus {
4534 background-color: #e7e7e7;
4535 color: #555;
4536 }
4537 @media (max-width: 540px) {
4538 .navbar-default .navbar-nav .open .dropdown-menu > li > a {
4539 color: #777;
4540 }
4541 .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
4542 .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
4543 color: #333;
4544 background-color: transparent;
4545 }
4546 .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
4547 .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
4548 .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
4549 color: #555;
4550 background-color: #e7e7e7;
4551 }
4552 .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
4553 .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
4554 .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
4555 color: #ccc;
4556 background-color: transparent;
4557 }
4558 }
4559 .navbar-default .navbar-link {
4560 color: #777;
4561 }
4562 .navbar-default .navbar-link:hover {
4563 color: #333;
4564 }
4565 .navbar-default .btn-link {
4566 color: #777;
4567 }
4568 .navbar-default .btn-link:hover,
4569 .navbar-default .btn-link:focus {
4570 color: #333;
4571 }
4572 .navbar-default .btn-link[disabled]:hover,
4573 fieldset[disabled] .navbar-default .btn-link:hover,
4574 .navbar-default .btn-link[disabled]:focus,
4575 fieldset[disabled] .navbar-default .btn-link:focus {
4576 color: #ccc;
4577 }
4578 .navbar-inverse {
4579 background-color: #222;
4580 border-color: #080808;
4581 }
4582 .navbar-inverse .navbar-brand {
4583 color: #9d9d9d;
4584 }
4585 .navbar-inverse .navbar-brand:hover,
4586 .navbar-inverse .navbar-brand:focus {
4587 color: #fff;
4588 background-color: transparent;
4589 }
4590 .navbar-inverse .navbar-text {
4591 color: #9d9d9d;
4592 }
4593 .navbar-inverse .navbar-nav > li > a {
4594 color: #9d9d9d;
4595 }
4596 .navbar-inverse .navbar-nav > li > a:hover,
4597 .navbar-inverse .navbar-nav > li > a:focus {
4598 color: #fff;
4599 background-color: transparent;
4600 }
4601 .navbar-inverse .navbar-nav > .active > a,
4602 .navbar-inverse .navbar-nav > .active > a:hover,
4603 .navbar-inverse .navbar-nav > .active > a:focus {
4604 color: #fff;
4605 background-color: #080808;
4606 }
4607 .navbar-inverse .navbar-nav > .disabled > a,
4608 .navbar-inverse .navbar-nav > .disabled > a:hover,
4609 .navbar-inverse .navbar-nav > .disabled > a:focus {
4610 color: #444;
4611 background-color: transparent;
4612 }
4613 .navbar-inverse .navbar-toggle {
4614 border-color: #333;
4615 }
4616 .navbar-inverse .navbar-toggle:hover,
4617 .navbar-inverse .navbar-toggle:focus {
4618 background-color: #333;
4619 }
4620 .navbar-inverse .navbar-toggle .icon-bar {
4621 background-color: #fff;
4622 }
4623 .navbar-inverse .navbar-collapse,
4624 .navbar-inverse .navbar-form {
4625 border-color: #101010;
4626 }
4627 .navbar-inverse .navbar-nav > .open > a,
4628 .navbar-inverse .navbar-nav > .open > a:hover,
4629 .navbar-inverse .navbar-nav > .open > a:focus {
4630 background-color: #080808;
4631 color: #fff;
4632 }
4633 @media (max-width: 540px) {
4634 .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
4635 border-color: #080808;
4636 }
4637 .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
4638 background-color: #080808;
4639 }
4640 .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
4641 color: #9d9d9d;
4642 }
4643 .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
4644 .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
4645 color: #fff;
4646 background-color: transparent;
4647 }
4648 .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
4649 .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
4650 .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
4651 color: #fff;
4652 background-color: #080808;
4653 }
4654 .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
4655 .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
4656 .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
4657 color: #444;
4658 background-color: transparent;
4659 }
4660 }
4661 .navbar-inverse .navbar-link {
4662 color: #9d9d9d;
4663 }
4664 .navbar-inverse .navbar-link:hover {
4665 color: #fff;
4666 }
4667 .navbar-inverse .btn-link {
4668 color: #9d9d9d;
4669 }
4670 .navbar-inverse .btn-link:hover,
4671 .navbar-inverse .btn-link:focus {
4672 color: #fff;
4673 }
4674 .navbar-inverse .btn-link[disabled]:hover,
4675 fieldset[disabled] .navbar-inverse .btn-link:hover,
4676 .navbar-inverse .btn-link[disabled]:focus,
4677 fieldset[disabled] .navbar-inverse .btn-link:focus {
4678 color: #444;
4679 }
4680 .breadcrumb {
4681 padding: 8px 15px;
4682 margin-bottom: 18px;
4683 list-style: none;
4684 background-color: #f5f5f5;
4685 border-radius: 2px;
4686 }
4687 .breadcrumb > li {
4688 display: inline-block;
4689 }
4690 .breadcrumb > li + li:before {
4691 content: "/\00a0";
4692 padding: 0 5px;
4693 color: #5e5e5e;
4694 }
4695 .breadcrumb > .active {
4696 color: #777777;
4697 }
4698 .pagination {
4699 display: inline-block;
4700 padding-left: 0;
4701 margin: 18px 0;
4702 border-radius: 2px;
4703 }
4704 .pagination > li {
4705 display: inline;
4706 }
4707 .pagination > li > a,
4708 .pagination > li > span {
4709 position: relative;
4710 float: left;
4711 padding: 6px 12px;
4712 line-height: 1.42857143;
4713 text-decoration: none;
4714 color: #337ab7;
4715 background-color: #fff;
4716 border: 1px solid #ddd;
4717 margin-left: -1px;
4718 }
4719 .pagination > li:first-child > a,
4720 .pagination > li:first-child > span {
4721 margin-left: 0;
4722 border-bottom-left-radius: 2px;
4723 border-top-left-radius: 2px;
4724 }
4725 .pagination > li:last-child > a,
4726 .pagination > li:last-child > span {
4727 border-bottom-right-radius: 2px;
4728 border-top-right-radius: 2px;
4729 }
4730 .pagination > li > a:hover,
4731 .pagination > li > span:hover,
4732 .pagination > li > a:focus,
4733 .pagination > li > span:focus {
4734 z-index: 2;
4735 color: #23527c;
4736 background-color: #eeeeee;
4737 border-color: #ddd;
4738 }
4739 .pagination > .active > a,
4740 .pagination > .active > span,
4741 .pagination > .active > a:hover,
4742 .pagination > .active > span:hover,
4743 .pagination > .active > a:focus,
4744 .pagination > .active > span:focus {
4745 z-index: 3;
4746 color: #fff;
4747 background-color: #337ab7;
4748 border-color: #337ab7;
4749 cursor: default;
4750 }
4751 .pagination > .disabled > span,
4752 .pagination > .disabled > span:hover,
4753 .pagination > .disabled > span:focus,
4754 .pagination > .disabled > a,
4755 .pagination > .disabled > a:hover,
4756 .pagination > .disabled > a:focus {
4757 color: #777777;
4758 background-color: #fff;
4759 border-color: #ddd;
4760 cursor: not-allowed;
4761 }
4762 .pagination-lg > li > a,
4763 .pagination-lg > li > span {
4764 padding: 10px 16px;
4765 font-size: 17px;
4766 line-height: 1.3333333;
4767 }
4768 .pagination-lg > li:first-child > a,
4769 .pagination-lg > li:first-child > span {
4770 border-bottom-left-radius: 3px;
4771 border-top-left-radius: 3px;
4772 }
4773 .pagination-lg > li:last-child > a,
4774 .pagination-lg > li:last-child > span {
4775 border-bottom-right-radius: 3px;
4776 border-top-right-radius: 3px;
4777 }
4778 .pagination-sm > li > a,
4779 .pagination-sm > li > span {
4780 padding: 5px 10px;
4781 font-size: 12px;
4782 line-height: 1.5;
4783 }
4784 .pagination-sm > li:first-child > a,
4785 .pagination-sm > li:first-child > span {
4786 border-bottom-left-radius: 1px;
4787 border-top-left-radius: 1px;
4788 }
4789 .pagination-sm > li:last-child > a,
4790 .pagination-sm > li:last-child > span {
4791 border-bottom-right-radius: 1px;
4792 border-top-right-radius: 1px;
4793 }
4794 .pager {
4795 padding-left: 0;
4796 margin: 18px 0;
4797 list-style: none;
4798 text-align: center;
4799 }
4800 .pager li {
4801 display: inline;
4802 }
4803 .pager li > a,
4804 .pager li > span {
4805 display: inline-block;
4806 padding: 5px 14px;
4807 background-color: #fff;
4808 border: 1px solid #ddd;
4809 border-radius: 15px;
4810 }
4811 .pager li > a:hover,
4812 .pager li > a:focus {
4813 text-decoration: none;
4814 background-color: #eeeeee;
4815 }
4816 .pager .next > a,
4817 .pager .next > span {
4818 float: right;
4819 }
4820 .pager .previous > a,
4821 .pager .previous > span {
4822 float: left;
4823 }
4824 .pager .disabled > a,
4825 .pager .disabled > a:hover,
4826 .pager .disabled > a:focus,
4827 .pager .disabled > span {
4828 color: #777777;
4829 background-color: #fff;
4830 cursor: not-allowed;
4831 }
4832 .label {
4833 display: inline;
4834 padding: .2em .6em .3em;
4835 font-size: 75%;
4836 font-weight: bold;
4837 line-height: 1;
4838 color: #fff;
4839 text-align: center;
4840 white-space: nowrap;
4841 vertical-align: baseline;
4842 border-radius: .25em;
4843 }
4844 a.label:hover,
4845 a.label:focus {
4846 color: #fff;
4847 text-decoration: none;
4848 cursor: pointer;
4849 }
4850 .label:empty {
4851 display: none;
4852 }
4853 .btn .label {
4854 position: relative;
4855 top: -1px;
4856 }
4857 .label-default {
4858 background-color: #777777;
4859 }
4860 .label-default[href]:hover,
4861 .label-default[href]:focus {
4862 background-color: #5e5e5e;
4863 }
4864 .label-primary {
4865 background-color: #337ab7;
4866 }
4867 .label-primary[href]:hover,
4868 .label-primary[href]:focus {
4869 background-color: #286090;
4870 }
4871 .label-success {
4872 background-color: #5cb85c;
4873 }
4874 .label-success[href]:hover,
4875 .label-success[href]:focus {
4876 background-color: #449d44;
4877 }
4878 .label-info {
4879 background-color: #5bc0de;
4880 }
4881 .label-info[href]:hover,
4882 .label-info[href]:focus {
4883 background-color: #31b0d5;
4884 }
4885 .label-warning {
4886 background-color: #f0ad4e;
4887 }
4888 .label-warning[href]:hover,
4889 .label-warning[href]:focus {
4890 background-color: #ec971f;
4891 }
4892 .label-danger {
4893 background-color: #d9534f;
4894 }
4895 .label-danger[href]:hover,
4896 .label-danger[href]:focus {
4897 background-color: #c9302c;
4898 }
4899 .badge {
4900 display: inline-block;
4901 min-width: 10px;
4902 padding: 3px 7px;
4903 font-size: 12px;
4904 font-weight: bold;
4905 color: #fff;
4906 line-height: 1;
4907 vertical-align: middle;
4908 white-space: nowrap;
4909 text-align: center;
4910 background-color: #777777;
4911 border-radius: 10px;
4912 }
4913 .badge:empty {
4914 display: none;
4915 }
4916 .btn .badge {
4917 position: relative;
4918 top: -1px;
4919 }
4920 .btn-xs .badge,
4921 .btn-group-xs > .btn .badge {
4922 top: 0;
4923 padding: 1px 5px;
4924 }
4925 a.badge:hover,
4926 a.badge:focus {
4927 color: #fff;
4928 text-decoration: none;
4929 cursor: pointer;
4930 }
4931 .list-group-item.active > .badge,
4932 .nav-pills > .active > a > .badge {
4933 color: #337ab7;
4934 background-color: #fff;
4935 }
4936 .list-group-item > .badge {
4937 float: right;
4938 }
4939 .list-group-item > .badge + .badge {
4940 margin-right: 5px;
4941 }
4942 .nav-pills > li > a > .badge {
4943 margin-left: 3px;
4944 }
4945 .jumbotron {
4946 padding-top: 30px;
4947 padding-bottom: 30px;
4948 margin-bottom: 30px;
4949 color: inherit;
4950 background-color: #eeeeee;
4951 }
4952 .jumbotron h1,
4953 .jumbotron .h1 {
4954 color: inherit;
4955 }
4956 .jumbotron p {
4957 margin-bottom: 15px;
4958 font-size: 20px;
4959 font-weight: 200;
4960 }
4961 .jumbotron > hr {
4962 border-top-color: #d5d5d5;
4963 }
4964 .container .jumbotron,
4965 .container-fluid .jumbotron {
4966 border-radius: 3px;
4967 padding-left: 0px;
4968 padding-right: 0px;
4969 }
4970 .jumbotron .container {
4971 max-width: 100%;
4972 }
4973 @media screen and (min-width: 768px) {
4974 .jumbotron {
4975 padding-top: 48px;
4976 padding-bottom: 48px;
4977 }
4978 .container .jumbotron,
4979 .container-fluid .jumbotron {
4980 padding-left: 60px;
4981 padding-right: 60px;
4982 }
4983 .jumbotron h1,
4984 .jumbotron .h1 {
4985 font-size: 59px;
4986 }
4987 }
4988 .thumbnail {
4989 display: block;
4990 padding: 4px;
4991 margin-bottom: 18px;
4992 line-height: 1.42857143;
4993 background-color: #fff;
4994 border: 1px solid #ddd;
4995 border-radius: 2px;
4996 -webkit-transition: border 0.2s ease-in-out;
4997 -o-transition: border 0.2s ease-in-out;
4998 transition: border 0.2s ease-in-out;
4999 }
5000 .thumbnail > img,
5001 .thumbnail a > img {
5002 margin-left: auto;
5003 margin-right: auto;
5004 }
5005 a.thumbnail:hover,
5006 a.thumbnail:focus,
5007 a.thumbnail.active {
5008 border-color: #337ab7;
5009 }
5010 .thumbnail .caption {
5011 padding: 9px;
5012 color: #000;
5013 }
5014 .alert {
5015 padding: 15px;
5016 margin-bottom: 18px;
5017 border: 1px solid transparent;
5018 border-radius: 2px;
5019 }
5020 .alert h4 {
5021 margin-top: 0;
5022 color: inherit;
5023 }
5024 .alert .alert-link {
5025 font-weight: bold;
5026 }
5027 .alert > p,
5028 .alert > ul {
5029 margin-bottom: 0;
5030 }
5031 .alert > p + p {
5032 margin-top: 5px;
5033 }
5034 .alert-dismissable,
5035 .alert-dismissible {
5036 padding-right: 35px;
5037 }
5038 .alert-dismissable .close,
5039 .alert-dismissible .close {
5040 position: relative;
5041 top: -2px;
5042 right: -21px;
5043 color: inherit;
5044 }
5045 .alert-success {
5046 background-color: #dff0d8;
5047 border-color: #d6e9c6;
5048 color: #3c763d;
5049 }
5050 .alert-success hr {
5051 border-top-color: #c9e2b3;
5052 }
5053 .alert-success .alert-link {
5054 color: #2b542c;
5055 }
5056 .alert-info {
5057 background-color: #d9edf7;
5058 border-color: #bce8f1;
5059 color: #31708f;
5060 }
5061 .alert-info hr {
5062 border-top-color: #a6e1ec;
5063 }
5064 .alert-info .alert-link {
5065 color: #245269;
5066 }
5067 .alert-warning {
5068 background-color: #fcf8e3;
5069 border-color: #faebcc;
5070 color: #8a6d3b;
5071 }
5072 .alert-warning hr {
5073 border-top-color: #f7e1b5;
5074 }
5075 .alert-warning .alert-link {
5076 color: #66512c;
5077 }
5078 .alert-danger {
5079 background-color: #f2dede;
5080 border-color: #ebccd1;
5081 color: #a94442;
5082 }
5083 .alert-danger hr {
5084 border-top-color: #e4b9c0;
5085 }
5086 .alert-danger .alert-link {
5087 color: #843534;
5088 }
5089 @-webkit-keyframes progress-bar-stripes {
5090 from {
5091 background-position: 40px 0;
5092 }
5093 to {
5094 background-position: 0 0;
5095 }
5096 }
5097 @keyframes progress-bar-stripes {
5098 from {
5099 background-position: 40px 0;
5100 }
5101 to {
5102 background-position: 0 0;
5103 }
5104 }
5105 .progress {
5106 overflow: hidden;
5107 height: 18px;
5108 margin-bottom: 18px;
5109 background-color: #f5f5f5;
5110 border-radius: 2px;
5111 -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
5112 box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
5113 }
5114 .progress-bar {
5115 float: left;
5116 width: 0%;
5117 height: 100%;
5118 font-size: 12px;
5119 line-height: 18px;
5120 color: #fff;
5121 text-align: center;
5122 background-color: #337ab7;
5123 -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
5124 box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
5125 -webkit-transition: width 0.6s ease;
5126 -o-transition: width 0.6s ease;
5127 transition: width 0.6s ease;
5128 }
5129 .progress-striped .progress-bar,
5130 .progress-bar-striped {
5131 background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5132 background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5133 background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5134 background-size: 40px 40px;
5135 }
5136 .progress.active .progress-bar,
5137 .progress-bar.active {
5138 -webkit-animation: progress-bar-stripes 2s linear infinite;
5139 -o-animation: progress-bar-stripes 2s linear infinite;
5140 animation: progress-bar-stripes 2s linear infinite;
5141 }
5142 .progress-bar-success {
5143 background-color: #5cb85c;
5144 }
5145 .progress-striped .progress-bar-success {
5146 background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5147 background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5148 background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5149 }
5150 .progress-bar-info {
5151 background-color: #5bc0de;
5152 }
5153 .progress-striped .progress-bar-info {
5154 background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5155 background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5156 background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5157 }
5158 .progress-bar-warning {
5159 background-color: #f0ad4e;
5160 }
5161 .progress-striped .progress-bar-warning {
5162 background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5163 background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5164 background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5165 }
5166 .progress-bar-danger {
5167 background-color: #d9534f;
5168 }
5169 .progress-striped .progress-bar-danger {
5170 background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5171 background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5172 background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
5173 }
5174 .media {
5175 margin-top: 15px;
5176 }
5177 .media:first-child {
5178 margin-top: 0;
5179 }
5180 .media,
5181 .media-body {
5182 zoom: 1;
5183 overflow: hidden;
5184 }
5185 .media-body {
5186 width: 10000px;
5187 }
5188 .media-object {
5189 display: block;
5190 }
5191 .media-object.img-thumbnail {
5192 max-width: none;
5193 }
5194 .media-right,
5195 .media > .pull-right {
5196 padding-left: 10px;
5197 }
5198 .media-left,
5199 .media > .pull-left {
5200 padding-right: 10px;
5201 }
5202 .media-left,
5203 .media-right,
5204 .media-body {
5205 display: table-cell;
5206 vertical-align: top;
5207 }
5208 .media-middle {
5209 vertical-align: middle;
5210 }
5211 .media-bottom {
5212 vertical-align: bottom;
5213 }
5214 .media-heading {
5215 margin-top: 0;
5216 margin-bottom: 5px;
5217 }
5218 .media-list {
5219 padding-left: 0;
5220 list-style: none;
5221 }
5222 .list-group {
5223 margin-bottom: 20px;
5224 padding-left: 0;
5225 }
5226 .list-group-item {
5227 position: relative;
5228 display: block;
5229 padding: 10px 15px;
5230 margin-bottom: -1px;
5231 background-color: #fff;
5232 border: 1px solid #ddd;
5233 }
5234 .list-group-item:first-child {
5235 border-top-right-radius: 2px;
5236 border-top-left-radius: 2px;
5237 }
5238 .list-group-item:last-child {
5239 margin-bottom: 0;
5240 border-bottom-right-radius: 2px;
5241 border-bottom-left-radius: 2px;
5242 }
5243 a.list-group-item,
5244 button.list-group-item {
5245 color: #555;
5246 }
5247 a.list-group-item .list-group-item-heading,
5248 button.list-group-item .list-group-item-heading {
5249 color: #333;
5250 }
5251 a.list-group-item:hover,
5252 button.list-group-item:hover,
5253 a.list-group-item:focus,
5254 button.list-group-item:focus {
5255 text-decoration: none;
5256 color: #555;
5257 background-color: #f5f5f5;
5258 }
5259 button.list-group-item {
5260 width: 100%;
5261 text-align: left;
5262 }
5263 .list-group-item.disabled,
5264 .list-group-item.disabled:hover,
5265 .list-group-item.disabled:focus {
5266 background-color: #eeeeee;
5267 color: #777777;
5268 cursor: not-allowed;
5269 }
5270 .list-group-item.disabled .list-group-item-heading,
5271 .list-group-item.disabled:hover .list-group-item-heading,
5272 .list-group-item.disabled:focus .list-group-item-heading {
5273 color: inherit;
5274 }
5275 .list-group-item.disabled .list-group-item-text,
5276 .list-group-item.disabled:hover .list-group-item-text,
5277 .list-group-item.disabled:focus .list-group-item-text {
5278 color: #777777;
5279 }
5280 .list-group-item.active,
5281 .list-group-item.active:hover,
5282 .list-group-item.active:focus {
5283 z-index: 2;
5284 color: #fff;
5285 background-color: #337ab7;
5286 border-color: #337ab7;
5287 }
5288 .list-group-item.active .list-group-item-heading,
5289 .list-group-item.active:hover .list-group-item-heading,
5290 .list-group-item.active:focus .list-group-item-heading,
5291 .list-group-item.active .list-group-item-heading > small,
5292 .list-group-item.active:hover .list-group-item-heading > small,
5293 .list-group-item.active:focus .list-group-item-heading > small,
5294 .list-group-item.active .list-group-item-heading > .small,
5295 .list-group-item.active:hover .list-group-item-heading > .small,
5296 .list-group-item.active:focus .list-group-item-heading > .small {
5297 color: inherit;
5298 }
5299 .list-group-item.active .list-group-item-text,
5300 .list-group-item.active:hover .list-group-item-text,
5301 .list-group-item.active:focus .list-group-item-text {
5302 color: #c7ddef;
5303 }
5304 .list-group-item-success {
5305 color: #3c763d;
5306 background-color: #dff0d8;
5307 }
5308 a.list-group-item-success,
5309 button.list-group-item-success {
5310 color: #3c763d;
5311 }
5312 a.list-group-item-success .list-group-item-heading,
5313 button.list-group-item-success .list-group-item-heading {
5314 color: inherit;
5315 }
5316 a.list-group-item-success:hover,
5317 button.list-group-item-success:hover,
5318 a.list-group-item-success:focus,
5319 button.list-group-item-success:focus {
5320 color: #3c763d;
5321 background-color: #d0e9c6;
5322 }
5323 a.list-group-item-success.active,
5324 button.list-group-item-success.active,
5325 a.list-group-item-success.active:hover,
5326 button.list-group-item-success.active:hover,
5327 a.list-group-item-success.active:focus,
5328 button.list-group-item-success.active:focus {
5329 color: #fff;
5330 background-color: #3c763d;
5331 border-color: #3c763d;
5332 }
5333 .list-group-item-info {
5334 color: #31708f;
5335 background-color: #d9edf7;
5336 }
5337 a.list-group-item-info,
5338 button.list-group-item-info {
5339 color: #31708f;
5340 }
5341 a.list-group-item-info .list-group-item-heading,
5342 button.list-group-item-info .list-group-item-heading {
5343 color: inherit;
5344 }
5345 a.list-group-item-info:hover,
5346 button.list-group-item-info:hover,
5347 a.list-group-item-info:focus,
5348 button.list-group-item-info:focus {
5349 color: #31708f;
5350 background-color: #c4e3f3;
5351 }
5352 a.list-group-item-info.active,
5353 button.list-group-item-info.active,
5354 a.list-group-item-info.active:hover,
5355 button.list-group-item-info.active:hover,
5356 a.list-group-item-info.active:focus,
5357 button.list-group-item-info.active:focus {
5358 color: #fff;
5359 background-color: #31708f;
5360 border-color: #31708f;
5361 }
5362 .list-group-item-warning {
5363 color: #8a6d3b;
5364 background-color: #fcf8e3;
5365 }
5366 a.list-group-item-warning,
5367 button.list-group-item-warning {
5368 color: #8a6d3b;
5369 }
5370 a.list-group-item-warning .list-group-item-heading,
5371 button.list-group-item-warning .list-group-item-heading {
5372 color: inherit;
5373 }
5374 a.list-group-item-warning:hover,
5375 button.list-group-item-warning:hover,
5376 a.list-group-item-warning:focus,
5377 button.list-group-item-warning:focus {
5378 color: #8a6d3b;
5379 background-color: #faf2cc;
5380 }
5381 a.list-group-item-warning.active,
5382 button.list-group-item-warning.active,
5383 a.list-group-item-warning.active:hover,
5384 button.list-group-item-warning.active:hover,
5385 a.list-group-item-warning.active:focus,
5386 button.list-group-item-warning.active:focus {
5387 color: #fff;
5388 background-color: #8a6d3b;
5389 border-color: #8a6d3b;
5390 }
5391 .list-group-item-danger {
5392 color: #a94442;
5393 background-color: #f2dede;
5394 }
5395 a.list-group-item-danger,
5396 button.list-group-item-danger {
5397 color: #a94442;
5398 }
5399 a.list-group-item-danger .list-group-item-heading,
5400 button.list-group-item-danger .list-group-item-heading {
5401 color: inherit;
5402 }
5403 a.list-group-item-danger:hover,
5404 button.list-group-item-danger:hover,
5405 a.list-group-item-danger:focus,
5406 button.list-group-item-danger:focus {
5407 color: #a94442;
5408 background-color: #ebcccc;
5409 }
5410 a.list-group-item-danger.active,
5411 button.list-group-item-danger.active,
5412 a.list-group-item-danger.active:hover,
5413 button.list-group-item-danger.active:hover,
5414 a.list-group-item-danger.active:focus,
5415 button.list-group-item-danger.active:focus {
5416 color: #fff;
5417 background-color: #a94442;
5418 border-color: #a94442;
5419 }
5420 .list-group-item-heading {
5421 margin-top: 0;
5422 margin-bottom: 5px;
5423 }
5424 .list-group-item-text {
5425 margin-bottom: 0;
5426 line-height: 1.3;
5427 }
5428 .panel {
5429 margin-bottom: 18px;
5430 background-color: #fff;
5431 border: 1px solid transparent;
5432 border-radius: 2px;
5433 -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
5434 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
5435 }
5436 .panel-body {
5437 padding: 15px;
5438 }
5439 .panel-heading {
5440 padding: 10px 15px;
5441 border-bottom: 1px solid transparent;
5442 border-top-right-radius: 1px;
5443 border-top-left-radius: 1px;
5444 }
5445 .panel-heading > .dropdown .dropdown-toggle {
5446 color: inherit;
5447 }
5448 .panel-title {
5449 margin-top: 0;
5450 margin-bottom: 0;
5451 font-size: 15px;
5452 color: inherit;
5453 }
5454 .panel-title > a,
5455 .panel-title > small,
5456 .panel-title > .small,
5457 .panel-title > small > a,
5458 .panel-title > .small > a {
5459 color: inherit;
5460 }
5461 .panel-footer {
5462 padding: 10px 15px;
5463 background-color: #f5f5f5;
5464 border-top: 1px solid #ddd;
5465 border-bottom-right-radius: 1px;
5466 border-bottom-left-radius: 1px;
5467 }
5468 .panel > .list-group,
5469 .panel > .panel-collapse > .list-group {
5470 margin-bottom: 0;
5471 }
5472 .panel > .list-group .list-group-item,
5473 .panel > .panel-collapse > .list-group .list-group-item {
5474 border-width: 1px 0;
5475 border-radius: 0;
5476 }
5477 .panel > .list-group:first-child .list-group-item:first-child,
5478 .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
5479 border-top: 0;
5480 border-top-right-radius: 1px;
5481 border-top-left-radius: 1px;
5482 }
5483 .panel > .list-group:last-child .list-group-item:last-child,
5484 .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
5485 border-bottom: 0;
5486 border-bottom-right-radius: 1px;
5487 border-bottom-left-radius: 1px;
5488 }
5489 .panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
5490 border-top-right-radius: 0;
5491 border-top-left-radius: 0;
5492 }
5493 .panel-heading + .list-group .list-group-item:first-child {
5494 border-top-width: 0;
5495 }
5496 .list-group + .panel-footer {
5497 border-top-width: 0;
5498 }
5499 .panel > .table,
5500 .panel > .table-responsive > .table,
5501 .panel > .panel-collapse > .table {
5502 margin-bottom: 0;
5503 }
5504 .panel > .table caption,
5505 .panel > .table-responsive > .table caption,
5506 .panel > .panel-collapse > .table caption {
5507 padding-left: 15px;
5508 padding-right: 15px;
5509 }
5510 .panel > .table:first-child,
5511 .panel > .table-responsive:first-child > .table:first-child {
5512 border-top-right-radius: 1px;
5513 border-top-left-radius: 1px;
5514 }
5515 .panel > .table:first-child > thead:first-child > tr:first-child,
5516 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
5517 .panel > .table:first-child > tbody:first-child > tr:first-child,
5518 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
5519 border-top-left-radius: 1px;
5520 border-top-right-radius: 1px;
5521 }
5522 .panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
5523 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
5524 .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
5525 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
5526 .panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
5527 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
5528 .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
5529 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
5530 border-top-left-radius: 1px;
5531 }
5532 .panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
5533 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
5534 .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
5535 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
5536 .panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
5537 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
5538 .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
5539 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
5540 border-top-right-radius: 1px;
5541 }
5542 .panel > .table:last-child,
5543 .panel > .table-responsive:last-child > .table:last-child {
5544 border-bottom-right-radius: 1px;
5545 border-bottom-left-radius: 1px;
5546 }
5547 .panel > .table:last-child > tbody:last-child > tr:last-child,
5548 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
5549 .panel > .table:last-child > tfoot:last-child > tr:last-child,
5550 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
5551 border-bottom-left-radius: 1px;
5552 border-bottom-right-radius: 1px;
5553 }
5554 .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
5555 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
5556 .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
5557 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
5558 .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
5559 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
5560 .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
5561 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
5562 border-bottom-left-radius: 1px;
5563 }
5564 .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
5565 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
5566 .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
5567 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
5568 .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
5569 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
5570 .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
5571 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
5572 border-bottom-right-radius: 1px;
5573 }
5574 .panel > .panel-body + .table,
5575 .panel > .panel-body + .table-responsive,
5576 .panel > .table + .panel-body,
5577 .panel > .table-responsive + .panel-body {
5578 border-top: 1px solid #ddd;
5579 }
5580 .panel > .table > tbody:first-child > tr:first-child th,
5581 .panel > .table > tbody:first-child > tr:first-child td {
5582 border-top: 0;
5583 }
5584 .panel > .table-bordered,
5585 .panel > .table-responsive > .table-bordered {
5586 border: 0;
5587 }
5588 .panel > .table-bordered > thead > tr > th:first-child,
5589 .panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
5590 .panel > .table-bordered > tbody > tr > th:first-child,
5591 .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
5592 .panel > .table-bordered > tfoot > tr > th:first-child,
5593 .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
5594 .panel > .table-bordered > thead > tr > td:first-child,
5595 .panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
5596 .panel > .table-bordered > tbody > tr > td:first-child,
5597 .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
5598 .panel > .table-bordered > tfoot > tr > td:first-child,
5599 .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
5600 border-left: 0;
5601 }
5602 .panel > .table-bordered > thead > tr > th:last-child,
5603 .panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
5604 .panel > .table-bordered > tbody > tr > th:last-child,
5605 .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
5606 .panel > .table-bordered > tfoot > tr > th:last-child,
5607 .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
5608 .panel > .table-bordered > thead > tr > td:last-child,
5609 .panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
5610 .panel > .table-bordered > tbody > tr > td:last-child,
5611 .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
5612 .panel > .table-bordered > tfoot > tr > td:last-child,
5613 .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
5614 border-right: 0;
5615 }
5616 .panel > .table-bordered > thead > tr:first-child > td,
5617 .panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
5618 .panel > .table-bordered > tbody > tr:first-child > td,
5619 .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
5620 .panel > .table-bordered > thead > tr:first-child > th,
5621 .panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
5622 .panel > .table-bordered > tbody > tr:first-child > th,
5623 .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
5624 border-bottom: 0;
5625 }
5626 .panel > .table-bordered > tbody > tr:last-child > td,
5627 .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
5628 .panel > .table-bordered > tfoot > tr:last-child > td,
5629 .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
5630 .panel > .table-bordered > tbody > tr:last-child > th,
5631 .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
5632 .panel > .table-bordered > tfoot > tr:last-child > th,
5633 .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
5634 border-bottom: 0;
5635 }
5636 .panel > .table-responsive {
5637 border: 0;
5638 margin-bottom: 0;
5639 }
5640 .panel-group {
5641 margin-bottom: 18px;
5642 }
5643 .panel-group .panel {
5644 margin-bottom: 0;
5645 border-radius: 2px;
5646 }
5647 .panel-group .panel + .panel {
5648 margin-top: 5px;
5649 }
5650 .panel-group .panel-heading {
5651 border-bottom: 0;
5652 }
5653 .panel-group .panel-heading + .panel-collapse > .panel-body,
5654 .panel-group .panel-heading + .panel-collapse > .list-group {
5655 border-top: 1px solid #ddd;
5656 }
5657 .panel-group .panel-footer {
5658 border-top: 0;
5659 }
5660 .panel-group .panel-footer + .panel-collapse .panel-body {
5661 border-bottom: 1px solid #ddd;
5662 }
5663 .panel-default {
5664 border-color: #ddd;
5665 }
5666 .panel-default > .panel-heading {
5667 color: #333333;
5668 background-color: #f5f5f5;
5669 border-color: #ddd;
5670 }
5671 .panel-default > .panel-heading + .panel-collapse > .panel-body {
5672 border-top-color: #ddd;
5673 }
5674 .panel-default > .panel-heading .badge {
5675 color: #f5f5f5;
5676 background-color: #333333;
5677 }
5678 .panel-default > .panel-footer + .panel-collapse > .panel-body {
5679 border-bottom-color: #ddd;
5680 }
5681 .panel-primary {
5682 border-color: #337ab7;
5683 }
5684 .panel-primary > .panel-heading {
5685 color: #fff;
5686 background-color: #337ab7;
5687 border-color: #337ab7;
5688 }
5689 .panel-primary > .panel-heading + .panel-collapse > .panel-body {
5690 border-top-color: #337ab7;
5691 }
5692 .panel-primary > .panel-heading .badge {
5693 color: #337ab7;
5694 background-color: #fff;
5695 }
5696 .panel-primary > .panel-footer + .panel-collapse > .panel-body {
5697 border-bottom-color: #337ab7;
5698 }
5699 .panel-success {
5700 border-color: #d6e9c6;
5701 }
5702 .panel-success > .panel-heading {
5703 color: #3c763d;
5704 background-color: #dff0d8;
5705 border-color: #d6e9c6;
5706 }
5707 .panel-success > .panel-heading + .panel-collapse > .panel-body {
5708 border-top-color: #d6e9c6;
5709 }
5710 .panel-success > .panel-heading .badge {
5711 color: #dff0d8;
5712 background-color: #3c763d;
5713 }
5714 .panel-success > .panel-footer + .panel-collapse > .panel-body {
5715 border-bottom-color: #d6e9c6;
5716 }
5717 .panel-info {
5718 border-color: #bce8f1;
5719 }
5720 .panel-info > .panel-heading {
5721 color: #31708f;
5722 background-color: #d9edf7;
5723 border-color: #bce8f1;
5724 }
5725 .panel-info > .panel-heading + .panel-collapse > .panel-body {
5726 border-top-color: #bce8f1;
5727 }
5728 .panel-info > .panel-heading .badge {
5729 color: #d9edf7;
5730 background-color: #31708f;
5731 }
5732 .panel-info > .panel-footer + .panel-collapse > .panel-body {
5733 border-bottom-color: #bce8f1;
5734 }
5735 .panel-warning {
5736 border-color: #faebcc;
5737 }
5738 .panel-warning > .panel-heading {
5739 color: #8a6d3b;
5740 background-color: #fcf8e3;
5741 border-color: #faebcc;
5742 }
5743 .panel-warning > .panel-heading + .panel-collapse > .panel-body {
5744 border-top-color: #faebcc;
5745 }
5746 .panel-warning > .panel-heading .badge {
5747 color: #fcf8e3;
5748 background-color: #8a6d3b;
5749 }
5750 .panel-warning > .panel-footer + .panel-collapse > .panel-body {
5751 border-bottom-color: #faebcc;
5752 }
5753 .panel-danger {
5754 border-color: #ebccd1;
5755 }
5756 .panel-danger > .panel-heading {
5757 color: #a94442;
5758 background-color: #f2dede;
5759 border-color: #ebccd1;
5760 }
5761 .panel-danger > .panel-heading + .panel-collapse > .panel-body {
5762 border-top-color: #ebccd1;
5763 }
5764 .panel-danger > .panel-heading .badge {
5765 color: #f2dede;
5766 background-color: #a94442;
5767 }
5768 .panel-danger > .panel-footer + .panel-collapse > .panel-body {
5769 border-bottom-color: #ebccd1;
5770 }
5771 .embed-responsive {
5772 position: relative;
5773 display: block;
5774 height: 0;
5775 padding: 0;
5776 overflow: hidden;
5777 }
5778 .embed-responsive .embed-responsive-item,
5779 .embed-responsive iframe,
5780 .embed-responsive embed,
5781 .embed-responsive object,
5782 .embed-responsive video {
5783 position: absolute;
5784 top: 0;
5785 left: 0;
5786 bottom: 0;
5787 height: 100%;
5788 width: 100%;
5789 border: 0;
5790 }
5791 .embed-responsive-16by9 {
5792 padding-bottom: 56.25%;
5793 }
5794 .embed-responsive-4by3 {
5795 padding-bottom: 75%;
5796 }
5797 .well {
5798 min-height: 20px;
5799 padding: 19px;
5800 margin-bottom: 20px;
5801 background-color: #f5f5f5;
5802 border: 1px solid #e3e3e3;
5803 border-radius: 2px;
5804 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
5805 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
5806 }
5807 .well blockquote {
5808 border-color: #ddd;
5809 border-color: rgba(0, 0, 0, 0.15);
5810 }
5811 .well-lg {
5812 padding: 24px;
5813 border-radius: 3px;
5814 }
5815 .well-sm {
5816 padding: 9px;
5817 border-radius: 1px;
5818 }
5819 .close {
5820 float: right;
5821 font-size: 19.5px;
5822 font-weight: bold;
5823 line-height: 1;
5824 color: #000;
5825 text-shadow: 0 1px 0 #fff;
5826 opacity: 0.2;
5827 filter: alpha(opacity=20);
5828 }
5829 .close:hover,
5830 .close:focus {
5831 color: #000;
5832 text-decoration: none;
5833 cursor: pointer;
5834 opacity: 0.5;
5835 filter: alpha(opacity=50);
5836 }
5837 button.close {
5838 padding: 0;
5839 cursor: pointer;
5840 background: transparent;
5841 border: 0;
5842 -webkit-appearance: none;
5843 }
5844 .modal-open {
5845 overflow: hidden;
5846 }
5847 .modal {
5848 display: none;
5849 overflow: hidden;
5850 position: fixed;
5851 top: 0;
5852 right: 0;
5853 bottom: 0;
5854 left: 0;
5855 z-index: 1050;
5856 -webkit-overflow-scrolling: touch;
5857 outline: 0;
5858 }
5859 .modal.fade .modal-dialog {
5860 -webkit-transform: translate(0, -25%);
5861 -ms-transform: translate(0, -25%);
5862 -o-transform: translate(0, -25%);
5863 transform: translate(0, -25%);
5864 -webkit-transition: -webkit-transform 0.3s ease-out;
5865 -moz-transition: -moz-transform 0.3s ease-out;
5866 -o-transition: -o-transform 0.3s ease-out;
5867 transition: transform 0.3s ease-out;
5868 }
5869 .modal.in .modal-dialog {
5870 -webkit-transform: translate(0, 0);
5871 -ms-transform: translate(0, 0);
5872 -o-transform: translate(0, 0);
5873 transform: translate(0, 0);
5874 }
5875 .modal-open .modal {
5876 overflow-x: hidden;
5877 overflow-y: auto;
5878 }
5879 .modal-dialog {
5880 position: relative;
5881 width: auto;
5882 margin: 10px;
5883 }
5884 .modal-content {
5885 position: relative;
5886 background-color: #fff;
5887 border: 1px solid #999;
5888 border: 1px solid rgba(0, 0, 0, 0.2);
5889 border-radius: 3px;
5890 -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
5891 box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
5892 background-clip: padding-box;
5893 outline: 0;
5894 }
5895 .modal-backdrop {
5896 position: fixed;
5897 top: 0;
5898 right: 0;
5899 bottom: 0;
5900 left: 0;
5901 z-index: 1040;
5902 background-color: #000;
5903 }
5904 .modal-backdrop.fade {
5905 opacity: 0;
5906 filter: alpha(opacity=0);
5907 }
5908 .modal-backdrop.in {
5909 opacity: 0.5;
5910 filter: alpha(opacity=50);
5911 }
5912 .modal-header {
5913 padding: 15px;
5914 border-bottom: 1px solid #e5e5e5;
5915 }
5916 .modal-header .close {
5917 margin-top: -2px;
5918 }
5919 .modal-title {
5920 margin: 0;
5921 line-height: 1.42857143;
5922 }
5923 .modal-body {
5924 position: relative;
5925 padding: 15px;
5926 }
5927 .modal-footer {
5928 padding: 15px;
5929 text-align: right;
5930 border-top: 1px solid #e5e5e5;
5931 }
5932 .modal-footer .btn + .btn {
5933 margin-left: 5px;
5934 margin-bottom: 0;
5935 }
5936 .modal-footer .btn-group .btn + .btn {
5937 margin-left: -1px;
5938 }
5939 .modal-footer .btn-block + .btn-block {
5940 margin-left: 0;
5941 }
5942 .modal-scrollbar-measure {
5943 position: absolute;
5944 top: -9999px;
5945 width: 50px;
5946 height: 50px;
5947 overflow: scroll;
5948 }
5949 @media (min-width: 768px) {
5950 .modal-dialog {
5951 width: 600px;
5952 margin: 30px auto;
5953 }
5954 .modal-content {
5955 -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
5956 box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
5957 }
5958 .modal-sm {
5959 width: 300px;
5960 }
5961 }
5962 @media (min-width: 992px) {
5963 .modal-lg {
5964 width: 900px;
5965 }
5966 }
5967 .tooltip {
5968 position: absolute;
5969 z-index: 1070;
5970 display: block;
5971 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
5972 font-style: normal;
5973 font-weight: normal;
5974 letter-spacing: normal;
5975 line-break: auto;
5976 line-height: 1.42857143;
5977 text-align: left;
5978 text-align: start;
5979 text-decoration: none;
5980 text-shadow: none;
5981 text-transform: none;
5982 white-space: normal;
5983 word-break: normal;
5984 word-spacing: normal;
5985 word-wrap: normal;
5986 font-size: 12px;
5987 opacity: 0;
5988 filter: alpha(opacity=0);
5989 }
5990 .tooltip.in {
5991 opacity: 0.9;
5992 filter: alpha(opacity=90);
5993 }
5994 .tooltip.top {
5995 margin-top: -3px;
5996 padding: 5px 0;
5997 }
5998 .tooltip.right {
5999 margin-left: 3px;
6000 padding: 0 5px;
6001 }
6002 .tooltip.bottom {
6003 margin-top: 3px;
6004 padding: 5px 0;
6005 }
6006 .tooltip.left {
6007 margin-left: -3px;
6008 padding: 0 5px;
6009 }
6010 .tooltip-inner {
6011 max-width: 200px;
6012 padding: 3px 8px;
6013 color: #fff;
6014 text-align: center;
6015 background-color: #000;
6016 border-radius: 2px;
6017 }
6018 .tooltip-arrow {
6019 position: absolute;
6020 width: 0;
6021 height: 0;
6022 border-color: transparent;
6023 border-style: solid;
6024 }
6025 .tooltip.top .tooltip-arrow {
6026 bottom: 0;
6027 left: 50%;
6028 margin-left: -5px;
6029 border-width: 5px 5px 0;
6030 border-top-color: #000;
6031 }
6032 .tooltip.top-left .tooltip-arrow {
6033 bottom: 0;
6034 right: 5px;
6035 margin-bottom: -5px;
6036 border-width: 5px 5px 0;
6037 border-top-color: #000;
6038 }
6039 .tooltip.top-right .tooltip-arrow {
6040 bottom: 0;
6041 left: 5px;
6042 margin-bottom: -5px;
6043 border-width: 5px 5px 0;
6044 border-top-color: #000;
6045 }
6046 .tooltip.right .tooltip-arrow {
6047 top: 50%;
6048 left: 0;
6049 margin-top: -5px;
6050 border-width: 5px 5px 5px 0;
6051 border-right-color: #000;
6052 }
6053 .tooltip.left .tooltip-arrow {
6054 top: 50%;
6055 right: 0;
6056 margin-top: -5px;
6057 border-width: 5px 0 5px 5px;
6058 border-left-color: #000;
6059 }
6060 .tooltip.bottom .tooltip-arrow {
6061 top: 0;
6062 left: 50%;
6063 margin-left: -5px;
6064 border-width: 0 5px 5px;
6065 border-bottom-color: #000;
6066 }
6067 .tooltip.bottom-left .tooltip-arrow {
6068 top: 0;
6069 right: 5px;
6070 margin-top: -5px;
6071 border-width: 0 5px 5px;
6072 border-bottom-color: #000;
6073 }
6074 .tooltip.bottom-right .tooltip-arrow {
6075 top: 0;
6076 left: 5px;
6077 margin-top: -5px;
6078 border-width: 0 5px 5px;
6079 border-bottom-color: #000;
6080 }
6081 .popover {
6082 position: absolute;
6083 top: 0;
6084 left: 0;
6085 z-index: 1060;
6086 display: none;
6087 max-width: 276px;
6088 padding: 1px;
6089 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
6090 font-style: normal;
6091 font-weight: normal;
6092 letter-spacing: normal;
6093 line-break: auto;
6094 line-height: 1.42857143;
6095 text-align: left;
6096 text-align: start;
6097 text-decoration: none;
6098 text-shadow: none;
6099 text-transform: none;
6100 white-space: normal;
6101 word-break: normal;
6102 word-spacing: normal;
6103 word-wrap: normal;
6104 font-size: 13px;
6105 background-color: #fff;
6106 background-clip: padding-box;
6107 border: 1px solid #ccc;
6108 border: 1px solid rgba(0, 0, 0, 0.2);
6109 border-radius: 3px;
6110 -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
6111 box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
6112 }
6113 .popover.top {
6114 margin-top: -10px;
6115 }
6116 .popover.right {
6117 margin-left: 10px;
6118 }
6119 .popover.bottom {
6120 margin-top: 10px;
6121 }
6122 .popover.left {
6123 margin-left: -10px;
6124 }
6125 .popover-title {
6126 margin: 0;
6127 padding: 8px 14px;
6128 font-size: 13px;
6129 background-color: #f7f7f7;
6130 border-bottom: 1px solid #ebebeb;
6131 border-radius: 2px 2px 0 0;
6132 }
6133 .popover-content {
6134 padding: 9px 14px;
6135 }
6136 .popover > .arrow,
6137 .popover > .arrow:after {
6138 position: absolute;
6139 display: block;
6140 width: 0;
6141 height: 0;
6142 border-color: transparent;
6143 border-style: solid;
6144 }
6145 .popover > .arrow {
6146 border-width: 11px;
6147 }
6148 .popover > .arrow:after {
6149 border-width: 10px;
6150 content: "";
6151 }
6152 .popover.top > .arrow {
6153 left: 50%;
6154 margin-left: -11px;
6155 border-bottom-width: 0;
6156 border-top-color: #999999;
6157 border-top-color: rgba(0, 0, 0, 0.25);
6158 bottom: -11px;
6159 }
6160 .popover.top > .arrow:after {
6161 content: " ";
6162 bottom: 1px;
6163 margin-left: -10px;
6164 border-bottom-width: 0;
6165 border-top-color: #fff;
6166 }
6167 .popover.right > .arrow {
6168 top: 50%;
6169 left: -11px;
6170 margin-top: -11px;
6171 border-left-width: 0;
6172 border-right-color: #999999;
6173 border-right-color: rgba(0, 0, 0, 0.25);
6174 }
6175 .popover.right > .arrow:after {
6176 content: " ";
6177 left: 1px;
6178 bottom: -10px;
6179 border-left-width: 0;
6180 border-right-color: #fff;
6181 }
6182 .popover.bottom > .arrow {
6183 left: 50%;
6184 margin-left: -11px;
6185 border-top-width: 0;
6186 border-bottom-color: #999999;
6187 border-bottom-color: rgba(0, 0, 0, 0.25);
6188 top: -11px;
6189 }
6190 .popover.bottom > .arrow:after {
6191 content: " ";
6192 top: 1px;
6193 margin-left: -10px;
6194 border-top-width: 0;
6195 border-bottom-color: #fff;
6196 }
6197 .popover.left > .arrow {
6198 top: 50%;
6199 right: -11px;
6200 margin-top: -11px;
6201 border-right-width: 0;
6202 border-left-color: #999999;
6203 border-left-color: rgba(0, 0, 0, 0.25);
6204 }
6205 .popover.left > .arrow:after {
6206 content: " ";
6207 right: 1px;
6208 border-right-width: 0;
6209 border-left-color: #fff;
6210 bottom: -10px;
6211 }
6212 .carousel {
6213 position: relative;
6214 }
6215 .carousel-inner {
6216 position: relative;
6217 overflow: hidden;
6218 width: 100%;
6219 }
6220 .carousel-inner > .item {
6221 display: none;
6222 position: relative;
6223 -webkit-transition: 0.6s ease-in-out left;
6224 -o-transition: 0.6s ease-in-out left;
6225 transition: 0.6s ease-in-out left;
6226 }
6227 .carousel-inner > .item > img,
6228 .carousel-inner > .item > a > img {
6229 line-height: 1;
6230 }
6231 @media all and (transform-3d), (-webkit-transform-3d) {
6232 .carousel-inner > .item {
6233 -webkit-transition: -webkit-transform 0.6s ease-in-out;
6234 -moz-transition: -moz-transform 0.6s ease-in-out;
6235 -o-transition: -o-transform 0.6s ease-in-out;
6236 transition: transform 0.6s ease-in-out;
6237 -webkit-backface-visibility: hidden;
6238 -moz-backface-visibility: hidden;
6239 backface-visibility: hidden;
6240 -webkit-perspective: 1000px;
6241 -moz-perspective: 1000px;
6242 perspective: 1000px;
6243 }
6244 .carousel-inner > .item.next,
6245 .carousel-inner > .item.active.right {
6246 -webkit-transform: translate3d(100%, 0, 0);
6247 transform: translate3d(100%, 0, 0);
6248 left: 0;
6249 }
6250 .carousel-inner > .item.prev,
6251 .carousel-inner > .item.active.left {
6252 -webkit-transform: translate3d(-100%, 0, 0);
6253 transform: translate3d(-100%, 0, 0);
6254 left: 0;
6255 }
6256 .carousel-inner > .item.next.left,
6257 .carousel-inner > .item.prev.right,
6258 .carousel-inner > .item.active {
6259 -webkit-transform: translate3d(0, 0, 0);
6260 transform: translate3d(0, 0, 0);
6261 left: 0;
6262 }
6263 }
6264 .carousel-inner > .active,
6265 .carousel-inner > .next,
6266 .carousel-inner > .prev {
6267 display: block;
6268 }
6269 .carousel-inner > .active {
6270 left: 0;
6271 }
6272 .carousel-inner > .next,
6273 .carousel-inner > .prev {
6274 position: absolute;
6275 top: 0;
6276 width: 100%;
6277 }
6278 .carousel-inner > .next {
6279 left: 100%;
6280 }
6281 .carousel-inner > .prev {
6282 left: -100%;
6283 }
6284 .carousel-inner > .next.left,
6285 .carousel-inner > .prev.right {
6286 left: 0;
6287 }
6288 .carousel-inner > .active.left {
6289 left: -100%;
6290 }
6291 .carousel-inner > .active.right {
6292 left: 100%;
6293 }
6294 .carousel-control {
6295 position: absolute;
6296 top: 0;
6297 left: 0;
6298 bottom: 0;
6299 width: 15%;
6300 opacity: 0.5;
6301 filter: alpha(opacity=50);
6302 font-size: 20px;
6303 color: #fff;
6304 text-align: center;
6305 text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
6306 background-color: rgba(0, 0, 0, 0);
6307 }
6308 .carousel-control.left {
6309 background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6310 background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6311 background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
6312 background-repeat: repeat-x;
6313 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
6314 }
6315 .carousel-control.right {
6316 left: auto;
6317 right: 0;
6318 background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6319 background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6320 background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
6321 background-repeat: repeat-x;
6322 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
6323 }
6324 .carousel-control:hover,
6325 .carousel-control:focus {
6326 outline: 0;
6327 color: #fff;
6328 text-decoration: none;
6329 opacity: 0.9;
6330 filter: alpha(opacity=90);
6331 }
6332 .carousel-control .icon-prev,
6333 .carousel-control .icon-next,
6334 .carousel-control .glyphicon-chevron-left,
6335 .carousel-control .glyphicon-chevron-right {
6336 position: absolute;
6337 top: 50%;
6338 margin-top: -10px;
6339 z-index: 5;
6340 display: inline-block;
6341 }
6342 .carousel-control .icon-prev,
6343 .carousel-control .glyphicon-chevron-left {
6344 left: 50%;
6345 margin-left: -10px;
6346 }
6347 .carousel-control .icon-next,
6348 .carousel-control .glyphicon-chevron-right {
6349 right: 50%;
6350 margin-right: -10px;
6351 }
6352 .carousel-control .icon-prev,
6353 .carousel-control .icon-next {
6354 width: 20px;
6355 height: 20px;
6356 line-height: 1;
6357 font-family: serif;
6358 }
6359 .carousel-control .icon-prev:before {
6360 content: '\2039';
6361 }
6362 .carousel-control .icon-next:before {
6363 content: '\203a';
6364 }
6365 .carousel-indicators {
6366 position: absolute;
6367 bottom: 10px;
6368 left: 50%;
6369 z-index: 15;
6370 width: 60%;
6371 margin-left: -30%;
6372 padding-left: 0;
6373 list-style: none;
6374 text-align: center;
6375 }
6376 .carousel-indicators li {
6377 display: inline-block;
6378 width: 10px;
6379 height: 10px;
6380 margin: 1px;
6381 text-indent: -999px;
6382 border: 1px solid #fff;
6383 border-radius: 10px;
6384 cursor: pointer;
6385 background-color: #000 \9;
6386 background-color: rgba(0, 0, 0, 0);
6387 }
6388 .carousel-indicators .active {
6389 margin: 0;
6390 width: 12px;
6391 height: 12px;
6392 background-color: #fff;
6393 }
6394 .carousel-caption {
6395 position: absolute;
6396 left: 15%;
6397 right: 15%;
6398 bottom: 20px;
6399 z-index: 10;
6400 padding-top: 20px;
6401 padding-bottom: 20px;
6402 color: #fff;
6403 text-align: center;
6404 text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
6405 }
6406 .carousel-caption .btn {
6407 text-shadow: none;
6408 }
6409 @media screen and (min-width: 768px) {
6410 .carousel-control .glyphicon-chevron-left,
6411 .carousel-control .glyphicon-chevron-right,
6412 .carousel-control .icon-prev,
6413 .carousel-control .icon-next {
6414 width: 30px;
6415 height: 30px;
6416 margin-top: -10px;
6417 font-size: 30px;
6418 }
6419 .carousel-control .glyphicon-chevron-left,
6420 .carousel-control .icon-prev {
6421 margin-left: -10px;
6422 }
6423 .carousel-control .glyphicon-chevron-right,
6424 .carousel-control .icon-next {
6425 margin-right: -10px;
6426 }
6427 .carousel-caption {
6428 left: 20%;
6429 right: 20%;
6430 padding-bottom: 30px;
6431 }
6432 .carousel-indicators {
6433 bottom: 20px;
6434 }
6435 }
6436 .clearfix:before,
6437 .clearfix:after,
6438 .dl-horizontal dd:before,
6439 .dl-horizontal dd:after,
6440 .container:before,
6441 .container:after,
6442 .container-fluid:before,
6443 .container-fluid:after,
6444 .row:before,
6445 .row:after,
6446 .form-horizontal .form-group:before,
6447 .form-horizontal .form-group:after,
6448 .btn-toolbar:before,
6449 .btn-toolbar:after,
6450 .btn-group-vertical > .btn-group:before,
6451 .btn-group-vertical > .btn-group:after,
6452 .nav:before,
6453 .nav:after,
6454 .navbar:before,
6455 .navbar:after,
6456 .navbar-header:before,
6457 .navbar-header:after,
6458 .navbar-collapse:before,
6459 .navbar-collapse:after,
6460 .pager:before,
6461 .pager:after,
6462 .panel-body:before,
6463 .panel-body:after,
6464 .modal-header:before,
6465 .modal-header:after,
6466 .modal-footer:before,
6467 .modal-footer:after,
6468 .item_buttons:before,
6469 .item_buttons:after {
6470 content: " ";
6471 display: table;
6472 }
6473 .clearfix:after,
6474 .dl-horizontal dd:after,
6475 .container:after,
6476 .container-fluid:after,
6477 .row:after,
6478 .form-horizontal .form-group:after,
6479 .btn-toolbar:after,
6480 .btn-group-vertical > .btn-group:after,
6481 .nav:after,
6482 .navbar:after,
6483 .navbar-header:after,
6484 .navbar-collapse:after,
6485 .pager:after,
6486 .panel-body:after,
6487 .modal-header:after,
6488 .modal-footer:after,
6489 .item_buttons:after {
6490 clear: both;
6491 }
6492 .center-block {
6493 display: block;
6494 margin-left: auto;
6495 margin-right: auto;
6496 }
6497 .pull-right {
6498 float: right !important;
6499 }
6500 .pull-left {
6501 float: left !important;
6502 }
6503 .hide {
6504 display: none !important;
6505 }
6506 .show {
6507 display: block !important;
6508 }
6509 .invisible {
6510 visibility: hidden;
6511 }
6512 .text-hide {
6513 font: 0/0 a;
6514 color: transparent;
6515 text-shadow: none;
6516 background-color: transparent;
6517 border: 0;
6518 }
6519 .hidden {
6520 display: none !important;
6521 }
6522 .affix {
6523 position: fixed;
6524 }
6525 @-ms-viewport {
6526 width: device-width;
6527 }
6528 .visible-xs,
6529 .visible-sm,
6530 .visible-md,
6531 .visible-lg {
6532 display: none !important;
6533 }
6534 .visible-xs-block,
6535 .visible-xs-inline,
6536 .visible-xs-inline-block,
6537 .visible-sm-block,
6538 .visible-sm-inline,
6539 .visible-sm-inline-block,
6540 .visible-md-block,
6541 .visible-md-inline,
6542 .visible-md-inline-block,
6543 .visible-lg-block,
6544 .visible-lg-inline,
6545 .visible-lg-inline-block {
6546 display: none !important;
6547 }
6548 @media (max-width: 767px) {
6549 .visible-xs {
6550 display: block !important;
6551 }
6552 table.visible-xs {
6553 display: table !important;
6554 }
6555 tr.visible-xs {
6556 display: table-row !important;
6557 }
6558 th.visible-xs,
6559 td.visible-xs {
6560 display: table-cell !important;
6561 }
6562 }
6563 @media (max-width: 767px) {
6564 .visible-xs-block {
6565 display: block !important;
6566 }
6567 }
6568 @media (max-width: 767px) {
6569 .visible-xs-inline {
6570 display: inline !important;
6571 }
6572 }
6573 @media (max-width: 767px) {
6574 .visible-xs-inline-block {
6575 display: inline-block !important;
6576 }
6577 }
6578 @media (min-width: 768px) and (max-width: 991px) {
6579 .visible-sm {
6580 display: block !important;
6581 }
6582 table.visible-sm {
6583 display: table !important;
6584 }
6585 tr.visible-sm {
6586 display: table-row !important;
6587 }
6588 th.visible-sm,
6589 td.visible-sm {
6590 display: table-cell !important;
6591 }
6592 }
6593 @media (min-width: 768px) and (max-width: 991px) {
6594 .visible-sm-block {
6595 display: block !important;
6596 }
6597 }
6598 @media (min-width: 768px) and (max-width: 991px) {
6599 .visible-sm-inline {
6600 display: inline !important;
6601 }
6602 }
6603 @media (min-width: 768px) and (max-width: 991px) {
6604 .visible-sm-inline-block {
6605 display: inline-block !important;
6606 }
6607 }
6608 @media (min-width: 992px) and (max-width: 1199px) {
6609 .visible-md {
6610 display: block !important;
6611 }
6612 table.visible-md {
6613 display: table !important;
6614 }
6615 tr.visible-md {
6616 display: table-row !important;
6617 }
6618 th.visible-md,
6619 td.visible-md {
6620 display: table-cell !important;
6621 }
6622 }
6623 @media (min-width: 992px) and (max-width: 1199px) {
6624 .visible-md-block {
6625 display: block !important;
6626 }
6627 }
6628 @media (min-width: 992px) and (max-width: 1199px) {
6629 .visible-md-inline {
6630 display: inline !important;
6631 }
6632 }
6633 @media (min-width: 992px) and (max-width: 1199px) {
6634 .visible-md-inline-block {
6635 display: inline-block !important;
6636 }
6637 }
6638 @media (min-width: 1200px) {
6639 .visible-lg {
6640 display: block !important;
6641 }
6642 table.visible-lg {
6643 display: table !important;
6644 }
6645 tr.visible-lg {
6646 display: table-row !important;
6647 }
6648 th.visible-lg,
6649 td.visible-lg {
6650 display: table-cell !important;
6651 }
6652 }
6653 @media (min-width: 1200px) {
6654 .visible-lg-block {
6655 display: block !important;
6656 }
6657 }
6658 @media (min-width: 1200px) {
6659 .visible-lg-inline {
6660 display: inline !important;
6661 }
6662 }
6663 @media (min-width: 1200px) {
6664 .visible-lg-inline-block {
6665 display: inline-block !important;
6666 }
6667 }
6668 @media (max-width: 767px) {
6669 .hidden-xs {
6670 display: none !important;
6671 }
6672 }
6673 @media (min-width: 768px) and (max-width: 991px) {
6674 .hidden-sm {
6675 display: none !important;
6676 }
6677 }
6678 @media (min-width: 992px) and (max-width: 1199px) {
6679 .hidden-md {
6680 display: none !important;
6681 }
6682 }
6683 @media (min-width: 1200px) {
6684 .hidden-lg {
6685 display: none !important;
6686 }
6687 }
6688 .visible-print {
6689 display: none !important;
6690 }
6691 @media print {
6692 .visible-print {
6693 display: block !important;
6694 }
6695 table.visible-print {
6696 display: table !important;
6697 }
6698 tr.visible-print {
6699 display: table-row !important;
6700 }
6701 th.visible-print,
6702 td.visible-print {
6703 display: table-cell !important;
6704 }
6705 }
6706 .visible-print-block {
6707 display: none !important;
6708 }
6709 @media print {
6710 .visible-print-block {
6711 display: block !important;
6712 }
6713 }
6714 .visible-print-inline {
6715 display: none !important;
6716 }
6717 @media print {
6718 .visible-print-inline {
6719 display: inline !important;
6720 }
6721 }
6722 .visible-print-inline-block {
6723 display: none !important;
6724 }
6725 @media print {
6726 .visible-print-inline-block {
6727 display: inline-block !important;
6728 }
6729 }
6730 @media print {
6731 .hidden-print {
6732 display: none !important;
6733 }
6734 }
6735 /*!
6736 *
6737 * Font Awesome
6738 *
6739 */
6740 /*!
6741 * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome
6742 * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
6743 */
6744 /* FONT PATH
6745 * -------------------------- */
6746 @font-face {
6747 font-family: 'FontAwesome';
6748 src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?v=4.2.0');
6749 src: url('../components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../components/font-awesome/fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../components/font-awesome/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
6750 font-weight: normal;
6751 font-style: normal;
6752 }
6753 .fa {
6754 display: inline-block;
6755 font: normal normal normal 14px/1 FontAwesome;
6756 font-size: inherit;
6757 text-rendering: auto;
6758 -webkit-font-smoothing: antialiased;
6759 -moz-osx-font-smoothing: grayscale;
6760 }
6761 /* makes the font 33% larger relative to the icon container */
6762 .fa-lg {
6763 font-size: 1.33333333em;
6764 line-height: 0.75em;
6765 vertical-align: -15%;
6766 }
6767 .fa-2x {
6768 font-size: 2em;
6769 }
6770 .fa-3x {
6771 font-size: 3em;
6772 }
6773 .fa-4x {
6774 font-size: 4em;
6775 }
6776 .fa-5x {
6777 font-size: 5em;
6778 }
6779 .fa-fw {
6780 width: 1.28571429em;
6781 text-align: center;
6782 }
6783 .fa-ul {
6784 padding-left: 0;
6785 margin-left: 2.14285714em;
6786 list-style-type: none;
6787 }
6788 .fa-ul > li {
6789 position: relative;
6790 }
6791 .fa-li {
6792 position: absolute;
6793 left: -2.14285714em;
6794 width: 2.14285714em;
6795 top: 0.14285714em;
6796 text-align: center;
6797 }
6798 .fa-li.fa-lg {
6799 left: -1.85714286em;
6800 }
6801 .fa-border {
6802 padding: .2em .25em .15em;
6803 border: solid 0.08em #eee;
6804 border-radius: .1em;
6805 }
6806 .pull-right {
6807 float: right;
6808 }
6809 .pull-left {
6810 float: left;
6811 }
6812 .fa.pull-left {
6813 margin-right: .3em;
6814 }
6815 .fa.pull-right {
6816 margin-left: .3em;
6817 }
6818 .fa-spin {
6819 -webkit-animation: fa-spin 2s infinite linear;
6820 animation: fa-spin 2s infinite linear;
6821 }
6822 @-webkit-keyframes fa-spin {
6823 0% {
6824 -webkit-transform: rotate(0deg);
6825 transform: rotate(0deg);
6826 }
6827 100% {
6828 -webkit-transform: rotate(359deg);
6829 transform: rotate(359deg);
6830 }
6831 }
6832 @keyframes fa-spin {
6833 0% {
6834 -webkit-transform: rotate(0deg);
6835 transform: rotate(0deg);
6836 }
6837 100% {
6838 -webkit-transform: rotate(359deg);
6839 transform: rotate(359deg);
6840 }
6841 }
6842 .fa-rotate-90 {
6843 filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
6844 -webkit-transform: rotate(90deg);
6845 -ms-transform: rotate(90deg);
6846 transform: rotate(90deg);
6847 }
6848 .fa-rotate-180 {
6849 filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
6850 -webkit-transform: rotate(180deg);
6851 -ms-transform: rotate(180deg);
6852 transform: rotate(180deg);
6853 }
6854 .fa-rotate-270 {
6855 filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
6856 -webkit-transform: rotate(270deg);
6857 -ms-transform: rotate(270deg);
6858 transform: rotate(270deg);
6859 }
6860 .fa-flip-horizontal {
6861 filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
6862 -webkit-transform: scale(-1, 1);
6863 -ms-transform: scale(-1, 1);
6864 transform: scale(-1, 1);
6865 }
6866 .fa-flip-vertical {
6867 filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
6868 -webkit-transform: scale(1, -1);
6869 -ms-transform: scale(1, -1);
6870 transform: scale(1, -1);
6871 }
6872 :root .fa-rotate-90,
6873 :root .fa-rotate-180,
6874 :root .fa-rotate-270,
6875 :root .fa-flip-horizontal,
6876 :root .fa-flip-vertical {
6877 filter: none;
6878 }
6879 .fa-stack {
6880 position: relative;
6881 display: inline-block;
6882 width: 2em;
6883 height: 2em;
6884 line-height: 2em;
6885 vertical-align: middle;
6886 }
6887 .fa-stack-1x,
6888 .fa-stack-2x {
6889 position: absolute;
6890 left: 0;
6891 width: 100%;
6892 text-align: center;
6893 }
6894 .fa-stack-1x {
6895 line-height: inherit;
6896 }
6897 .fa-stack-2x {
6898 font-size: 2em;
6899 }
6900 .fa-inverse {
6901 color: #fff;
6902 }
6903 /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
6904 readers do not read off random characters that represent icons */
6905 .fa-glass:before {
6906 content: "\f000";
6907 }
6908 .fa-music:before {
6909 content: "\f001";
6910 }
6911 .fa-search:before {
6912 content: "\f002";
6913 }
6914 .fa-envelope-o:before {
6915 content: "\f003";
6916 }
6917 .fa-heart:before {
6918 content: "\f004";
6919 }
6920 .fa-star:before {
6921 content: "\f005";
6922 }
6923 .fa-star-o:before {
6924 content: "\f006";
6925 }
6926 .fa-user:before {
6927 content: "\f007";
6928 }
6929 .fa-film:before {
6930 content: "\f008";
6931 }
6932 .fa-th-large:before {
6933 content: "\f009";
6934 }
6935 .fa-th:before {
6936 content: "\f00a";
6937 }
6938 .fa-th-list:before {
6939 content: "\f00b";
6940 }
6941 .fa-check:before {
6942 content: "\f00c";
6943 }
6944 .fa-remove:before,
6945 .fa-close:before,
6946 .fa-times:before {
6947 content: "\f00d";
6948 }
6949 .fa-search-plus:before {
6950 content: "\f00e";
6951 }
6952 .fa-search-minus:before {
6953 content: "\f010";
6954 }
6955 .fa-power-off:before {
6956 content: "\f011";
6957 }
6958 .fa-signal:before {
6959 content: "\f012";
6960 }
6961 .fa-gear:before,
6962 .fa-cog:before {
6963 content: "\f013";
6964 }
6965 .fa-trash-o:before {
6966 content: "\f014";
6967 }
6968 .fa-home:before {
6969 content: "\f015";
6970 }
6971 .fa-file-o:before {
6972 content: "\f016";
6973 }
6974 .fa-clock-o:before {
6975 content: "\f017";
6976 }
6977 .fa-road:before {
6978 content: "\f018";
6979 }
6980 .fa-download:before {
6981 content: "\f019";
6982 }
6983 .fa-arrow-circle-o-down:before {
6984 content: "\f01a";
6985 }
6986 .fa-arrow-circle-o-up:before {
6987 content: "\f01b";
6988 }
6989 .fa-inbox:before {
6990 content: "\f01c";
6991 }
6992 .fa-play-circle-o:before {
6993 content: "\f01d";
6994 }
6995 .fa-rotate-right:before,
6996 .fa-repeat:before {
6997 content: "\f01e";
6998 }
6999 .fa-refresh:before {
7000 content: "\f021";
7001 }
7002 .fa-list-alt:before {
7003 content: "\f022";
7004 }
7005 .fa-lock:before {
7006 content: "\f023";
7007 }
7008 .fa-flag:before {
7009 content: "\f024";
7010 }
7011 .fa-headphones:before {
7012 content: "\f025";
7013 }
7014 .fa-volume-off:before {
7015 content: "\f026";
7016 }
7017 .fa-volume-down:before {
7018 content: "\f027";
7019 }
7020 .fa-volume-up:before {
7021 content: "\f028";
7022 }
7023 .fa-qrcode:before {
7024 content: "\f029";
7025 }
7026 .fa-barcode:before {
7027 content: "\f02a";
7028 }
7029 .fa-tag:before {
7030 content: "\f02b";
7031 }
7032 .fa-tags:before {
7033 content: "\f02c";
7034 }
7035 .fa-book:before {
7036 content: "\f02d";
7037 }
7038 .fa-bookmark:before {
7039 content: "\f02e";
7040 }
7041 .fa-print:before {
7042 content: "\f02f";
7043 }
7044 .fa-camera:before {
7045 content: "\f030";
7046 }
7047 .fa-font:before {
7048 content: "\f031";
7049 }
7050 .fa-bold:before {
7051 content: "\f032";
7052 }
7053 .fa-italic:before {
7054 content: "\f033";
7055 }
7056 .fa-text-height:before {
7057 content: "\f034";
7058 }
7059 .fa-text-width:before {
7060 content: "\f035";
7061 }
7062 .fa-align-left:before {
7063 content: "\f036";
7064 }
7065 .fa-align-center:before {
7066 content: "\f037";
7067 }
7068 .fa-align-right:before {
7069 content: "\f038";
7070 }
7071 .fa-align-justify:before {
7072 content: "\f039";
7073 }
7074 .fa-list:before {
7075 content: "\f03a";
7076 }
7077 .fa-dedent:before,
7078 .fa-outdent:before {
7079 content: "\f03b";
7080 }
7081 .fa-indent:before {
7082 content: "\f03c";
7083 }
7084 .fa-video-camera:before {
7085 content: "\f03d";
7086 }
7087 .fa-photo:before,
7088 .fa-image:before,
7089 .fa-picture-o:before {
7090 content: "\f03e";
7091 }
7092 .fa-pencil:before {
7093 content: "\f040";
7094 }
7095 .fa-map-marker:before {
7096 content: "\f041";
7097 }
7098 .fa-adjust:before {
7099 content: "\f042";
7100 }
7101 .fa-tint:before {
7102 content: "\f043";
7103 }
7104 .fa-edit:before,
7105 .fa-pencil-square-o:before {
7106 content: "\f044";
7107 }
7108 .fa-share-square-o:before {
7109 content: "\f045";
7110 }
7111 .fa-check-square-o:before {
7112 content: "\f046";
7113 }
7114 .fa-arrows:before {
7115 content: "\f047";
7116 }
7117 .fa-step-backward:before {
7118 content: "\f048";
7119 }
7120 .fa-fast-backward:before {
7121 content: "\f049";
7122 }
7123 .fa-backward:before {
7124 content: "\f04a";
7125 }
7126 .fa-play:before {
7127 content: "\f04b";
7128 }
7129 .fa-pause:before {
7130 content: "\f04c";
7131 }
7132 .fa-stop:before {
7133 content: "\f04d";
7134 }
7135 .fa-forward:before {
7136 content: "\f04e";
7137 }
7138 .fa-fast-forward:before {
7139 content: "\f050";
7140 }
7141 .fa-step-forward:before {
7142 content: "\f051";
7143 }
7144 .fa-eject:before {
7145 content: "\f052";
7146 }
7147 .fa-chevron-left:before {
7148 content: "\f053";
7149 }
7150 .fa-chevron-right:before {
7151 content: "\f054";
7152 }
7153 .fa-plus-circle:before {
7154 content: "\f055";
7155 }
7156 .fa-minus-circle:before {
7157 content: "\f056";
7158 }
7159 .fa-times-circle:before {
7160 content: "\f057";
7161 }
7162 .fa-check-circle:before {
7163 content: "\f058";
7164 }
7165 .fa-question-circle:before {
7166 content: "\f059";
7167 }
7168 .fa-info-circle:before {
7169 content: "\f05a";
7170 }
7171 .fa-crosshairs:before {
7172 content: "\f05b";
7173 }
7174 .fa-times-circle-o:before {
7175 content: "\f05c";
7176 }
7177 .fa-check-circle-o:before {
7178 content: "\f05d";
7179 }
7180 .fa-ban:before {
7181 content: "\f05e";
7182 }
7183 .fa-arrow-left:before {
7184 content: "\f060";
7185 }
7186 .fa-arrow-right:before {
7187 content: "\f061";
7188 }
7189 .fa-arrow-up:before {
7190 content: "\f062";
7191 }
7192 .fa-arrow-down:before {
7193 content: "\f063";
7194 }
7195 .fa-mail-forward:before,
7196 .fa-share:before {
7197 content: "\f064";
7198 }
7199 .fa-expand:before {
7200 content: "\f065";
7201 }
7202 .fa-compress:before {
7203 content: "\f066";
7204 }
7205 .fa-plus:before {
7206 content: "\f067";
7207 }
7208 .fa-minus:before {
7209 content: "\f068";
7210 }
7211 .fa-asterisk:before {
7212 content: "\f069";
7213 }
7214 .fa-exclamation-circle:before {
7215 content: "\f06a";
7216 }
7217 .fa-gift:before {
7218 content: "\f06b";
7219 }
7220 .fa-leaf:before {
7221 content: "\f06c";
7222 }
7223 .fa-fire:before {
7224 content: "\f06d";
7225 }
7226 .fa-eye:before {
7227 content: "\f06e";
7228 }
7229 .fa-eye-slash:before {
7230 content: "\f070";
7231 }
7232 .fa-warning:before,
7233 .fa-exclamation-triangle:before {
7234 content: "\f071";
7235 }
7236 .fa-plane:before {
7237 content: "\f072";
7238 }
7239 .fa-calendar:before {
7240 content: "\f073";
7241 }
7242 .fa-random:before {
7243 content: "\f074";
7244 }
7245 .fa-comment:before {
7246 content: "\f075";
7247 }
7248 .fa-magnet:before {
7249 content: "\f076";
7250 }
7251 .fa-chevron-up:before {
7252 content: "\f077";
7253 }
7254 .fa-chevron-down:before {
7255 content: "\f078";
7256 }
7257 .fa-retweet:before {
7258 content: "\f079";
7259 }
7260 .fa-shopping-cart:before {
7261 content: "\f07a";
7262 }
7263 .fa-folder:before {
7264 content: "\f07b";
7265 }
7266 .fa-folder-open:before {
7267 content: "\f07c";
7268 }
7269 .fa-arrows-v:before {
7270 content: "\f07d";
7271 }
7272 .fa-arrows-h:before {
7273 content: "\f07e";
7274 }
7275 .fa-bar-chart-o:before,
7276 .fa-bar-chart:before {
7277 content: "\f080";
7278 }
7279 .fa-twitter-square:before {
7280 content: "\f081";
7281 }
7282 .fa-facebook-square:before {
7283 content: "\f082";
7284 }
7285 .fa-camera-retro:before {
7286 content: "\f083";
7287 }
7288 .fa-key:before {
7289 content: "\f084";
7290 }
7291 .fa-gears:before,
7292 .fa-cogs:before {
7293 content: "\f085";
7294 }
7295 .fa-comments:before {
7296 content: "\f086";
7297 }
7298 .fa-thumbs-o-up:before {
7299 content: "\f087";
7300 }
7301 .fa-thumbs-o-down:before {
7302 content: "\f088";
7303 }
7304 .fa-star-half:before {
7305 content: "\f089";
7306 }
7307 .fa-heart-o:before {
7308 content: "\f08a";
7309 }
7310 .fa-sign-out:before {
7311 content: "\f08b";
7312 }
7313 .fa-linkedin-square:before {
7314 content: "\f08c";
7315 }
7316 .fa-thumb-tack:before {
7317 content: "\f08d";
7318 }
7319 .fa-external-link:before {
7320 content: "\f08e";
7321 }
7322 .fa-sign-in:before {
7323 content: "\f090";
7324 }
7325 .fa-trophy:before {
7326 content: "\f091";
7327 }
7328 .fa-github-square:before {
7329 content: "\f092";
7330 }
7331 .fa-upload:before {
7332 content: "\f093";
7333 }
7334 .fa-lemon-o:before {
7335 content: "\f094";
7336 }
7337 .fa-phone:before {
7338 content: "\f095";
7339 }
7340 .fa-square-o:before {
7341 content: "\f096";
7342 }
7343 .fa-bookmark-o:before {
7344 content: "\f097";
7345 }
7346 .fa-phone-square:before {
7347 content: "\f098";
7348 }
7349 .fa-twitter:before {
7350 content: "\f099";
7351 }
7352 .fa-facebook:before {
7353 content: "\f09a";
7354 }
7355 .fa-github:before {
7356 content: "\f09b";
7357 }
7358 .fa-unlock:before {
7359 content: "\f09c";
7360 }
7361 .fa-credit-card:before {
7362 content: "\f09d";
7363 }
7364 .fa-rss:before {
7365 content: "\f09e";
7366 }
7367 .fa-hdd-o:before {
7368 content: "\f0a0";
7369 }
7370 .fa-bullhorn:before {
7371 content: "\f0a1";
7372 }
7373 .fa-bell:before {
7374 content: "\f0f3";
7375 }
7376 .fa-certificate:before {
7377 content: "\f0a3";
7378 }
7379 .fa-hand-o-right:before {
7380 content: "\f0a4";
7381 }
7382 .fa-hand-o-left:before {
7383 content: "\f0a5";
7384 }
7385 .fa-hand-o-up:before {
7386 content: "\f0a6";
7387 }
7388 .fa-hand-o-down:before {
7389 content: "\f0a7";
7390 }
7391 .fa-arrow-circle-left:before {
7392 content: "\f0a8";
7393 }
7394 .fa-arrow-circle-right:before {
7395 content: "\f0a9";
7396 }
7397 .fa-arrow-circle-up:before {
7398 content: "\f0aa";
7399 }
7400 .fa-arrow-circle-down:before {
7401 content: "\f0ab";
7402 }
7403 .fa-globe:before {
7404 content: "\f0ac";
7405 }
7406 .fa-wrench:before {
7407 content: "\f0ad";
7408 }
7409 .fa-tasks:before {
7410 content: "\f0ae";
7411 }
7412 .fa-filter:before {
7413 content: "\f0b0";
7414 }
7415 .fa-briefcase:before {
7416 content: "\f0b1";
7417 }
7418 .fa-arrows-alt:before {
7419 content: "\f0b2";
7420 }
7421 .fa-group:before,
7422 .fa-users:before {
7423 content: "\f0c0";
7424 }
7425 .fa-chain:before,
7426 .fa-link:before {
7427 content: "\f0c1";
7428 }
7429 .fa-cloud:before {
7430 content: "\f0c2";
7431 }
7432 .fa-flask:before {
7433 content: "\f0c3";
7434 }
7435 .fa-cut:before,
7436 .fa-scissors:before {
7437 content: "\f0c4";
7438 }
7439 .fa-copy:before,
7440 .fa-files-o:before {
7441 content: "\f0c5";
7442 }
7443 .fa-paperclip:before {
7444 content: "\f0c6";
7445 }
7446 .fa-save:before,
7447 .fa-floppy-o:before {
7448 content: "\f0c7";
7449 }
7450 .fa-square:before {
7451 content: "\f0c8";
7452 }
7453 .fa-navicon:before,
7454 .fa-reorder:before,
7455 .fa-bars:before {
7456 content: "\f0c9";
7457 }
7458 .fa-list-ul:before {
7459 content: "\f0ca";
7460 }
7461 .fa-list-ol:before {
7462 content: "\f0cb";
7463 }
7464 .fa-strikethrough:before {
7465 content: "\f0cc";
7466 }
7467 .fa-underline:before {
7468 content: "\f0cd";
7469 }
7470 .fa-table:before {
7471 content: "\f0ce";
7472 }
7473 .fa-magic:before {
7474 content: "\f0d0";
7475 }
7476 .fa-truck:before {
7477 content: "\f0d1";
7478 }
7479 .fa-pinterest:before {
7480 content: "\f0d2";
7481 }
7482 .fa-pinterest-square:before {
7483 content: "\f0d3";
7484 }
7485 .fa-google-plus-square:before {
7486 content: "\f0d4";
7487 }
7488 .fa-google-plus:before {
7489 content: "\f0d5";
7490 }
7491 .fa-money:before {
7492 content: "\f0d6";
7493 }
7494 .fa-caret-down:before {
7495 content: "\f0d7";
7496 }
7497 .fa-caret-up:before {
7498 content: "\f0d8";
7499 }
7500 .fa-caret-left:before {
7501 content: "\f0d9";
7502 }
7503 .fa-caret-right:before {
7504 content: "\f0da";
7505 }
7506 .fa-columns:before {
7507 content: "\f0db";
7508 }
7509 .fa-unsorted:before,
7510 .fa-sort:before {
7511 content: "\f0dc";
7512 }
7513 .fa-sort-down:before,
7514 .fa-sort-desc:before {
7515 content: "\f0dd";
7516 }
7517 .fa-sort-up:before,
7518 .fa-sort-asc:before {
7519 content: "\f0de";
7520 }
7521 .fa-envelope:before {
7522 content: "\f0e0";
7523 }
7524 .fa-linkedin:before {
7525 content: "\f0e1";
7526 }
7527 .fa-rotate-left:before,
7528 .fa-undo:before {
7529 content: "\f0e2";
7530 }
7531 .fa-legal:before,
7532 .fa-gavel:before {
7533 content: "\f0e3";
7534 }
7535 .fa-dashboard:before,
7536 .fa-tachometer:before {
7537 content: "\f0e4";
7538 }
7539 .fa-comment-o:before {
7540 content: "\f0e5";
7541 }
7542 .fa-comments-o:before {
7543 content: "\f0e6";
7544 }
7545 .fa-flash:before,
7546 .fa-bolt:before {
7547 content: "\f0e7";
7548 }
7549 .fa-sitemap:before {
7550 content: "\f0e8";
7551 }
7552 .fa-umbrella:before {
7553 content: "\f0e9";
7554 }
7555 .fa-paste:before,
7556 .fa-clipboard:before {
7557 content: "\f0ea";
7558 }
7559 .fa-lightbulb-o:before {
7560 content: "\f0eb";
7561 }
7562 .fa-exchange:before {
7563 content: "\f0ec";
7564 }
7565 .fa-cloud-download:before {
7566 content: "\f0ed";
7567 }
7568 .fa-cloud-upload:before {
7569 content: "\f0ee";
7570 }
7571 .fa-user-md:before {
7572 content: "\f0f0";
7573 }
7574 .fa-stethoscope:before {
7575 content: "\f0f1";
7576 }
7577 .fa-suitcase:before {
7578 content: "\f0f2";
7579 }
7580 .fa-bell-o:before {
7581 content: "\f0a2";
7582 }
7583 .fa-coffee:before {
7584 content: "\f0f4";
7585 }
7586 .fa-cutlery:before {
7587 content: "\f0f5";
7588 }
7589 .fa-file-text-o:before {
7590 content: "\f0f6";
7591 }
7592 .fa-building-o:before {
7593 content: "\f0f7";
7594 }
7595 .fa-hospital-o:before {
7596 content: "\f0f8";
7597 }
7598 .fa-ambulance:before {
7599 content: "\f0f9";
7600 }
7601 .fa-medkit:before {
7602 content: "\f0fa";
7603 }
7604 .fa-fighter-jet:before {
7605 content: "\f0fb";
7606 }
7607 .fa-beer:before {
7608 content: "\f0fc";
7609 }
7610 .fa-h-square:before {
7611 content: "\f0fd";
7612 }
7613 .fa-plus-square:before {
7614 content: "\f0fe";
7615 }
7616 .fa-angle-double-left:before {
7617 content: "\f100";
7618 }
7619 .fa-angle-double-right:before {
7620 content: "\f101";
7621 }
7622 .fa-angle-double-up:before {
7623 content: "\f102";
7624 }
7625 .fa-angle-double-down:before {
7626 content: "\f103";
7627 }
7628 .fa-angle-left:before {
7629 content: "\f104";
7630 }
7631 .fa-angle-right:before {
7632 content: "\f105";
7633 }
7634 .fa-angle-up:before {
7635 content: "\f106";
7636 }
7637 .fa-angle-down:before {
7638 content: "\f107";
7639 }
7640 .fa-desktop:before {
7641 content: "\f108";
7642 }
7643 .fa-laptop:before {
7644 content: "\f109";
7645 }
7646 .fa-tablet:before {
7647 content: "\f10a";
7648 }
7649 .fa-mobile-phone:before,
7650 .fa-mobile:before {
7651 content: "\f10b";
7652 }
7653 .fa-circle-o:before {
7654 content: "\f10c";
7655 }
7656 .fa-quote-left:before {
7657 content: "\f10d";
7658 }
7659 .fa-quote-right:before {
7660 content: "\f10e";
7661 }
7662 .fa-spinner:before {
7663 content: "\f110";
7664 }
7665 .fa-circle:before {
7666 content: "\f111";
7667 }
7668 .fa-mail-reply:before,
7669 .fa-reply:before {
7670 content: "\f112";
7671 }
7672 .fa-github-alt:before {
7673 content: "\f113";
7674 }
7675 .fa-folder-o:before {
7676 content: "\f114";
7677 }
7678 .fa-folder-open-o:before {
7679 content: "\f115";
7680 }
7681 .fa-smile-o:before {
7682 content: "\f118";
7683 }
7684 .fa-frown-o:before {
7685 content: "\f119";
7686 }
7687 .fa-meh-o:before {
7688 content: "\f11a";
7689 }
7690 .fa-gamepad:before {
7691 content: "\f11b";
7692 }
7693 .fa-keyboard-o:before {
7694 content: "\f11c";
7695 }
7696 .fa-flag-o:before {
7697 content: "\f11d";
7698 }
7699 .fa-flag-checkered:before {
7700 content: "\f11e";
7701 }
7702 .fa-terminal:before {
7703 content: "\f120";
7704 }
7705 .fa-code:before {
7706 content: "\f121";
7707 }
7708 .fa-mail-reply-all:before,
7709 .fa-reply-all:before {
7710 content: "\f122";
7711 }
7712 .fa-star-half-empty:before,
7713 .fa-star-half-full:before,
7714 .fa-star-half-o:before {
7715 content: "\f123";
7716 }
7717 .fa-location-arrow:before {
7718 content: "\f124";
7719 }
7720 .fa-crop:before {
7721 content: "\f125";
7722 }
7723 .fa-code-fork:before {
7724 content: "\f126";
7725 }
7726 .fa-unlink:before,
7727 .fa-chain-broken:before {
7728 content: "\f127";
7729 }
7730 .fa-question:before {
7731 content: "\f128";
7732 }
7733 .fa-info:before {
7734 content: "\f129";
7735 }
7736 .fa-exclamation:before {
7737 content: "\f12a";
7738 }
7739 .fa-superscript:before {
7740 content: "\f12b";
7741 }
7742 .fa-subscript:before {
7743 content: "\f12c";
7744 }
7745 .fa-eraser:before {
7746 content: "\f12d";
7747 }
7748 .fa-puzzle-piece:before {
7749 content: "\f12e";
7750 }
7751 .fa-microphone:before {
7752 content: "\f130";
7753 }
7754 .fa-microphone-slash:before {
7755 content: "\f131";
7756 }
7757 .fa-shield:before {
7758 content: "\f132";
7759 }
7760 .fa-calendar-o:before {
7761 content: "\f133";
7762 }
7763 .fa-fire-extinguisher:before {
7764 content: "\f134";
7765 }
7766 .fa-rocket:before {
7767 content: "\f135";
7768 }
7769 .fa-maxcdn:before {
7770 content: "\f136";
7771 }
7772 .fa-chevron-circle-left:before {
7773 content: "\f137";
7774 }
7775 .fa-chevron-circle-right:before {
7776 content: "\f138";
7777 }
7778 .fa-chevron-circle-up:before {
7779 content: "\f139";
7780 }
7781 .fa-chevron-circle-down:before {
7782 content: "\f13a";
7783 }
7784 .fa-html5:before {
7785 content: "\f13b";
7786 }
7787 .fa-css3:before {
7788 content: "\f13c";
7789 }
7790 .fa-anchor:before {
7791 content: "\f13d";
7792 }
7793 .fa-unlock-alt:before {
7794 content: "\f13e";
7795 }
7796 .fa-bullseye:before {
7797 content: "\f140";
7798 }
7799 .fa-ellipsis-h:before {
7800 content: "\f141";
7801 }
7802 .fa-ellipsis-v:before {
7803 content: "\f142";
7804 }
7805 .fa-rss-square:before {
7806 content: "\f143";
7807 }
7808 .fa-play-circle:before {
7809 content: "\f144";
7810 }
7811 .fa-ticket:before {
7812 content: "\f145";
7813 }
7814 .fa-minus-square:before {
7815 content: "\f146";
7816 }
7817 .fa-minus-square-o:before {
7818 content: "\f147";
7819 }
7820 .fa-level-up:before {
7821 content: "\f148";
7822 }
7823 .fa-level-down:before {
7824 content: "\f149";
7825 }
7826 .fa-check-square:before {
7827 content: "\f14a";
7828 }
7829 .fa-pencil-square:before {
7830 content: "\f14b";
7831 }
7832 .fa-external-link-square:before {
7833 content: "\f14c";
7834 }
7835 .fa-share-square:before {
7836 content: "\f14d";
7837 }
7838 .fa-compass:before {
7839 content: "\f14e";
7840 }
7841 .fa-toggle-down:before,
7842 .fa-caret-square-o-down:before {
7843 content: "\f150";
7844 }
7845 .fa-toggle-up:before,
7846 .fa-caret-square-o-up:before {
7847 content: "\f151";
7848 }
7849 .fa-toggle-right:before,
7850 .fa-caret-square-o-right:before {
7851 content: "\f152";
7852 }
7853 .fa-euro:before,
7854 .fa-eur:before {
7855 content: "\f153";
7856 }
7857 .fa-gbp:before {
7858 content: "\f154";
7859 }
7860 .fa-dollar:before,
7861 .fa-usd:before {
7862 content: "\f155";
7863 }
7864 .fa-rupee:before,
7865 .fa-inr:before {
7866 content: "\f156";
7867 }
7868 .fa-cny:before,
7869 .fa-rmb:before,
7870 .fa-yen:before,
7871 .fa-jpy:before {
7872 content: "\f157";
7873 }
7874 .fa-ruble:before,
7875 .fa-rouble:before,
7876 .fa-rub:before {
7877 content: "\f158";
7878 }
7879 .fa-won:before,
7880 .fa-krw:before {
7881 content: "\f159";
7882 }
7883 .fa-bitcoin:before,
7884 .fa-btc:before {
7885 content: "\f15a";
7886 }
7887 .fa-file:before {
7888 content: "\f15b";
7889 }
7890 .fa-file-text:before {
7891 content: "\f15c";
7892 }
7893 .fa-sort-alpha-asc:before {
7894 content: "\f15d";
7895 }
7896 .fa-sort-alpha-desc:before {
7897 content: "\f15e";
7898 }
7899 .fa-sort-amount-asc:before {
7900 content: "\f160";
7901 }
7902 .fa-sort-amount-desc:before {
7903 content: "\f161";
7904 }
7905 .fa-sort-numeric-asc:before {
7906 content: "\f162";
7907 }
7908 .fa-sort-numeric-desc:before {
7909 content: "\f163";
7910 }
7911 .fa-thumbs-up:before {
7912 content: "\f164";
7913 }
7914 .fa-thumbs-down:before {
7915 content: "\f165";
7916 }
7917 .fa-youtube-square:before {
7918 content: "\f166";
7919 }
7920 .fa-youtube:before {
7921 content: "\f167";
7922 }
7923 .fa-xing:before {
7924 content: "\f168";
7925 }
7926 .fa-xing-square:before {
7927 content: "\f169";
7928 }
7929 .fa-youtube-play:before {
7930 content: "\f16a";
7931 }
7932 .fa-dropbox:before {
7933 content: "\f16b";
7934 }
7935 .fa-stack-overflow:before {
7936 content: "\f16c";
7937 }
7938 .fa-instagram:before {
7939 content: "\f16d";
7940 }
7941 .fa-flickr:before {
7942 content: "\f16e";
7943 }
7944 .fa-adn:before {
7945 content: "\f170";
7946 }
7947 .fa-bitbucket:before {
7948 content: "\f171";
7949 }
7950 .fa-bitbucket-square:before {
7951 content: "\f172";
7952 }
7953 .fa-tumblr:before {
7954 content: "\f173";
7955 }
7956 .fa-tumblr-square:before {
7957 content: "\f174";
7958 }
7959 .fa-long-arrow-down:before {
7960 content: "\f175";
7961 }
7962 .fa-long-arrow-up:before {
7963 content: "\f176";
7964 }
7965 .fa-long-arrow-left:before {
7966 content: "\f177";
7967 }
7968 .fa-long-arrow-right:before {
7969 content: "\f178";
7970 }
7971 .fa-apple:before {
7972 content: "\f179";
7973 }
7974 .fa-windows:before {
7975 content: "\f17a";
7976 }
7977 .fa-android:before {
7978 content: "\f17b";
7979 }
7980 .fa-linux:before {
7981 content: "\f17c";
7982 }
7983 .fa-dribbble:before {
7984 content: "\f17d";
7985 }
7986 .fa-skype:before {
7987 content: "\f17e";
7988 }
7989 .fa-foursquare:before {
7990 content: "\f180";
7991 }
7992 .fa-trello:before {
7993 content: "\f181";
7994 }
7995 .fa-female:before {
7996 content: "\f182";
7997 }
7998 .fa-male:before {
7999 content: "\f183";
8000 }
8001 .fa-gittip:before {
8002 content: "\f184";
8003 }
8004 .fa-sun-o:before {
8005 content: "\f185";
8006 }
8007 .fa-moon-o:before {
8008 content: "\f186";
8009 }
8010 .fa-archive:before {
8011 content: "\f187";
8012 }
8013 .fa-bug:before {
8014 content: "\f188";
8015 }
8016 .fa-vk:before {
8017 content: "\f189";
8018 }
8019 .fa-weibo:before {
8020 content: "\f18a";
8021 }
8022 .fa-renren:before {
8023 content: "\f18b";
8024 }
8025 .fa-pagelines:before {
8026 content: "\f18c";
8027 }
8028 .fa-stack-exchange:before {
8029 content: "\f18d";
8030 }
8031 .fa-arrow-circle-o-right:before {
8032 content: "\f18e";
8033 }
8034 .fa-arrow-circle-o-left:before {
8035 content: "\f190";
8036 }
8037 .fa-toggle-left:before,
8038 .fa-caret-square-o-left:before {
8039 content: "\f191";
8040 }
8041 .fa-dot-circle-o:before {
8042 content: "\f192";
8043 }
8044 .fa-wheelchair:before {
8045 content: "\f193";
8046 }
8047 .fa-vimeo-square:before {
8048 content: "\f194";
8049 }
8050 .fa-turkish-lira:before,
8051 .fa-try:before {
8052 content: "\f195";
8053 }
8054 .fa-plus-square-o:before {
8055 content: "\f196";
8056 }
8057 .fa-space-shuttle:before {
8058 content: "\f197";
8059 }
8060 .fa-slack:before {
8061 content: "\f198";
8062 }
8063 .fa-envelope-square:before {
8064 content: "\f199";
8065 }
8066 .fa-wordpress:before {
8067 content: "\f19a";
8068 }
8069 .fa-openid:before {
8070 content: "\f19b";
8071 }
8072 .fa-institution:before,
8073 .fa-bank:before,
8074 .fa-university:before {
8075 content: "\f19c";
8076 }
8077 .fa-mortar-board:before,
8078 .fa-graduation-cap:before {
8079 content: "\f19d";
8080 }
8081 .fa-yahoo:before {
8082 content: "\f19e";
8083 }
8084 .fa-google:before {
8085 content: "\f1a0";
8086 }
8087 .fa-reddit:before {
8088 content: "\f1a1";
8089 }
8090 .fa-reddit-square:before {
8091 content: "\f1a2";
8092 }
8093 .fa-stumbleupon-circle:before {
8094 content: "\f1a3";
8095 }
8096 .fa-stumbleupon:before {
8097 content: "\f1a4";
8098 }
8099 .fa-delicious:before {
8100 content: "\f1a5";
8101 }
8102 .fa-digg:before {
8103 content: "\f1a6";
8104 }
8105 .fa-pied-piper:before {
8106 content: "\f1a7";
8107 }
8108 .fa-pied-piper-alt:before {
8109 content: "\f1a8";
8110 }
8111 .fa-drupal:before {
8112 content: "\f1a9";
8113 }
8114 .fa-joomla:before {
8115 content: "\f1aa";
8116 }
8117 .fa-language:before {
8118 content: "\f1ab";
8119 }
8120 .fa-fax:before {
8121 content: "\f1ac";
8122 }
8123 .fa-building:before {
8124 content: "\f1ad";
8125 }
8126 .fa-child:before {
8127 content: "\f1ae";
8128 }
8129 .fa-paw:before {
8130 content: "\f1b0";
8131 }
8132 .fa-spoon:before {
8133 content: "\f1b1";
8134 }
8135 .fa-cube:before {
8136 content: "\f1b2";
8137 }
8138 .fa-cubes:before {
8139 content: "\f1b3";
8140 }
8141 .fa-behance:before {
8142 content: "\f1b4";
8143 }
8144 .fa-behance-square:before {
8145 content: "\f1b5";
8146 }
8147 .fa-steam:before {
8148 content: "\f1b6";
8149 }
8150 .fa-steam-square:before {
8151 content: "\f1b7";
8152 }
8153 .fa-recycle:before {
8154 content: "\f1b8";
8155 }
8156 .fa-automobile:before,
8157 .fa-car:before {
8158 content: "\f1b9";
8159 }
8160 .fa-cab:before,
8161 .fa-taxi:before {
8162 content: "\f1ba";
8163 }
8164 .fa-tree:before {
8165 content: "\f1bb";
8166 }
8167 .fa-spotify:before {
8168 content: "\f1bc";
8169 }
8170 .fa-deviantart:before {
8171 content: "\f1bd";
8172 }
8173 .fa-soundcloud:before {
8174 content: "\f1be";
8175 }
8176 .fa-database:before {
8177 content: "\f1c0";
8178 }
8179 .fa-file-pdf-o:before {
8180 content: "\f1c1";
8181 }
8182 .fa-file-word-o:before {
8183 content: "\f1c2";
8184 }
8185 .fa-file-excel-o:before {
8186 content: "\f1c3";
8187 }
8188 .fa-file-powerpoint-o:before {
8189 content: "\f1c4";
8190 }
8191 .fa-file-photo-o:before,
8192 .fa-file-picture-o:before,
8193 .fa-file-image-o:before {
8194 content: "\f1c5";
8195 }
8196 .fa-file-zip-o:before,
8197 .fa-file-archive-o:before {
8198 content: "\f1c6";
8199 }
8200 .fa-file-sound-o:before,
8201 .fa-file-audio-o:before {
8202 content: "\f1c7";
8203 }
8204 .fa-file-movie-o:before,
8205 .fa-file-video-o:before {
8206 content: "\f1c8";
8207 }
8208 .fa-file-code-o:before {
8209 content: "\f1c9";
8210 }
8211 .fa-vine:before {
8212 content: "\f1ca";
8213 }
8214 .fa-codepen:before {
8215 content: "\f1cb";
8216 }
8217 .fa-jsfiddle:before {
8218 content: "\f1cc";
8219 }
8220 .fa-life-bouy:before,
8221 .fa-life-buoy:before,
8222 .fa-life-saver:before,
8223 .fa-support:before,
8224 .fa-life-ring:before {
8225 content: "\f1cd";
8226 }
8227 .fa-circle-o-notch:before {
8228 content: "\f1ce";
8229 }
8230 .fa-ra:before,
8231 .fa-rebel:before {
8232 content: "\f1d0";
8233 }
8234 .fa-ge:before,
8235 .fa-empire:before {
8236 content: "\f1d1";
8237 }
8238 .fa-git-square:before {
8239 content: "\f1d2";
8240 }
8241 .fa-git:before {
8242 content: "\f1d3";
8243 }
8244 .fa-hacker-news:before {
8245 content: "\f1d4";
8246 }
8247 .fa-tencent-weibo:before {
8248 content: "\f1d5";
8249 }
8250 .fa-qq:before {
8251 content: "\f1d6";
8252 }
8253 .fa-wechat:before,
8254 .fa-weixin:before {
8255 content: "\f1d7";
8256 }
8257 .fa-send:before,
8258 .fa-paper-plane:before {
8259 content: "\f1d8";
8260 }
8261 .fa-send-o:before,
8262 .fa-paper-plane-o:before {
8263 content: "\f1d9";
8264 }
8265 .fa-history:before {
8266 content: "\f1da";
8267 }
8268 .fa-circle-thin:before {
8269 content: "\f1db";
8270 }
8271 .fa-header:before {
8272 content: "\f1dc";
8273 }
8274 .fa-paragraph:before {
8275 content: "\f1dd";
8276 }
8277 .fa-sliders:before {
8278 content: "\f1de";
8279 }
8280 .fa-share-alt:before {
8281 content: "\f1e0";
8282 }
8283 .fa-share-alt-square:before {
8284 content: "\f1e1";
8285 }
8286 .fa-bomb:before {
8287 content: "\f1e2";
8288 }
8289 .fa-soccer-ball-o:before,
8290 .fa-futbol-o:before {
8291 content: "\f1e3";
8292 }
8293 .fa-tty:before {
8294 content: "\f1e4";
8295 }
8296 .fa-binoculars:before {
8297 content: "\f1e5";
8298 }
8299 .fa-plug:before {
8300 content: "\f1e6";
8301 }
8302 .fa-slideshare:before {
8303 content: "\f1e7";
8304 }
8305 .fa-twitch:before {
8306 content: "\f1e8";
8307 }
8308 .fa-yelp:before {
8309 content: "\f1e9";
8310 }
8311 .fa-newspaper-o:before {
8312 content: "\f1ea";
8313 }
8314 .fa-wifi:before {
8315 content: "\f1eb";
8316 }
8317 .fa-calculator:before {
8318 content: "\f1ec";
8319 }
8320 .fa-paypal:before {
8321 content: "\f1ed";
8322 }
8323 .fa-google-wallet:before {
8324 content: "\f1ee";
8325 }
8326 .fa-cc-visa:before {
8327 content: "\f1f0";
8328 }
8329 .fa-cc-mastercard:before {
8330 content: "\f1f1";
8331 }
8332 .fa-cc-discover:before {
8333 content: "\f1f2";
8334 }
8335 .fa-cc-amex:before {
8336 content: "\f1f3";
8337 }
8338 .fa-cc-paypal:before {
8339 content: "\f1f4";
8340 }
8341 .fa-cc-stripe:before {
8342 content: "\f1f5";
8343 }
8344 .fa-bell-slash:before {
8345 content: "\f1f6";
8346 }
8347 .fa-bell-slash-o:before {
8348 content: "\f1f7";
8349 }
8350 .fa-trash:before {
8351 content: "\f1f8";
8352 }
8353 .fa-copyright:before {
8354 content: "\f1f9";
8355 }
8356 .fa-at:before {
8357 content: "\f1fa";
8358 }
8359 .fa-eyedropper:before {
8360 content: "\f1fb";
8361 }
8362 .fa-paint-brush:before {
8363 content: "\f1fc";
8364 }
8365 .fa-birthday-cake:before {
8366 content: "\f1fd";
8367 }
8368 .fa-area-chart:before {
8369 content: "\f1fe";
8370 }
8371 .fa-pie-chart:before {
8372 content: "\f200";
8373 }
8374 .fa-line-chart:before {
8375 content: "\f201";
8376 }
8377 .fa-lastfm:before {
8378 content: "\f202";
8379 }
8380 .fa-lastfm-square:before {
8381 content: "\f203";
8382 }
8383 .fa-toggle-off:before {
8384 content: "\f204";
8385 }
8386 .fa-toggle-on:before {
8387 content: "\f205";
8388 }
8389 .fa-bicycle:before {
8390 content: "\f206";
8391 }
8392 .fa-bus:before {
8393 content: "\f207";
8394 }
8395 .fa-ioxhost:before {
8396 content: "\f208";
8397 }
8398 .fa-angellist:before {
8399 content: "\f209";
8400 }
8401 .fa-cc:before {
8402 content: "\f20a";
8403 }
8404 .fa-shekel:before,
8405 .fa-sheqel:before,
8406 .fa-ils:before {
8407 content: "\f20b";
8408 }
8409 .fa-meanpath:before {
8410 content: "\f20c";
8411 }
8412 /*!
8413 *
8414 * IPython base
8415 *
8416 */
8417 .modal.fade .modal-dialog {
8418 -webkit-transform: translate(0, 0);
8419 -ms-transform: translate(0, 0);
8420 -o-transform: translate(0, 0);
8421 transform: translate(0, 0);
8422 }
8423 code {
8424 color: #000;
8425 }
8426 pre {
8427 font-size: inherit;
8428 line-height: inherit;
8429 }
8430 label {
8431 font-weight: normal;
8432 }
8433 /* Make the page background atleast 100% the height of the view port */
8434 /* Make the page itself atleast 70% the height of the view port */
8435 .border-box-sizing {
8436 box-sizing: border-box;
8437 -moz-box-sizing: border-box;
8438 -webkit-box-sizing: border-box;
8439 }
8440 .corner-all {
8441 border-radius: 2px;
8442 }
8443 .no-padding {
8444 padding: 0px;
8445 }
8446 /* Flexible box model classes */
8447 /* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
8448 /* This file is a compatability layer. It allows the usage of flexible box
8449 model layouts accross multiple browsers, including older browsers. The newest,
8450 universal implementation of the flexible box model is used when available (see
8451 `Modern browsers` comments below). Browsers that are known to implement this
8452 new spec completely include:
8453
8454 Firefox 28.0+
8455 Chrome 29.0+
8456 Internet Explorer 11+
8457 Opera 17.0+
8458
8459 Browsers not listed, including Safari, are supported via the styling under the
8460 `Old browsers` comments below.
8461 */
8462 .hbox {
8463 /* Old browsers */
8464 display: -webkit-box;
8465 -webkit-box-orient: horizontal;
8466 -webkit-box-align: stretch;
8467 display: -moz-box;
8468 -moz-box-orient: horizontal;
8469 -moz-box-align: stretch;
8470 display: box;
8471 box-orient: horizontal;
8472 box-align: stretch;
8473 /* Modern browsers */
8474 display: flex;
8475 flex-direction: row;
8476 align-items: stretch;
8477 }
8478 .hbox > * {
8479 /* Old browsers */
8480 -webkit-box-flex: 0;
8481 -moz-box-flex: 0;
8482 box-flex: 0;
8483 /* Modern browsers */
8484 flex: none;
8485 }
8486 .vbox {
8487 /* Old browsers */
8488 display: -webkit-box;
8489 -webkit-box-orient: vertical;
8490 -webkit-box-align: stretch;
8491 display: -moz-box;
8492 -moz-box-orient: vertical;
8493 -moz-box-align: stretch;
8494 display: box;
8495 box-orient: vertical;
8496 box-align: stretch;
8497 /* Modern browsers */
8498 display: flex;
8499 flex-direction: column;
8500 align-items: stretch;
8501 }
8502 .vbox > * {
8503 /* Old browsers */
8504 -webkit-box-flex: 0;
8505 -moz-box-flex: 0;
8506 box-flex: 0;
8507 /* Modern browsers */
8508 flex: none;
8509 }
8510 .hbox.reverse,
8511 .vbox.reverse,
8512 .reverse {
8513 /* Old browsers */
8514 -webkit-box-direction: reverse;
8515 -moz-box-direction: reverse;
8516 box-direction: reverse;
8517 /* Modern browsers */
8518 flex-direction: row-reverse;
8519 }
8520 .hbox.box-flex0,
8521 .vbox.box-flex0,
8522 .box-flex0 {
8523 /* Old browsers */
8524 -webkit-box-flex: 0;
8525 -moz-box-flex: 0;
8526 box-flex: 0;
8527 /* Modern browsers */
8528 flex: none;
8529 width: auto;
8530 }
8531 .hbox.box-flex1,
8532 .vbox.box-flex1,
8533 .box-flex1 {
8534 /* Old browsers */
8535 -webkit-box-flex: 1;
8536 -moz-box-flex: 1;
8537 box-flex: 1;
8538 /* Modern browsers */
8539 flex: 1;
8540 }
8541 .hbox.box-flex,
8542 .vbox.box-flex,
8543 .box-flex {
8544 /* Old browsers */
8545 /* Old browsers */
8546 -webkit-box-flex: 1;
8547 -moz-box-flex: 1;
8548 box-flex: 1;
8549 /* Modern browsers */
8550 flex: 1;
8551 }
8552 .hbox.box-flex2,
8553 .vbox.box-flex2,
8554 .box-flex2 {
8555 /* Old browsers */
8556 -webkit-box-flex: 2;
8557 -moz-box-flex: 2;
8558 box-flex: 2;
8559 /* Modern browsers */
8560 flex: 2;
8561 }
8562 .box-group1 {
8563 /* Deprecated */
8564 -webkit-box-flex-group: 1;
8565 -moz-box-flex-group: 1;
8566 box-flex-group: 1;
8567 }
8568 .box-group2 {
8569 /* Deprecated */
8570 -webkit-box-flex-group: 2;
8571 -moz-box-flex-group: 2;
8572 box-flex-group: 2;
8573 }
8574 .hbox.start,
8575 .vbox.start,
8576 .start {
8577 /* Old browsers */
8578 -webkit-box-pack: start;
8579 -moz-box-pack: start;
8580 box-pack: start;
8581 /* Modern browsers */
8582 justify-content: flex-start;
8583 }
8584 .hbox.end,
8585 .vbox.end,
8586 .end {
8587 /* Old browsers */
8588 -webkit-box-pack: end;
8589 -moz-box-pack: end;
8590 box-pack: end;
8591 /* Modern browsers */
8592 justify-content: flex-end;
8593 }
8594 .hbox.center,
8595 .vbox.center,
8596 .center {
8597 /* Old browsers */
8598 -webkit-box-pack: center;
8599 -moz-box-pack: center;
8600 box-pack: center;
8601 /* Modern browsers */
8602 justify-content: center;
8603 }
8604 .hbox.baseline,
8605 .vbox.baseline,
8606 .baseline {
8607 /* Old browsers */
8608 -webkit-box-pack: baseline;
8609 -moz-box-pack: baseline;
8610 box-pack: baseline;
8611 /* Modern browsers */
8612 justify-content: baseline;
8613 }
8614 .hbox.stretch,
8615 .vbox.stretch,
8616 .stretch {
8617 /* Old browsers */
8618 -webkit-box-pack: stretch;
8619 -moz-box-pack: stretch;
8620 box-pack: stretch;
8621 /* Modern browsers */
8622 justify-content: stretch;
8623 }
8624 .hbox.align-start,
8625 .vbox.align-start,
8626 .align-start {
8627 /* Old browsers */
8628 -webkit-box-align: start;
8629 -moz-box-align: start;
8630 box-align: start;
8631 /* Modern browsers */
8632 align-items: flex-start;
8633 }
8634 .hbox.align-end,
8635 .vbox.align-end,
8636 .align-end {
8637 /* Old browsers */
8638 -webkit-box-align: end;
8639 -moz-box-align: end;
8640 box-align: end;
8641 /* Modern browsers */
8642 align-items: flex-end;
8643 }
8644 .hbox.align-center,
8645 .vbox.align-center,
8646 .align-center {
8647 /* Old browsers */
8648 -webkit-box-align: center;
8649 -moz-box-align: center;
8650 box-align: center;
8651 /* Modern browsers */
8652 align-items: center;
8653 }
8654 .hbox.align-baseline,
8655 .vbox.align-baseline,
8656 .align-baseline {
8657 /* Old browsers */
8658 -webkit-box-align: baseline;
8659 -moz-box-align: baseline;
8660 box-align: baseline;
8661 /* Modern browsers */
8662 align-items: baseline;
8663 }
8664 .hbox.align-stretch,
8665 .vbox.align-stretch,
8666 .align-stretch {
8667 /* Old browsers */
8668 -webkit-box-align: stretch;
8669 -moz-box-align: stretch;
8670 box-align: stretch;
8671 /* Modern browsers */
8672 align-items: stretch;
8673 }
8674 div.error {
8675 margin: 2em;
8676 text-align: center;
8677 }
8678 div.error > h1 {
8679 font-size: 500%;
8680 line-height: normal;
8681 }
8682 div.error > p {
8683 font-size: 200%;
8684 line-height: normal;
8685 }
8686 div.traceback-wrapper {
8687 text-align: left;
8688 max-width: 800px;
8689 margin: auto;
8690 }
8691 /**
8692 * Primary styles
8693 *
8694 * Author: Jupyter Development Team
8695 */
8696 body {
8697 background-color: #fff;
8698 /* This makes sure that the body covers the entire window and needs to
8699 be in a different element than the display: box in wrapper below */
8700 position: absolute;
8701 left: 0px;
8702 right: 0px;
8703 top: 0px;
8704 bottom: 0px;
8705 overflow: visible;
8706 }
8707 body > #header {
8708 /* Initially hidden to prevent FLOUC */
8709 display: none;
8710 background-color: #fff;
8711 /* Display over codemirror */
8712 position: relative;
8713 z-index: 100;
8714 }
8715 body > #header #header-container {
8716 padding-bottom: 5px;
8717 padding-top: 5px;
8718 box-sizing: border-box;
8719 -moz-box-sizing: border-box;
8720 -webkit-box-sizing: border-box;
8721 }
8722 body > #header .header-bar {
8723 width: 100%;
8724 height: 1px;
8725 background: #e7e7e7;
8726 margin-bottom: -1px;
8727 }
8728 @media print {
8729 body > #header {
8730 display: none !important;
8731 }
8732 }
8733 #header-spacer {
8734 width: 100%;
8735 visibility: hidden;
8736 }
8737 @media print {
8738 #header-spacer {
8739 display: none;
8740 }
8741 }
8742 #ipython_notebook {
8743 padding-left: 0px;
8744 padding-top: 1px;
8745 padding-bottom: 1px;
8746 }
8747 @media (max-width: 991px) {
8748 #ipython_notebook {
8749 margin-left: 10px;
8750 }
8751 }
8752 [dir="rtl"] #ipython_notebook {
8753 float: right !important;
8754 }
8755 #noscript {
8756 width: auto;
8757 padding-top: 16px;
8758 padding-bottom: 16px;
8759 text-align: center;
8760 font-size: 22px;
8761 color: red;
8762 font-weight: bold;
8763 }
8764 #ipython_notebook img {
8765 height: 28px;
8766 }
8767 #site {
8768 width: 100%;
8769 display: none;
8770 box-sizing: border-box;
8771 -moz-box-sizing: border-box;
8772 -webkit-box-sizing: border-box;
8773 overflow: auto;
8774 }
8775 @media print {
8776 #site {
8777 height: auto !important;
8778 }
8779 }
8780 /* Smaller buttons */
8781 .ui-button .ui-button-text {
8782 padding: 0.2em 0.8em;
8783 font-size: 77%;
8784 }
8785 input.ui-button {
8786 padding: 0.3em 0.9em;
8787 }
8788 span#login_widget {
8789 float: right;
8790 }
8791 span#login_widget > .button,
8792 #logout {
8793 color: #333;
8794 background-color: #fff;
8795 border-color: #ccc;
8796 }
8797 span#login_widget > .button:focus,
8798 #logout:focus,
8799 span#login_widget > .button.focus,
8800 #logout.focus {
8801 color: #333;
8802 background-color: #e6e6e6;
8803 border-color: #8c8c8c;
8804 }
8805 span#login_widget > .button:hover,
8806 #logout:hover {
8807 color: #333;
8808 background-color: #e6e6e6;
8809 border-color: #adadad;
8810 }
8811 span#login_widget > .button:active,
8812 #logout:active,
8813 span#login_widget > .button.active,
8814 #logout.active,
8815 .open > .dropdown-togglespan#login_widget > .button,
8816 .open > .dropdown-toggle#logout {
8817 color: #333;
8818 background-color: #e6e6e6;
8819 border-color: #adadad;
8820 }
8821 span#login_widget > .button:active:hover,
8822 #logout:active:hover,
8823 span#login_widget > .button.active:hover,
8824 #logout.active:hover,
8825 .open > .dropdown-togglespan#login_widget > .button:hover,
8826 .open > .dropdown-toggle#logout:hover,
8827 span#login_widget > .button:active:focus,
8828 #logout:active:focus,
8829 span#login_widget > .button.active:focus,
8830 #logout.active:focus,
8831 .open > .dropdown-togglespan#login_widget > .button:focus,
8832 .open > .dropdown-toggle#logout:focus,
8833 span#login_widget > .button:active.focus,
8834 #logout:active.focus,
8835 span#login_widget > .button.active.focus,
8836 #logout.active.focus,
8837 .open > .dropdown-togglespan#login_widget > .button.focus,
8838 .open > .dropdown-toggle#logout.focus {
8839 color: #333;
8840 background-color: #d4d4d4;
8841 border-color: #8c8c8c;
8842 }
8843 span#login_widget > .button:active,
8844 #logout:active,
8845 span#login_widget > .button.active,
8846 #logout.active,
8847 .open > .dropdown-togglespan#login_widget > .button,
8848 .open > .dropdown-toggle#logout {
8849 background-image: none;
8850 }
8851 span#login_widget > .button.disabled:hover,
8852 #logout.disabled:hover,
8853 span#login_widget > .button[disabled]:hover,
8854 #logout[disabled]:hover,
8855 fieldset[disabled] span#login_widget > .button:hover,
8856 fieldset[disabled] #logout:hover,
8857 span#login_widget > .button.disabled:focus,
8858 #logout.disabled:focus,
8859 span#login_widget > .button[disabled]:focus,
8860 #logout[disabled]:focus,
8861 fieldset[disabled] span#login_widget > .button:focus,
8862 fieldset[disabled] #logout:focus,
8863 span#login_widget > .button.disabled.focus,
8864 #logout.disabled.focus,
8865 span#login_widget > .button[disabled].focus,
8866 #logout[disabled].focus,
8867 fieldset[disabled] span#login_widget > .button.focus,
8868 fieldset[disabled] #logout.focus {
8869 background-color: #fff;
8870 border-color: #ccc;
8871 }
8872 span#login_widget > .button .badge,
8873 #logout .badge {
8874 color: #fff;
8875 background-color: #333;
8876 }
8877 .nav-header {
8878 text-transform: none;
8879 }
8880 #header > span {
8881 margin-top: 10px;
8882 }
8883 .modal_stretch .modal-dialog {
8884 /* Old browsers */
8885 display: -webkit-box;
8886 -webkit-box-orient: vertical;
8887 -webkit-box-align: stretch;
8888 display: -moz-box;
8889 -moz-box-orient: vertical;
8890 -moz-box-align: stretch;
8891 display: box;
8892 box-orient: vertical;
8893 box-align: stretch;
8894 /* Modern browsers */
8895 display: flex;
8896 flex-direction: column;
8897 align-items: stretch;
8898 min-height: 80vh;
8899 }
8900 .modal_stretch .modal-dialog .modal-body {
8901 max-height: calc(100vh - 200px);
8902 overflow: auto;
8903 flex: 1;
8904 }
8905 @media (min-width: 768px) {
8906 .modal .modal-dialog {
8907 width: 700px;
8908 }
8909 }
8910 @media (min-width: 768px) {
8911 select.form-control {
8912 margin-left: 12px;
8913 margin-right: 12px;
8914 }
8915 }
8916 /*!
8917 *
8918 * IPython auth
8919 *
8920 */
8921 .center-nav {
8922 display: inline-block;
8923 margin-bottom: -4px;
8924 }
8925 /*!
8926 *
8927 * IPython tree view
8928 *
8929 */
8930 /* We need an invisible input field on top of the sentense*/
8931 /* "Drag file onto the list ..." */
8932 .alternate_upload {
8933 background-color: none;
8934 display: inline;
8935 }
8936 .alternate_upload.form {
8937 padding: 0;
8938 margin: 0;
8939 }
8940 .alternate_upload input.fileinput {
8941 text-align: center;
8942 vertical-align: middle;
8943 display: inline;
8944 opacity: 0;
8945 z-index: 2;
8946 width: 12ex;
8947 margin-right: -12ex;
8948 }
8949 .alternate_upload .btn-upload {
8950 height: 22px;
8951 }
8952 /**
8953 * Primary styles
8954 *
8955 * Author: Jupyter Development Team
8956 */
8957 [dir="rtl"] #tabs li {
8958 float: right;
8959 }
8960 ul#tabs {
8961 margin-bottom: 4px;
8962 }
8963 [dir="rtl"] ul#tabs {
8964 margin-right: 0px;
8965 }
8966 ul#tabs a {
8967 padding-top: 6px;
8968 padding-bottom: 4px;
8969 }
8970 ul.breadcrumb a:focus,
8971 ul.breadcrumb a:hover {
8972 text-decoration: none;
8973 }
8974 ul.breadcrumb i.icon-home {
8975 font-size: 16px;
8976 margin-right: 4px;
8977 }
8978 ul.breadcrumb span {
8979 color: #5e5e5e;
8980 }
8981 .list_toolbar {
8982 padding: 4px 0 4px 0;
8983 vertical-align: middle;
8984 }
8985 .list_toolbar .tree-buttons {
8986 padding-top: 1px;
8987 }
8988 [dir="rtl"] .list_toolbar .tree-buttons {
8989 float: left !important;
8990 }
8991 [dir="rtl"] .list_toolbar .pull-right {
8992 padding-top: 1px;
8993 float: left !important;
8994 }
8995 [dir="rtl"] .list_toolbar .pull-left {
8996 float: right !important;
8997 }
8998 .dynamic-buttons {
8999 padding-top: 3px;
9000 display: inline-block;
9001 }
9002 .list_toolbar [class*="span"] {
9003 min-height: 24px;
9004 }
9005 .list_header {
9006 font-weight: bold;
9007 background-color: #EEE;
9008 }
9009 .list_placeholder {
9010 font-weight: bold;
9011 padding-top: 4px;
9012 padding-bottom: 4px;
9013 padding-left: 7px;
9014 padding-right: 7px;
9015 }
9016 .list_container {
9017 margin-top: 4px;
9018 margin-bottom: 20px;
9019 border: 1px solid #ddd;
9020 border-radius: 2px;
9021 }
9022 .list_container > div {
9023 border-bottom: 1px solid #ddd;
9024 }
9025 .list_container > div:hover .list-item {
9026 background-color: red;
9027 }
9028 .list_container > div:last-child {
9029 border: none;
9030 }
9031 .list_item:hover .list_item {
9032 background-color: #ddd;
9033 }
9034 .list_item a {
9035 text-decoration: none;
9036 }
9037 .list_item:hover {
9038 background-color: #fafafa;
9039 }
9040 .list_header > div,
9041 .list_item > div {
9042 padding-top: 4px;
9043 padding-bottom: 4px;
9044 padding-left: 7px;
9045 padding-right: 7px;
9046 line-height: 22px;
9047 }
9048 .list_header > div input,
9049 .list_item > div input {
9050 margin-right: 7px;
9051 margin-left: 14px;
9052 vertical-align: baseline;
9053 line-height: 22px;
9054 position: relative;
9055 top: -1px;
9056 }
9057 .list_header > div .item_link,
9058 .list_item > div .item_link {
9059 margin-left: -1px;
9060 vertical-align: baseline;
9061 line-height: 22px;
9062 }
9063 .new-file input[type=checkbox] {
9064 visibility: hidden;
9065 }
9066 .item_name {
9067 line-height: 22px;
9068 height: 24px;
9069 }
9070 .item_icon {
9071 font-size: 14px;
9072 color: #5e5e5e;
9073 margin-right: 7px;
9074 margin-left: 7px;
9075 line-height: 22px;
9076 vertical-align: baseline;
9077 }
9078 .item_buttons {
9079 line-height: 1em;
9080 margin-left: -5px;
9081 }
9082 .item_buttons .btn,
9083 .item_buttons .btn-group,
9084 .item_buttons .input-group {
9085 float: left;
9086 }
9087 .item_buttons > .btn,
9088 .item_buttons > .btn-group,
9089 .item_buttons > .input-group {
9090 margin-left: 5px;
9091 }
9092 .item_buttons .btn {
9093 min-width: 13ex;
9094 }
9095 .item_buttons .running-indicator {
9096 padding-top: 4px;
9097 color: #5cb85c;
9098 }
9099 .item_buttons .kernel-name {
9100 padding-top: 4px;
9101 color: #5bc0de;
9102 margin-right: 7px;
9103 float: left;
9104 }
9105 .toolbar_info {
9106 height: 24px;
9107 line-height: 24px;
9108 }
9109 .list_item input:not([type=checkbox]) {
9110 padding-top: 3px;
9111 padding-bottom: 3px;
9112 height: 22px;
9113 line-height: 14px;
9114 margin: 0px;
9115 }
9116 .highlight_text {
9117 color: blue;
9118 }
9119 #project_name {
9120 display: inline-block;
9121 padding-left: 7px;
9122 margin-left: -2px;
9123 }
9124 #project_name > .breadcrumb {
9125 padding: 0px;
9126 margin-bottom: 0px;
9127 background-color: transparent;
9128 font-weight: bold;
9129 }
9130 #tree-selector {
9131 padding-right: 0px;
9132 }
9133 [dir="rtl"] #tree-selector a {
9134 float: right;
9135 }
9136 #button-select-all {
9137 min-width: 50px;
9138 }
9139 #select-all {
9140 margin-left: 7px;
9141 margin-right: 2px;
9142 }
9143 .menu_icon {
9144 margin-right: 2px;
9145 }
9146 .tab-content .row {
9147 margin-left: 0px;
9148 margin-right: 0px;
9149 }
9150 .folder_icon:before {
9151 display: inline-block;
9152 font: normal normal normal 14px/1 FontAwesome;
9153 font-size: inherit;
9154 text-rendering: auto;
9155 -webkit-font-smoothing: antialiased;
9156 -moz-osx-font-smoothing: grayscale;
9157 content: "\f114";
9158 }
9159 .folder_icon:before.pull-left {
9160 margin-right: .3em;
9161 }
9162 .folder_icon:before.pull-right {
9163 margin-left: .3em;
9164 }
9165 .notebook_icon:before {
9166 display: inline-block;
9167 font: normal normal normal 14px/1 FontAwesome;
9168 font-size: inherit;
9169 text-rendering: auto;
9170 -webkit-font-smoothing: antialiased;
9171 -moz-osx-font-smoothing: grayscale;
9172 content: "\f02d";
9173 position: relative;
9174 top: -1px;
9175 }
9176 .notebook_icon:before.pull-left {
9177 margin-right: .3em;
9178 }
9179 .notebook_icon:before.pull-right {
9180 margin-left: .3em;
9181 }
9182 .running_notebook_icon:before {
9183 display: inline-block;
9184 font: normal normal normal 14px/1 FontAwesome;
9185 font-size: inherit;
9186 text-rendering: auto;
9187 -webkit-font-smoothing: antialiased;
9188 -moz-osx-font-smoothing: grayscale;
9189 content: "\f02d";
9190 position: relative;
9191 top: -1px;
9192 color: #5cb85c;
9193 }
9194 .running_notebook_icon:before.pull-left {
9195 margin-right: .3em;
9196 }
9197 .running_notebook_icon:before.pull-right {
9198 margin-left: .3em;
9199 }
9200 .file_icon:before {
9201 display: inline-block;
9202 font: normal normal normal 14px/1 FontAwesome;
9203 font-size: inherit;
9204 text-rendering: auto;
9205 -webkit-font-smoothing: antialiased;
9206 -moz-osx-font-smoothing: grayscale;
9207 content: "\f016";
9208 position: relative;
9209 top: -2px;
9210 }
9211 .file_icon:before.pull-left {
9212 margin-right: .3em;
9213 }
9214 .file_icon:before.pull-right {
9215 margin-left: .3em;
9216 }
9217 #notebook_toolbar .pull-right {
9218 padding-top: 0px;
9219 margin-right: -1px;
9220 }
9221 ul#new-menu {
9222 left: auto;
9223 right: 0;
9224 }
9225 [dir="rtl"] #new-menu {
9226 text-align: right;
9227 }
9228 .kernel-menu-icon {
9229 padding-right: 12px;
9230 width: 24px;
9231 content: "\f096";
9232 }
9233 .kernel-menu-icon:before {
9234 content: "\f096";
9235 }
9236 .kernel-menu-icon-current:before {
9237 content: "\f00c";
9238 }
9239 #tab_content {
9240 padding-top: 20px;
9241 }
9242 #running .panel-group .panel {
9243 margin-top: 3px;
9244 margin-bottom: 1em;
9245 }
9246 #running .panel-group .panel .panel-heading {
9247 background-color: #EEE;
9248 padding-top: 4px;
9249 padding-bottom: 4px;
9250 padding-left: 7px;
9251 padding-right: 7px;
9252 line-height: 22px;
9253 }
9254 #running .panel-group .panel .panel-heading a:focus,
9255 #running .panel-group .panel .panel-heading a:hover {
9256 text-decoration: none;
9257 }
9258 #running .panel-group .panel .panel-body {
9259 padding: 0px;
9260 }
9261 #running .panel-group .panel .panel-body .list_container {
9262 margin-top: 0px;
9263 margin-bottom: 0px;
9264 border: 0px;
9265 border-radius: 0px;
9266 }
9267 #running .panel-group .panel .panel-body .list_container .list_item {
9268 border-bottom: 1px solid #ddd;
9269 }
9270 #running .panel-group .panel .panel-body .list_container .list_item:last-child {
9271 border-bottom: 0px;
9272 }
9273 [dir="rtl"] #running .col-sm-8 {
9274 float: right !important;
9275 }
9276 .delete-button {
9277 display: none;
9278 }
9279 .duplicate-button {
9280 display: none;
9281 }
9282 .rename-button {
9283 display: none;
9284 }
9285 .shutdown-button {
9286 display: none;
9287 }
9288 .dynamic-instructions {
9289 display: inline-block;
9290 padding-top: 4px;
9291 }
9292 /*!
9293 *
9294 * IPython text editor webapp
9295 *
9296 */
9297 .selected-keymap i.fa {
9298 padding: 0px 5px;
9299 }
9300 .selected-keymap i.fa:before {
9301 content: "\f00c";
9302 }
9303 #mode-menu {
9304 overflow: auto;
9305 max-height: 20em;
9306 }
9307 .edit_app #header {
9308 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
9309 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
9310 }
9311 .edit_app #menubar .navbar {
9312 /* Use a negative 1 bottom margin, so the border overlaps the border of the
9313 header */
9314 margin-bottom: -1px;
9315 }
9316 .dirty-indicator {
9317 display: inline-block;
9318 font: normal normal normal 14px/1 FontAwesome;
9319 font-size: inherit;
9320 text-rendering: auto;
9321 -webkit-font-smoothing: antialiased;
9322 -moz-osx-font-smoothing: grayscale;
9323 width: 20px;
9324 }
9325 .dirty-indicator.pull-left {
9326 margin-right: .3em;
9327 }
9328 .dirty-indicator.pull-right {
9329 margin-left: .3em;
9330 }
9331 .dirty-indicator-dirty {
9332 display: inline-block;
9333 font: normal normal normal 14px/1 FontAwesome;
9334 font-size: inherit;
9335 text-rendering: auto;
9336 -webkit-font-smoothing: antialiased;
9337 -moz-osx-font-smoothing: grayscale;
9338 width: 20px;
9339 }
9340 .dirty-indicator-dirty.pull-left {
9341 margin-right: .3em;
9342 }
9343 .dirty-indicator-dirty.pull-right {
9344 margin-left: .3em;
9345 }
9346 .dirty-indicator-clean {
9347 display: inline-block;
9348 font: normal normal normal 14px/1 FontAwesome;
9349 font-size: inherit;
9350 text-rendering: auto;
9351 -webkit-font-smoothing: antialiased;
9352 -moz-osx-font-smoothing: grayscale;
9353 width: 20px;
9354 }
9355 .dirty-indicator-clean.pull-left {
9356 margin-right: .3em;
9357 }
9358 .dirty-indicator-clean.pull-right {
9359 margin-left: .3em;
9360 }
9361 .dirty-indicator-clean:before {
9362 display: inline-block;
9363 font: normal normal normal 14px/1 FontAwesome;
9364 font-size: inherit;
9365 text-rendering: auto;
9366 -webkit-font-smoothing: antialiased;
9367 -moz-osx-font-smoothing: grayscale;
9368 content: "\f00c";
9369 }
9370 .dirty-indicator-clean:before.pull-left {
9371 margin-right: .3em;
9372 }
9373 .dirty-indicator-clean:before.pull-right {
9374 margin-left: .3em;
9375 }
9376 #filename {
9377 font-size: 16pt;
9378 display: table;
9379 padding: 0px 5px;
9380 }
9381 #current-mode {
9382 padding-left: 5px;
9383 padding-right: 5px;
9384 }
9385 #texteditor-backdrop {
9386 padding-top: 20px;
9387 padding-bottom: 20px;
9388 }
9389 @media not print {
9390 #texteditor-backdrop {
9391 background-color: #EEE;
9392 }
9393 }
9394 @media print {
9395 #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
9396 #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
9397 background-color: #fff;
9398 }
9399 }
9400 @media not print {
9401 #texteditor-backdrop #texteditor-container .CodeMirror-gutter,
9402 #texteditor-backdrop #texteditor-container .CodeMirror-gutters {
9403 background-color: #fff;
9404 }
9405 }
9406 @media not print {
9407 #texteditor-backdrop #texteditor-container {
9408 padding: 0px;
9409 background-color: #fff;
9410 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
9411 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
9412 }
9413 }
9414 /*!
9415 *
9416 * IPython notebook
9417 *
9418 */
9419 /* CSS font colors for translated ANSI colors. */
9420 .ansibold {
9421 font-weight: bold;
9422 }
9423 /* use dark versions for foreground, to improve visibility */
9424 .ansiblack {
9425 color: black;
9426 }
9427 .ansired {
9428 color: darkred;
9429 }
9430 .ansigreen {
9431 color: darkgreen;
9432 }
9433 .ansiyellow {
9434 color: #c4a000;
9435 }
9436 .ansiblue {
9437 color: darkblue;
9438 }
9439 .ansipurple {
9440 color: darkviolet;
9441 }
9442 .ansicyan {
9443 color: steelblue;
9444 }
9445 .ansigray {
9446 color: gray;
9447 }
9448 /* and light for background, for the same reason */
9449 .ansibgblack {
9450 background-color: black;
9451 }
9452 .ansibgred {
9453 background-color: red;
9454 }
9455 .ansibggreen {
9456 background-color: green;
9457 }
9458 .ansibgyellow {
9459 background-color: yellow;
9460 }
9461 .ansibgblue {
9462 background-color: blue;
9463 }
9464 .ansibgpurple {
9465 background-color: magenta;
9466 }
9467 .ansibgcyan {
9468 background-color: cyan;
9469 }
9470 .ansibggray {
9471 background-color: gray;
9472 }
9473 div.cell {
9474 /* Old browsers */
9475 display: -webkit-box;
9476 -webkit-box-orient: vertical;
9477 -webkit-box-align: stretch;
9478 display: -moz-box;
9479 -moz-box-orient: vertical;
9480 -moz-box-align: stretch;
9481 display: box;
9482 box-orient: vertical;
9483 box-align: stretch;
9484 /* Modern browsers */
9485 display: flex;
9486 flex-direction: column;
9487 align-items: stretch;
9488 border-radius: 2px;
9489 box-sizing: border-box;
9490 -moz-box-sizing: border-box;
9491 -webkit-box-sizing: border-box;
9492 border-width: 1px;
9493 border-style: solid;
9494 border-color: transparent;
9495 width: 100%;
9496 padding: 5px;
9497 /* This acts as a spacer between cells, that is outside the border */
9498 margin: 0px;
9499 outline: none;
9500 border-left-width: 1px;
9501 padding-left: 5px;
9502 background: linear-gradient(to right, transparent -40px, transparent 1px, transparent 1px, transparent 100%);
9503 }
9504 div.cell.jupyter-soft-selected {
9505 border-left-color: #90CAF9;
9506 border-left-color: #E3F2FD;
9507 border-left-width: 1px;
9508 padding-left: 5px;
9509 border-right-color: #E3F2FD;
9510 border-right-width: 1px;
9511 background: #E3F2FD;
9512 }
9513 @media print {
9514 div.cell.jupyter-soft-selected {
9515 border-color: transparent;
9516 }
9517 }
9518 div.cell.selected {
9519 border-color: #ababab;
9520 border-left-width: 0px;
9521 padding-left: 6px;
9522 background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 5px, transparent 5px, transparent 100%);
9523 }
9524 @media print {
9525 div.cell.selected {
9526 border-color: transparent;
9527 }
9528 }
9529 div.cell.selected.jupyter-soft-selected {
9530 border-left-width: 0;
9531 padding-left: 6px;
9532 background: linear-gradient(to right, #42A5F5 -40px, #42A5F5 7px, #E3F2FD 7px, #E3F2FD 100%);
9533 }
9534 .edit_mode div.cell.selected {
9535 border-color: #66BB6A;
9536 border-left-width: 0px;
9537 padding-left: 6px;
9538 background: linear-gradient(to right, #66BB6A -40px, #66BB6A 5px, transparent 5px, transparent 100%);
9539 }
9540 @media print {
9541 .edit_mode div.cell.selected {
9542 border-color: transparent;
9543 }
9544 }
9545 .prompt {
9546 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
9547 min-width: 14ex;
9548 /* This padding is tuned to match the padding on the CodeMirror editor. */
9549 padding: 0.4em;
9550 margin: 0px;
9551 font-family: monospace;
9552 text-align: right;
9553 /* This has to match that of the the CodeMirror class line-height below */
9554 line-height: 1.21429em;
9555 /* Don't highlight prompt number selection */
9556 -webkit-touch-callout: none;
9557 -webkit-user-select: none;
9558 -khtml-user-select: none;
9559 -moz-user-select: none;
9560 -ms-user-select: none;
9561 user-select: none;
9562 /* Use default cursor */
9563 cursor: default;
9564 }
9565 @media (max-width: 540px) {
9566 .prompt {
9567 text-align: left;
9568 }
9569 }
9570 div.inner_cell {
9571 min-width: 0;
9572 /* Old browsers */
9573 display: -webkit-box;
9574 -webkit-box-orient: vertical;
9575 -webkit-box-align: stretch;
9576 display: -moz-box;
9577 -moz-box-orient: vertical;
9578 -moz-box-align: stretch;
9579 display: box;
9580 box-orient: vertical;
9581 box-align: stretch;
9582 /* Modern browsers */
9583 display: flex;
9584 flex-direction: column;
9585 align-items: stretch;
9586 /* Old browsers */
9587 -webkit-box-flex: 1;
9588 -moz-box-flex: 1;
9589 box-flex: 1;
9590 /* Modern browsers */
9591 flex: 1;
9592 }
9593 /* input_area and input_prompt must match in top border and margin for alignment */
9594 div.input_area {
9595 border: 1px solid #cfcfcf;
9596 border-radius: 2px;
9597 background: #f7f7f7;
9598 line-height: 1.21429em;
9599 }
9600 /* This is needed so that empty prompt areas can collapse to zero height when there
9601 is no content in the output_subarea and the prompt. The main purpose of this is
9602 to make sure that empty JavaScript output_subareas have no height. */
9603 div.prompt:empty {
9604 padding-top: 0;
9605 padding-bottom: 0;
9606 }
9607 div.unrecognized_cell {
9608 padding: 5px 5px 5px 0px;
9609 /* Old browsers */
9610 display: -webkit-box;
9611 -webkit-box-orient: horizontal;
9612 -webkit-box-align: stretch;
9613 display: -moz-box;
9614 -moz-box-orient: horizontal;
9615 -moz-box-align: stretch;
9616 display: box;
9617 box-orient: horizontal;
9618 box-align: stretch;
9619 /* Modern browsers */
9620 display: flex;
9621 flex-direction: row;
9622 align-items: stretch;
9623 }
9624 div.unrecognized_cell .inner_cell {
9625 border-radius: 2px;
9626 padding: 5px;
9627 font-weight: bold;
9628 color: red;
9629 border: 1px solid #cfcfcf;
9630 background: #eaeaea;
9631 }
9632 div.unrecognized_cell .inner_cell a {
9633 color: inherit;
9634 text-decoration: none;
9635 }
9636 div.unrecognized_cell .inner_cell a:hover {
9637 color: inherit;
9638 text-decoration: none;
9639 }
9640 @media (max-width: 540px) {
9641 div.unrecognized_cell > div.prompt {
9642 display: none;
9643 }
9644 }
9645 div.code_cell {
9646 /* avoid page breaking on code cells when printing */
9647 }
9648 @media print {
9649 div.code_cell {
9650 page-break-inside: avoid;
9651 }
9652 }
9653 /* any special styling for code cells that are currently running goes here */
9654 div.input {
9655 page-break-inside: avoid;
9656 /* Old browsers */
9657 display: -webkit-box;
9658 -webkit-box-orient: horizontal;
9659 -webkit-box-align: stretch;
9660 display: -moz-box;
9661 -moz-box-orient: horizontal;
9662 -moz-box-align: stretch;
9663 display: box;
9664 box-orient: horizontal;
9665 box-align: stretch;
9666 /* Modern browsers */
9667 display: flex;
9668 flex-direction: row;
9669 align-items: stretch;
9670 }
9671 @media (max-width: 540px) {
9672 div.input {
9673 /* Old browsers */
9674 display: -webkit-box;
9675 -webkit-box-orient: vertical;
9676 -webkit-box-align: stretch;
9677 display: -moz-box;
9678 -moz-box-orient: vertical;
9679 -moz-box-align: stretch;
9680 display: box;
9681 box-orient: vertical;
9682 box-align: stretch;
9683 /* Modern browsers */
9684 display: flex;
9685 flex-direction: column;
9686 align-items: stretch;
9687 }
9688 }
9689 /* input_area and input_prompt must match in top border and margin for alignment */
9690 div.input_prompt {
9691 color: #303F9F;
9692 border-top: 1px solid transparent;
9693 }
9694 div.input_area > div.highlight {
9695 margin: 0.4em;
9696 border: none;
9697 padding: 0px;
9698 background-color: transparent;
9699 }
9700 div.input_area > div.highlight > pre {
9701 margin: 0px;
9702 border: none;
9703 padding: 0px;
9704 background-color: transparent;
9705 }
9706 /* The following gets added to the <head> if it is detected that the user has a
9707 * monospace font with inconsistent normal/bold/italic height. See
9708 * notebookmain.js. Such fonts will have keywords vertically offset with
9709 * respect to the rest of the text. The user should select a better font.
9710 * See: https://github.com/ipython/ipython/issues/1503
9711 *
9712 * .CodeMirror span {
9713 * vertical-align: bottom;
9714 * }
9715 */
9716 .CodeMirror {
9717 line-height: 1.21429em;
9718 /* Changed from 1em to our global default */
9719 font-size: 14px;
9720 height: auto;
9721 /* Changed to auto to autogrow */
9722 background: none;
9723 /* Changed from white to allow our bg to show through */
9724 }
9725 .CodeMirror-scroll {
9726 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
9727 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
9728 overflow-y: hidden;
9729 overflow-x: auto;
9730 }
9731 .CodeMirror-lines {
9732 /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
9733 /* we have set a different line-height and want this to scale with that. */
9734 padding: 0.4em;
9735 }
9736 .CodeMirror-linenumber {
9737 padding: 0 8px 0 4px;
9738 }
9739 .CodeMirror-gutters {
9740 border-bottom-left-radius: 2px;
9741 border-top-left-radius: 2px;
9742 }
9743 .CodeMirror pre {
9744 /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */
9745 /* .CodeMirror-lines */
9746 padding: 0;
9747 border: 0;
9748 border-radius: 0;
9749 }
9750 /*
9751
9752 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
9753 Adapted from GitHub theme
9754
9755 */
9756 .highlight-base {
9757 color: #000;
9758 }
9759 .highlight-variable {
9760 color: #000;
9761 }
9762 .highlight-variable-2 {
9763 color: #1a1a1a;
9764 }
9765 .highlight-variable-3 {
9766 color: #333333;
9767 }
9768 .highlight-string {
9769 color: #BA2121;
9770 }
9771 .highlight-comment {
9772 color: #408080;
9773 font-style: italic;
9774 }
9775 .highlight-number {
9776 color: #080;
9777 }
9778 .highlight-atom {
9779 color: #88F;
9780 }
9781 .highlight-keyword {
9782 color: #008000;
9783 font-weight: bold;
9784 }
9785 .highlight-builtin {
9786 color: #008000;
9787 }
9788 .highlight-error {
9789 color: #f00;
9790 }
9791 .highlight-operator {
9792 color: #AA22FF;
9793 font-weight: bold;
9794 }
9795 .highlight-meta {
9796 color: #AA22FF;
9797 }
9798 /* previously not defined, copying from default codemirror */
9799 .highlight-def {
9800 color: #00f;
9801 }
9802 .highlight-string-2 {
9803 color: #f50;
9804 }
9805 .highlight-qualifier {
9806 color: #555;
9807 }
9808 .highlight-bracket {
9809 color: #997;
9810 }
9811 .highlight-tag {
9812 color: #170;
9813 }
9814 .highlight-attribute {
9815 color: #00c;
9816 }
9817 .highlight-header {
9818 color: blue;
9819 }
9820 .highlight-quote {
9821 color: #090;
9822 }
9823 .highlight-link {
9824 color: #00c;
9825 }
9826 /* apply the same style to codemirror */
9827 .cm-s-ipython span.cm-keyword {
9828 color: #008000;
9829 font-weight: bold;
9830 }
9831 .cm-s-ipython span.cm-atom {
9832 color: #88F;
9833 }
9834 .cm-s-ipython span.cm-number {
9835 color: #080;
9836 }
9837 .cm-s-ipython span.cm-def {
9838 color: #00f;
9839 }
9840 .cm-s-ipython span.cm-variable {
9841 color: #000;
9842 }
9843 .cm-s-ipython span.cm-operator {
9844 color: #AA22FF;
9845 font-weight: bold;
9846 }
9847 .cm-s-ipython span.cm-variable-2 {
9848 color: #1a1a1a;
9849 }
9850 .cm-s-ipython span.cm-variable-3 {
9851 color: #333333;
9852 }
9853 .cm-s-ipython span.cm-comment {
9854 color: #408080;
9855 font-style: italic;
9856 }
9857 .cm-s-ipython span.cm-string {
9858 color: #BA2121;
9859 }
9860 .cm-s-ipython span.cm-string-2 {
9861 color: #f50;
9862 }
9863 .cm-s-ipython span.cm-meta {
9864 color: #AA22FF;
9865 }
9866 .cm-s-ipython span.cm-qualifier {
9867 color: #555;
9868 }
9869 .cm-s-ipython span.cm-builtin {
9870 color: #008000;
9871 }
9872 .cm-s-ipython span.cm-bracket {
9873 color: #997;
9874 }
9875 .cm-s-ipython span.cm-tag {
9876 color: #170;
9877 }
9878 .cm-s-ipython span.cm-attribute {
9879 color: #00c;
9880 }
9881 .cm-s-ipython span.cm-header {
9882 color: blue;
9883 }
9884 .cm-s-ipython span.cm-quote {
9885 color: #090;
9886 }
9887 .cm-s-ipython span.cm-link {
9888 color: #00c;
9889 }
9890 .cm-s-ipython span.cm-error {
9891 color: #f00;
9892 }
9893 .cm-s-ipython span.cm-tab {
9894 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
9895 background-position: right;
9896 background-repeat: no-repeat;
9897 }
9898 div.output_wrapper {
9899 /* this position must be relative to enable descendents to be absolute within it */
9900 position: relative;
9901 /* Old browsers */
9902 display: -webkit-box;
9903 -webkit-box-orient: vertical;
9904 -webkit-box-align: stretch;
9905 display: -moz-box;
9906 -moz-box-orient: vertical;
9907 -moz-box-align: stretch;
9908 display: box;
9909 box-orient: vertical;
9910 box-align: stretch;
9911 /* Modern browsers */
9912 display: flex;
9913 flex-direction: column;
9914 align-items: stretch;
9915 z-index: 1;
9916 }
9917 /* class for the output area when it should be height-limited */
9918 div.output_scroll {
9919 /* ideally, this would be max-height, but FF barfs all over that */
9920 height: 24em;
9921 /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
9922 width: 100%;
9923 overflow: auto;
9924 border-radius: 2px;
9925 -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
9926 box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
9927 display: block;
9928 }
9929 /* output div while it is collapsed */
9930 div.output_collapsed {
9931 margin: 0px;
9932 padding: 0px;
9933 /* Old browsers */
9934 display: -webkit-box;
9935 -webkit-box-orient: vertical;
9936 -webkit-box-align: stretch;
9937 display: -moz-box;
9938 -moz-box-orient: vertical;
9939 -moz-box-align: stretch;
9940 display: box;
9941 box-orient: vertical;
9942 box-align: stretch;
9943 /* Modern browsers */
9944 display: flex;
9945 flex-direction: column;
9946 align-items: stretch;
9947 }
9948 div.out_prompt_overlay {
9949 height: 100%;
9950 padding: 0px 0.4em;
9951 position: absolute;
9952 border-radius: 2px;
9953 }
9954 div.out_prompt_overlay:hover {
9955 /* use inner shadow to get border that is computed the same on WebKit/FF */
9956 -webkit-box-shadow: inset 0 0 1px #000;
9957 box-shadow: inset 0 0 1px #000;
9958 background: rgba(240, 240, 240, 0.5);
9959 }
9960 div.output_prompt {
9961 color: #D84315;
9962 }
9963 /* This class is the outer container of all output sections. */
9964 div.output_area {
9965 padding: 0px;
9966 page-break-inside: avoid;
9967 /* Old browsers */
9968 display: -webkit-box;
9969 -webkit-box-orient: horizontal;
9970 -webkit-box-align: stretch;
9971 display: -moz-box;
9972 -moz-box-orient: horizontal;
9973 -moz-box-align: stretch;
9974 display: box;
9975 box-orient: horizontal;
9976 box-align: stretch;
9977 /* Modern browsers */
9978 display: flex;
9979 flex-direction: row;
9980 align-items: stretch;
9981 }
9982 div.output_area .MathJax_Display {
9983 text-align: left !important;
9984 }
9985 div.output_area .rendered_html table {
9986 margin-left: 0;
9987 margin-right: 0;
9988 }
9989 div.output_area .rendered_html img {
9990 margin-left: 0;
9991 margin-right: 0;
9992 }
9993 div.output_area img,
9994 div.output_area svg {
9995 max-width: 100%;
9996 height: auto;
9997 }
9998 div.output_area img.unconfined,
9999 div.output_area svg.unconfined {
10000 max-width: none;
10001 }
10002 /* This is needed to protect the pre formating from global settings such
10003 as that of bootstrap */
10004 .output {
10005 /* Old browsers */
10006 display: -webkit-box;
10007 -webkit-box-orient: vertical;
10008 -webkit-box-align: stretch;
10009 display: -moz-box;
10010 -moz-box-orient: vertical;
10011 -moz-box-align: stretch;
10012 display: box;
10013 box-orient: vertical;
10014 box-align: stretch;
10015 /* Modern browsers */
10016 display: flex;
10017 flex-direction: column;
10018 align-items: stretch;
10019 }
10020 @media (max-width: 540px) {
10021 div.output_area {
10022 /* Old browsers */
10023 display: -webkit-box;
10024 -webkit-box-orient: vertical;
10025 -webkit-box-align: stretch;
10026 display: -moz-box;
10027 -moz-box-orient: vertical;
10028 -moz-box-align: stretch;
10029 display: box;
10030 box-orient: vertical;
10031 box-align: stretch;
10032 /* Modern browsers */
10033 display: flex;
10034 flex-direction: column;
10035 align-items: stretch;
10036 }
10037 }
10038 div.output_area pre {
10039 margin: 0;
10040 padding: 0;
10041 border: 0;
10042 vertical-align: baseline;
10043 color: black;
10044 background-color: transparent;
10045 border-radius: 0;
10046 }
10047 /* This class is for the output subarea inside the output_area and after
10048 the prompt div. */
10049 div.output_subarea {
10050 overflow-x: auto;
10051 padding: 0.4em;
10052 /* Old browsers */
10053 -webkit-box-flex: 1;
10054 -moz-box-flex: 1;
10055 box-flex: 1;
10056 /* Modern browsers */
10057 flex: 1;
10058 max-width: calc(100% - 14ex);
10059 }
10060 div.output_scroll div.output_subarea {
10061 overflow-x: visible;
10062 }
10063 /* The rest of the output_* classes are for special styling of the different
10064 output types */
10065 /* all text output has this class: */
10066 div.output_text {
10067 text-align: left;
10068 color: #000;
10069 /* This has to match that of the the CodeMirror class line-height below */
10070 line-height: 1.21429em;
10071 }
10072 /* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
10073 div.output_stderr {
10074 background: #fdd;
10075 /* very light red background for stderr */
10076 }
10077 div.output_latex {
10078 text-align: left;
10079 }
10080 /* Empty output_javascript divs should have no height */
10081 div.output_javascript:empty {
10082 padding: 0;
10083 }
10084 .js-error {
10085 color: darkred;
10086 }
10087 /* raw_input styles */
10088 div.raw_input_container {
10089 line-height: 1.21429em;
10090 padding-top: 5px;
10091 }
10092 pre.raw_input_prompt {
10093 /* nothing needed here. */
10094 }
10095 input.raw_input {
10096 font-family: monospace;
10097 font-size: inherit;
10098 color: inherit;
10099 width: auto;
10100 /* make sure input baseline aligns with prompt */
10101 vertical-align: baseline;
10102 /* padding + margin = 0.5em between prompt and cursor */
10103 padding: 0em 0.25em;
10104 margin: 0em 0.25em;
10105 }
10106 input.raw_input:focus {
10107 box-shadow: none;
10108 }
10109 p.p-space {
10110 margin-bottom: 10px;
10111 }
10112 div.output_unrecognized {
10113 padding: 5px;
10114 font-weight: bold;
10115 color: red;
10116 }
10117 div.output_unrecognized a {
10118 color: inherit;
10119 text-decoration: none;
10120 }
10121 div.output_unrecognized a:hover {
10122 color: inherit;
10123 text-decoration: none;
10124 }
10125 .rendered_html {
10126 color: #000;
10127 /* any extras will just be numbers: */
10128 }
10129 .rendered_html em {
10130 font-style: italic;
10131 }
10132 .rendered_html strong {
10133 font-weight: bold;
10134 }
10135 .rendered_html u {
10136 text-decoration: underline;
10137 }
10138 .rendered_html :link {
10139 text-decoration: underline;
10140 }
10141 .rendered_html :visited {
10142 text-decoration: underline;
10143 }
10144 .rendered_html h1 {
10145 font-size: 185.7%;
10146 margin: 1.08em 0 0 0;
10147 font-weight: bold;
10148 line-height: 1.0;
10149 }
10150 .rendered_html h2 {
10151 font-size: 157.1%;
10152 margin: 1.27em 0 0 0;
10153 font-weight: bold;
10154 line-height: 1.0;
10155 }
10156 .rendered_html h3 {
10157 font-size: 128.6%;
10158 margin: 1.55em 0 0 0;
10159 font-weight: bold;
10160 line-height: 1.0;
10161 }
10162 .rendered_html h4 {
10163 font-size: 100%;
10164 margin: 2em 0 0 0;
10165 font-weight: bold;
10166 line-height: 1.0;
10167 }
10168 .rendered_html h5 {
10169 font-size: 100%;
10170 margin: 2em 0 0 0;
10171 font-weight: bold;
10172 line-height: 1.0;
10173 font-style: italic;
10174 }
10175 .rendered_html h6 {
10176 font-size: 100%;
10177 margin: 2em 0 0 0;
10178 font-weight: bold;
10179 line-height: 1.0;
10180 font-style: italic;
10181 }
10182 .rendered_html h1:first-child {
10183 margin-top: 0.538em;
10184 }
10185 .rendered_html h2:first-child {
10186 margin-top: 0.636em;
10187 }
10188 .rendered_html h3:first-child {
10189 margin-top: 0.777em;
10190 }
10191 .rendered_html h4:first-child {
10192 margin-top: 1em;
10193 }
10194 .rendered_html h5:first-child {
10195 margin-top: 1em;
10196 }
10197 .rendered_html h6:first-child {
10198 margin-top: 1em;
10199 }
10200 .rendered_html ul {
10201 list-style: disc;
10202 margin: 0em 2em;
10203 padding-left: 0px;
10204 }
10205 .rendered_html ul ul {
10206 list-style: square;
10207 margin: 0em 2em;
10208 }
10209 .rendered_html ul ul ul {
10210 list-style: circle;
10211 margin: 0em 2em;
10212 }
10213 .rendered_html ol {
10214 list-style: decimal;
10215 margin: 0em 2em;
10216 padding-left: 0px;
10217 }
10218 .rendered_html ol ol {
10219 list-style: upper-alpha;
10220 margin: 0em 2em;
10221 }
10222 .rendered_html ol ol ol {
10223 list-style: lower-alpha;
10224 margin: 0em 2em;
10225 }
10226 .rendered_html ol ol ol ol {
10227 list-style: lower-roman;
10228 margin: 0em 2em;
10229 }
10230 .rendered_html ol ol ol ol ol {
10231 list-style: decimal;
10232 margin: 0em 2em;
10233 }
10234 .rendered_html * + ul {
10235 margin-top: 1em;
10236 }
10237 .rendered_html * + ol {
10238 margin-top: 1em;
10239 }
10240 .rendered_html hr {
10241 color: black;
10242 background-color: black;
10243 }
10244 .rendered_html pre {
10245 margin: 1em 2em;
10246 }
10247 .rendered_html pre,
10248 .rendered_html code {
10249 border: 0;
10250 background-color: #fff;
10251 color: #000;
10252 font-size: 100%;
10253 padding: 0px;
10254 }
10255 .rendered_html blockquote {
10256 margin: 1em 2em;
10257 }
10258 .rendered_html table {
10259 margin-left: auto;
10260 margin-right: auto;
10261 border: 1px solid black;
10262 border-collapse: collapse;
10263 }
10264 .rendered_html tr,
10265 .rendered_html th,
10266 .rendered_html td {
10267 border: 1px solid black;
10268 border-collapse: collapse;
10269 margin: 1em 2em;
10270 }
10271 .rendered_html td,
10272 .rendered_html th {
10273 text-align: left;
10274 vertical-align: middle;
10275 padding: 4px;
10276 }
10277 .rendered_html th {
10278 font-weight: bold;
10279 }
10280 .rendered_html * + table {
10281 margin-top: 1em;
10282 }
10283 .rendered_html p {
10284 text-align: left;
10285 }
10286 .rendered_html * + p {
10287 margin-top: 1em;
10288 }
10289 .rendered_html img {
10290 display: block;
10291 margin-left: auto;
10292 margin-right: auto;
10293 }
10294 .rendered_html * + img {
10295 margin-top: 1em;
10296 }
10297 .rendered_html img,
10298 .rendered_html svg {
10299 max-width: 100%;
10300 height: auto;
10301 }
10302 .rendered_html img.unconfined,
10303 .rendered_html svg.unconfined {
10304 max-width: none;
10305 }
10306 div.text_cell {
10307 /* Old browsers */
10308 display: -webkit-box;
10309 -webkit-box-orient: horizontal;
10310 -webkit-box-align: stretch;
10311 display: -moz-box;
10312 -moz-box-orient: horizontal;
10313 -moz-box-align: stretch;
10314 display: box;
10315 box-orient: horizontal;
10316 box-align: stretch;
10317 /* Modern browsers */
10318 display: flex;
10319 flex-direction: row;
10320 align-items: stretch;
10321 }
10322 @media (max-width: 540px) {
10323 div.text_cell > div.prompt {
10324 display: none;
10325 }
10326 }
10327 div.text_cell_render {
10328 /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
10329 outline: none;
10330 resize: none;
10331 width: inherit;
10332 border-style: none;
10333 padding: 0.5em 0.5em 0.5em 0.4em;
10334 color: #000;
10335 box-sizing: border-box;
10336 -moz-box-sizing: border-box;
10337 -webkit-box-sizing: border-box;
10338 }
10339 a.anchor-link:link {
10340 text-decoration: none;
10341 padding: 0px 20px;
10342 visibility: hidden;
10343 }
10344 h1:hover .anchor-link,
10345 h2:hover .anchor-link,
10346 h3:hover .anchor-link,
10347 h4:hover .anchor-link,
10348 h5:hover .anchor-link,
10349 h6:hover .anchor-link {
10350 visibility: visible;
10351 }
10352 .text_cell.rendered .input_area {
10353 display: none;
10354 }
10355 .text_cell.rendered .rendered_html {
10356 overflow-x: auto;
10357 overflow-y: hidden;
10358 }
10359 .text_cell.unrendered .text_cell_render {
10360 display: none;
10361 }
10362 .cm-header-1,
10363 .cm-header-2,
10364 .cm-header-3,
10365 .cm-header-4,
10366 .cm-header-5,
10367 .cm-header-6 {
10368 font-weight: bold;
10369 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
10370 }
10371 .cm-header-1 {
10372 font-size: 185.7%;
10373 }
10374 .cm-header-2 {
10375 font-size: 157.1%;
10376 }
10377 .cm-header-3 {
10378 font-size: 128.6%;
10379 }
10380 .cm-header-4 {
10381 font-size: 110%;
10382 }
10383 .cm-header-5 {
10384 font-size: 100%;
10385 font-style: italic;
10386 }
10387 .cm-header-6 {
10388 font-size: 100%;
10389 font-style: italic;
10390 }
10391 /*!
10392 *
10393 * IPython notebook webapp
10394 *
10395 */
10396 @media (max-width: 767px) {
10397 .notebook_app {
10398 padding-left: 0px;
10399 padding-right: 0px;
10400 }
10401 }
10402 #ipython-main-app {
10403 box-sizing: border-box;
10404 -moz-box-sizing: border-box;
10405 -webkit-box-sizing: border-box;
10406 height: 100%;
10407 }
10408 div#notebook_panel {
10409 margin: 0px;
10410 padding: 0px;
10411 box-sizing: border-box;
10412 -moz-box-sizing: border-box;
10413 -webkit-box-sizing: border-box;
10414 height: 100%;
10415 }
10416 div#notebook {
10417 font-size: 14px;
10418 line-height: 20px;
10419 overflow-y: hidden;
10420 overflow-x: auto;
10421 width: 100%;
10422 /* This spaces the page away from the edge of the notebook area */
10423 padding-top: 20px;
10424 margin: 0px;
10425 outline: none;
10426 box-sizing: border-box;
10427 -moz-box-sizing: border-box;
10428 -webkit-box-sizing: border-box;
10429 min-height: 100%;
10430 }
10431 @media not print {
10432 #notebook-container {
10433 padding: 15px;
10434 background-color: #fff;
10435 min-height: 0;
10436 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10437 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10438 }
10439 }
10440 @media print {
10441 #notebook-container {
10442 width: 100%;
10443 }
10444 }
10445 div.ui-widget-content {
10446 border: 1px solid #ababab;
10447 outline: none;
10448 }
10449 pre.dialog {
10450 background-color: #f7f7f7;
10451 border: 1px solid #ddd;
10452 border-radius: 2px;
10453 padding: 0.4em;
10454 padding-left: 2em;
10455 }
10456 p.dialog {
10457 padding: 0.2em;
10458 }
10459 /* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems
10460 to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do.
10461 */
10462 pre,
10463 code,
10464 kbd,
10465 samp {
10466 white-space: pre-wrap;
10467 }
10468 #fonttest {
10469 font-family: monospace;
10470 }
10471 p {
10472 margin-bottom: 0;
10473 }
10474 .end_space {
10475 min-height: 100px;
10476 transition: height .2s ease;
10477 }
10478 .notebook_app > #header {
10479 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10480 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
10481 }
10482 @media not print {
10483 .notebook_app {
10484 background-color: #EEE;
10485 }
10486 }
10487 kbd {
10488 border-style: solid;
10489 border-width: 1px;
10490 box-shadow: none;
10491 margin: 2px;
10492 padding-left: 2px;
10493 padding-right: 2px;
10494 padding-top: 1px;
10495 padding-bottom: 1px;
10496 }
10497 /* CSS for the cell toolbar */
10498 .celltoolbar {
10499 border: thin solid #CFCFCF;
10500 border-bottom: none;
10501 background: #EEE;
10502 border-radius: 2px 2px 0px 0px;
10503 width: 100%;
10504 height: 29px;
10505 padding-right: 4px;
10506 /* Old browsers */
10507 display: -webkit-box;
10508 -webkit-box-orient: horizontal;
10509 -webkit-box-align: stretch;
10510 display: -moz-box;
10511 -moz-box-orient: horizontal;
10512 -moz-box-align: stretch;
10513 display: box;
10514 box-orient: horizontal;
10515 box-align: stretch;
10516 /* Modern browsers */
10517 display: flex;
10518 flex-direction: row;
10519 align-items: stretch;
10520 /* Old browsers */
10521 -webkit-box-pack: end;
10522 -moz-box-pack: end;
10523 box-pack: end;
10524 /* Modern browsers */
10525 justify-content: flex-end;
10526 display: -webkit-flex;
10527 }
10528 @media print {
10529 .celltoolbar {
10530 display: none;
10531 }
10532 }
10533 .ctb_hideshow {
10534 display: none;
10535 vertical-align: bottom;
10536 }
10537 /* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
10538 Cell toolbars are only shown when the ctb_global_show class is also set.
10539 */
10540 .ctb_global_show .ctb_show.ctb_hideshow {
10541 display: block;
10542 }
10543 .ctb_global_show .ctb_show + .input_area,
10544 .ctb_global_show .ctb_show + div.text_cell_input,
10545 .ctb_global_show .ctb_show ~ div.text_cell_render {
10546 border-top-right-radius: 0px;
10547 border-top-left-radius: 0px;
10548 }
10549 .ctb_global_show .ctb_show ~ div.text_cell_render {
10550 border: 1px solid #cfcfcf;
10551 }
10552 .celltoolbar {
10553 font-size: 87%;
10554 padding-top: 3px;
10555 }
10556 .celltoolbar select {
10557 display: block;
10558 width: 100%;
10559 height: 32px;
10560 padding: 6px 12px;
10561 font-size: 13px;
10562 line-height: 1.42857143;
10563 color: #555555;
10564 background-color: #fff;
10565 background-image: none;
10566 border: 1px solid #ccc;
10567 border-radius: 2px;
10568 -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
10569 box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
10570 -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
10571 -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
10572 transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
10573 height: 30px;
10574 padding: 5px 10px;
10575 font-size: 12px;
10576 line-height: 1.5;
10577 border-radius: 1px;
10578 width: inherit;
10579 font-size: inherit;
10580 height: 22px;
10581 padding: 0px;
10582 display: inline-block;
10583 }
10584 .celltoolbar select:focus {
10585 border-color: #66afe9;
10586 outline: 0;
10587 -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
10588 box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
10589 }
10590 .celltoolbar select::-moz-placeholder {
10591 color: #999;
10592 opacity: 1;
10593 }
10594 .celltoolbar select:-ms-input-placeholder {
10595 color: #999;
10596 }
10597 .celltoolbar select::-webkit-input-placeholder {
10598 color: #999;
10599 }
10600 .celltoolbar select::-ms-expand {
10601 border: 0;
10602 background-color: transparent;
10603 }
10604 .celltoolbar select[disabled],
10605 .celltoolbar select[readonly],
10606 fieldset[disabled] .celltoolbar select {
10607 background-color: #eeeeee;
10608 opacity: 1;
10609 }
10610 .celltoolbar select[disabled],
10611 fieldset[disabled] .celltoolbar select {
10612 cursor: not-allowed;
10613 }
10614 textarea.celltoolbar select {
10615 height: auto;
10616 }
10617 select.celltoolbar select {
10618 height: 30px;
10619 line-height: 30px;
10620 }
10621 textarea.celltoolbar select,
10622 select[multiple].celltoolbar select {
10623 height: auto;
10624 }
10625 .celltoolbar label {
10626 margin-left: 5px;
10627 margin-right: 5px;
10628 }
10629 .completions {
10630 position: absolute;
10631 z-index: 110;
10632 overflow: hidden;
10633 border: 1px solid #ababab;
10634 border-radius: 2px;
10635 -webkit-box-shadow: 0px 6px 10px -1px #adadad;
10636 box-shadow: 0px 6px 10px -1px #adadad;
10637 line-height: 1;
10638 }
10639 .completions select {
10640 background: white;
10641 outline: none;
10642 border: none;
10643 padding: 0px;
10644 margin: 0px;
10645 overflow: auto;
10646 font-family: monospace;
10647 font-size: 110%;
10648 color: #000;
10649 width: auto;
10650 }
10651 .completions select option.context {
10652 color: #286090;
10653 }
10654 #kernel_logo_widget {
10655 float: right !important;
10656 float: right;
10657 }
10658 #kernel_logo_widget .current_kernel_logo {
10659 display: none;
10660 margin-top: -1px;
10661 margin-bottom: -1px;
10662 width: 32px;
10663 height: 32px;
10664 }
10665 #menubar {
10666 box-sizing: border-box;
10667 -moz-box-sizing: border-box;
10668 -webkit-box-sizing: border-box;
10669 margin-top: 1px;
10670 }
10671 #menubar .navbar {
10672 border-top: 1px;
10673 border-radius: 0px 0px 2px 2px;
10674 margin-bottom: 0px;
10675 }
10676 #menubar .navbar-toggle {
10677 float: left;
10678 padding-top: 7px;
10679 padding-bottom: 7px;
10680 border: none;
10681 }
10682 #menubar .navbar-collapse {
10683 clear: left;
10684 }
10685 .nav-wrapper {
10686 border-bottom: 1px solid #e7e7e7;
10687 }
10688 i.menu-icon {
10689 padding-top: 4px;
10690 }
10691 ul#help_menu li a {
10692 overflow: hidden;
10693 padding-right: 2.2em;
10694 }
10695 ul#help_menu li a i {
10696 margin-right: -1.2em;
10697 }
10698 .dropdown-submenu {
10699 position: relative;
10700 }
10701 .dropdown-submenu > .dropdown-menu {
10702 top: 0;
10703 left: 100%;
10704 margin-top: -6px;
10705 margin-left: -1px;
10706 }
10707 .dropdown-submenu:hover > .dropdown-menu {
10708 display: block;
10709 }
10710 .dropdown-submenu > a:after {
10711 display: inline-block;
10712 font: normal normal normal 14px/1 FontAwesome;
10713 font-size: inherit;
10714 text-rendering: auto;
10715 -webkit-font-smoothing: antialiased;
10716 -moz-osx-font-smoothing: grayscale;
10717 display: block;
10718 content: "\f0da";
10719 float: right;
10720 color: #333333;
10721 margin-top: 2px;
10722 margin-right: -10px;
10723 }
10724 .dropdown-submenu > a:after.pull-left {
10725 margin-right: .3em;
10726 }
10727 .dropdown-submenu > a:after.pull-right {
10728 margin-left: .3em;
10729 }
10730 .dropdown-submenu:hover > a:after {
10731 color: #262626;
10732 }
10733 .dropdown-submenu.pull-left {
10734 float: none;
10735 }
10736 .dropdown-submenu.pull-left > .dropdown-menu {
10737 left: -100%;
10738 margin-left: 10px;
10739 }
10740 #notification_area {
10741 float: right !important;
10742 float: right;
10743 z-index: 10;
10744 }
10745 .indicator_area {
10746 float: right !important;
10747 float: right;
10748 color: #777;
10749 margin-left: 5px;
10750 margin-right: 5px;
10751 width: 11px;
10752 z-index: 10;
10753 text-align: center;
10754 width: auto;
10755 }
10756 #kernel_indicator {
10757 float: right !important;
10758 float: right;
10759 color: #777;
10760 margin-left: 5px;
10761 margin-right: 5px;
10762 width: 11px;
10763 z-index: 10;
10764 text-align: center;
10765 width: auto;
10766 border-left: 1px solid;
10767 }
10768 #kernel_indicator .kernel_indicator_name {
10769 padding-left: 5px;
10770 padding-right: 5px;
10771 }
10772 #modal_indicator {
10773 float: right !important;
10774 float: right;
10775 color: #777;
10776 margin-left: 5px;
10777 margin-right: 5px;
10778 width: 11px;
10779 z-index: 10;
10780 text-align: center;
10781 width: auto;
10782 }
10783 #readonly-indicator {
10784 float: right !important;
10785 float: right;
10786 color: #777;
10787 margin-left: 5px;
10788 margin-right: 5px;
10789 width: 11px;
10790 z-index: 10;
10791 text-align: center;
10792 width: auto;
10793 margin-top: 2px;
10794 margin-bottom: 0px;
10795 margin-left: 0px;
10796 margin-right: 0px;
10797 display: none;
10798 }
10799 .modal_indicator:before {
10800 width: 1.28571429em;
10801 text-align: center;
10802 }
10803 .edit_mode .modal_indicator:before {
10804 display: inline-block;
10805 font: normal normal normal 14px/1 FontAwesome;
10806 font-size: inherit;
10807 text-rendering: auto;
10808 -webkit-font-smoothing: antialiased;
10809 -moz-osx-font-smoothing: grayscale;
10810 content: "\f040";
10811 }
10812 .edit_mode .modal_indicator:before.pull-left {
10813 margin-right: .3em;
10814 }
10815 .edit_mode .modal_indicator:before.pull-right {
10816 margin-left: .3em;
10817 }
10818 .command_mode .modal_indicator:before {
10819 display: inline-block;
10820 font: normal normal normal 14px/1 FontAwesome;
10821 font-size: inherit;
10822 text-rendering: auto;
10823 -webkit-font-smoothing: antialiased;
10824 -moz-osx-font-smoothing: grayscale;
10825 content: ' ';
10826 }
10827 .command_mode .modal_indicator:before.pull-left {
10828 margin-right: .3em;
10829 }
10830 .command_mode .modal_indicator:before.pull-right {
10831 margin-left: .3em;
10832 }
10833 .kernel_idle_icon:before {
10834 display: inline-block;
10835 font: normal normal normal 14px/1 FontAwesome;
10836 font-size: inherit;
10837 text-rendering: auto;
10838 -webkit-font-smoothing: antialiased;
10839 -moz-osx-font-smoothing: grayscale;
10840 content: "\f10c";
10841 }
10842 .kernel_idle_icon:before.pull-left {
10843 margin-right: .3em;
10844 }
10845 .kernel_idle_icon:before.pull-right {
10846 margin-left: .3em;
10847 }
10848 .kernel_busy_icon:before {
10849 display: inline-block;
10850 font: normal normal normal 14px/1 FontAwesome;
10851 font-size: inherit;
10852 text-rendering: auto;
10853 -webkit-font-smoothing: antialiased;
10854 -moz-osx-font-smoothing: grayscale;
10855 content: "\f111";
10856 }
10857 .kernel_busy_icon:before.pull-left {
10858 margin-right: .3em;
10859 }
10860 .kernel_busy_icon:before.pull-right {
10861 margin-left: .3em;
10862 }
10863 .kernel_dead_icon:before {
10864 display: inline-block;
10865 font: normal normal normal 14px/1 FontAwesome;
10866 font-size: inherit;
10867 text-rendering: auto;
10868 -webkit-font-smoothing: antialiased;
10869 -moz-osx-font-smoothing: grayscale;
10870 content: "\f1e2";
10871 }
10872 .kernel_dead_icon:before.pull-left {
10873 margin-right: .3em;
10874 }
10875 .kernel_dead_icon:before.pull-right {
10876 margin-left: .3em;
10877 }
10878 .kernel_disconnected_icon:before {
10879 display: inline-block;
10880 font: normal normal normal 14px/1 FontAwesome;
10881 font-size: inherit;
10882 text-rendering: auto;
10883 -webkit-font-smoothing: antialiased;
10884 -moz-osx-font-smoothing: grayscale;
10885 content: "\f127";
10886 }
10887 .kernel_disconnected_icon:before.pull-left {
10888 margin-right: .3em;
10889 }
10890 .kernel_disconnected_icon:before.pull-right {
10891 margin-left: .3em;
10892 }
10893 .notification_widget {
10894 color: #777;
10895 z-index: 10;
10896 background: rgba(240, 240, 240, 0.5);
10897 margin-right: 4px;
10898 color: #333;
10899 background-color: #fff;
10900 border-color: #ccc;
10901 }
10902 .notification_widget:focus,
10903 .notification_widget.focus {
10904 color: #333;
10905 background-color: #e6e6e6;
10906 border-color: #8c8c8c;
10907 }
10908 .notification_widget:hover {
10909 color: #333;
10910 background-color: #e6e6e6;
10911 border-color: #adadad;
10912 }
10913 .notification_widget:active,
10914 .notification_widget.active,
10915 .open > .dropdown-toggle.notification_widget {
10916 color: #333;
10917 background-color: #e6e6e6;
10918 border-color: #adadad;
10919 }
10920 .notification_widget:active:hover,
10921 .notification_widget.active:hover,
10922 .open > .dropdown-toggle.notification_widget:hover,
10923 .notification_widget:active:focus,
10924 .notification_widget.active:focus,
10925 .open > .dropdown-toggle.notification_widget:focus,
10926 .notification_widget:active.focus,
10927 .notification_widget.active.focus,
10928 .open > .dropdown-toggle.notification_widget.focus {
10929 color: #333;
10930 background-color: #d4d4d4;
10931 border-color: #8c8c8c;
10932 }
10933 .notification_widget:active,
10934 .notification_widget.active,
10935 .open > .dropdown-toggle.notification_widget {
10936 background-image: none;
10937 }
10938 .notification_widget.disabled:hover,
10939 .notification_widget[disabled]:hover,
10940 fieldset[disabled] .notification_widget:hover,
10941 .notification_widget.disabled:focus,
10942 .notification_widget[disabled]:focus,
10943 fieldset[disabled] .notification_widget:focus,
10944 .notification_widget.disabled.focus,
10945 .notification_widget[disabled].focus,
10946 fieldset[disabled] .notification_widget.focus {
10947 background-color: #fff;
10948 border-color: #ccc;
10949 }
10950 .notification_widget .badge {
10951 color: #fff;
10952 background-color: #333;
10953 }
10954 .notification_widget.warning {
10955 color: #fff;
10956 background-color: #f0ad4e;
10957 border-color: #eea236;
10958 }
10959 .notification_widget.warning:focus,
10960 .notification_widget.warning.focus {
10961 color: #fff;
10962 background-color: #ec971f;
10963 border-color: #985f0d;
10964 }
10965 .notification_widget.warning:hover {
10966 color: #fff;
10967 background-color: #ec971f;
10968 border-color: #d58512;
10969 }
10970 .notification_widget.warning:active,
10971 .notification_widget.warning.active,
10972 .open > .dropdown-toggle.notification_widget.warning {
10973 color: #fff;
10974 background-color: #ec971f;
10975 border-color: #d58512;
10976 }
10977 .notification_widget.warning:active:hover,
10978 .notification_widget.warning.active:hover,
10979 .open > .dropdown-toggle.notification_widget.warning:hover,
10980 .notification_widget.warning:active:focus,
10981 .notification_widget.warning.active:focus,
10982 .open > .dropdown-toggle.notification_widget.warning:focus,
10983 .notification_widget.warning:active.focus,
10984 .notification_widget.warning.active.focus,
10985 .open > .dropdown-toggle.notification_widget.warning.focus {
10986 color: #fff;
10987 background-color: #d58512;
10988 border-color: #985f0d;
10989 }
10990 .notification_widget.warning:active,
10991 .notification_widget.warning.active,
10992 .open > .dropdown-toggle.notification_widget.warning {
10993 background-image: none;
10994 }
10995 .notification_widget.warning.disabled:hover,
10996 .notification_widget.warning[disabled]:hover,
10997 fieldset[disabled] .notification_widget.warning:hover,
10998 .notification_widget.warning.disabled:focus,
10999 .notification_widget.warning[disabled]:focus,
11000 fieldset[disabled] .notification_widget.warning:focus,
11001 .notification_widget.warning.disabled.focus,
11002 .notification_widget.warning[disabled].focus,
11003 fieldset[disabled] .notification_widget.warning.focus {
11004 background-color: #f0ad4e;
11005 border-color: #eea236;
11006 }
11007 .notification_widget.warning .badge {
11008 color: #f0ad4e;
11009 background-color: #fff;
11010 }
11011 .notification_widget.success {
11012 color: #fff;
11013 background-color: #5cb85c;
11014 border-color: #4cae4c;
11015 }
11016 .notification_widget.success:focus,
11017 .notification_widget.success.focus {
11018 color: #fff;
11019 background-color: #449d44;
11020 border-color: #255625;
11021 }
11022 .notification_widget.success:hover {
11023 color: #fff;
11024 background-color: #449d44;
11025 border-color: #398439;
11026 }
11027 .notification_widget.success:active,
11028 .notification_widget.success.active,
11029 .open > .dropdown-toggle.notification_widget.success {
11030 color: #fff;
11031 background-color: #449d44;
11032 border-color: #398439;
11033 }
11034 .notification_widget.success:active:hover,
11035 .notification_widget.success.active:hover,
11036 .open > .dropdown-toggle.notification_widget.success:hover,
11037 .notification_widget.success:active:focus,
11038 .notification_widget.success.active:focus,
11039 .open > .dropdown-toggle.notification_widget.success:focus,
11040 .notification_widget.success:active.focus,
11041 .notification_widget.success.active.focus,
11042 .open > .dropdown-toggle.notification_widget.success.focus {
11043 color: #fff;
11044 background-color: #398439;
11045 border-color: #255625;
11046 }
11047 .notification_widget.success:active,
11048 .notification_widget.success.active,
11049 .open > .dropdown-toggle.notification_widget.success {
11050 background-image: none;
11051 }
11052 .notification_widget.success.disabled:hover,
11053 .notification_widget.success[disabled]:hover,
11054 fieldset[disabled] .notification_widget.success:hover,
11055 .notification_widget.success.disabled:focus,
11056 .notification_widget.success[disabled]:focus,
11057 fieldset[disabled] .notification_widget.success:focus,
11058 .notification_widget.success.disabled.focus,
11059 .notification_widget.success[disabled].focus,
11060 fieldset[disabled] .notification_widget.success.focus {
11061 background-color: #5cb85c;
11062 border-color: #4cae4c;
11063 }
11064 .notification_widget.success .badge {
11065 color: #5cb85c;
11066 background-color: #fff;
11067 }
11068 .notification_widget.info {
11069 color: #fff;
11070 background-color: #5bc0de;
11071 border-color: #46b8da;
11072 }
11073 .notification_widget.info:focus,
11074 .notification_widget.info.focus {
11075 color: #fff;
11076 background-color: #31b0d5;
11077 border-color: #1b6d85;
11078 }
11079 .notification_widget.info:hover {
11080 color: #fff;
11081 background-color: #31b0d5;
11082 border-color: #269abc;
11083 }
11084 .notification_widget.info:active,
11085 .notification_widget.info.active,
11086 .open > .dropdown-toggle.notification_widget.info {
11087 color: #fff;
11088 background-color: #31b0d5;
11089 border-color: #269abc;
11090 }
11091 .notification_widget.info:active:hover,
11092 .notification_widget.info.active:hover,
11093 .open > .dropdown-toggle.notification_widget.info:hover,
11094 .notification_widget.info:active:focus,
11095 .notification_widget.info.active:focus,
11096 .open > .dropdown-toggle.notification_widget.info:focus,
11097 .notification_widget.info:active.focus,
11098 .notification_widget.info.active.focus,
11099 .open > .dropdown-toggle.notification_widget.info.focus {
11100 color: #fff;
11101 background-color: #269abc;
11102 border-color: #1b6d85;
11103 }
11104 .notification_widget.info:active,
11105 .notification_widget.info.active,
11106 .open > .dropdown-toggle.notification_widget.info {
11107 background-image: none;
11108 }
11109 .notification_widget.info.disabled:hover,
11110 .notification_widget.info[disabled]:hover,
11111 fieldset[disabled] .notification_widget.info:hover,
11112 .notification_widget.info.disabled:focus,
11113 .notification_widget.info[disabled]:focus,
11114 fieldset[disabled] .notification_widget.info:focus,
11115 .notification_widget.info.disabled.focus,
11116 .notification_widget.info[disabled].focus,
11117 fieldset[disabled] .notification_widget.info.focus {
11118 background-color: #5bc0de;
11119 border-color: #46b8da;
11120 }
11121 .notification_widget.info .badge {
11122 color: #5bc0de;
11123 background-color: #fff;
11124 }
11125 .notification_widget.danger {
11126 color: #fff;
11127 background-color: #d9534f;
11128 border-color: #d43f3a;
11129 }
11130 .notification_widget.danger:focus,
11131 .notification_widget.danger.focus {
11132 color: #fff;
11133 background-color: #c9302c;
11134 border-color: #761c19;
11135 }
11136 .notification_widget.danger:hover {
11137 color: #fff;
11138 background-color: #c9302c;
11139 border-color: #ac2925;
11140 }
11141 .notification_widget.danger:active,
11142 .notification_widget.danger.active,
11143 .open > .dropdown-toggle.notification_widget.danger {
11144 color: #fff;
11145 background-color: #c9302c;
11146 border-color: #ac2925;
11147 }
11148 .notification_widget.danger:active:hover,
11149 .notification_widget.danger.active:hover,
11150 .open > .dropdown-toggle.notification_widget.danger:hover,
11151 .notification_widget.danger:active:focus,
11152 .notification_widget.danger.active:focus,
11153 .open > .dropdown-toggle.notification_widget.danger:focus,
11154 .notification_widget.danger:active.focus,
11155 .notification_widget.danger.active.focus,
11156 .open > .dropdown-toggle.notification_widget.danger.focus {
11157 color: #fff;
11158 background-color: #ac2925;
11159 border-color: #761c19;
11160 }
11161 .notification_widget.danger:active,
11162 .notification_widget.danger.active,
11163 .open > .dropdown-toggle.notification_widget.danger {
11164 background-image: none;
11165 }
11166 .notification_widget.danger.disabled:hover,
11167 .notification_widget.danger[disabled]:hover,
11168 fieldset[disabled] .notification_widget.danger:hover,
11169 .notification_widget.danger.disabled:focus,
11170 .notification_widget.danger[disabled]:focus,
11171 fieldset[disabled] .notification_widget.danger:focus,
11172 .notification_widget.danger.disabled.focus,
11173 .notification_widget.danger[disabled].focus,
11174 fieldset[disabled] .notification_widget.danger.focus {
11175 background-color: #d9534f;
11176 border-color: #d43f3a;
11177 }
11178 .notification_widget.danger .badge {
11179 color: #d9534f;
11180 background-color: #fff;
11181 }
11182 div#pager {
11183 background-color: #fff;
11184 font-size: 14px;
11185 line-height: 20px;
11186 overflow: hidden;
11187 display: none;
11188 position: fixed;
11189 bottom: 0px;
11190 width: 100%;
11191 max-height: 50%;
11192 padding-top: 8px;
11193 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11194 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11195 /* Display over codemirror */
11196 z-index: 100;
11197 /* Hack which prevents jquery ui resizable from changing top. */
11198 top: auto !important;
11199 }
11200 div#pager pre {
11201 line-height: 1.21429em;
11202 color: #000;
11203 background-color: #f7f7f7;
11204 padding: 0.4em;
11205 }
11206 div#pager #pager-button-area {
11207 position: absolute;
11208 top: 8px;
11209 right: 20px;
11210 }
11211 div#pager #pager-contents {
11212 position: relative;
11213 overflow: auto;
11214 width: 100%;
11215 height: 100%;
11216 }
11217 div#pager #pager-contents #pager-container {
11218 position: relative;
11219 padding: 15px 0px;
11220 box-sizing: border-box;
11221 -moz-box-sizing: border-box;
11222 -webkit-box-sizing: border-box;
11223 }
11224 div#pager .ui-resizable-handle {
11225 top: 0px;
11226 height: 8px;
11227 background: #f7f7f7;
11228 border-top: 1px solid #cfcfcf;
11229 border-bottom: 1px solid #cfcfcf;
11230 /* This injects handle bars (a short, wide = symbol) for
11231 the resize handle. */
11232 }
11233 div#pager .ui-resizable-handle::after {
11234 content: '';
11235 top: 2px;
11236 left: 50%;
11237 height: 3px;
11238 width: 30px;
11239 margin-left: -15px;
11240 position: absolute;
11241 border-top: 1px solid #cfcfcf;
11242 }
11243 .quickhelp {
11244 /* Old browsers */
11245 display: -webkit-box;
11246 -webkit-box-orient: horizontal;
11247 -webkit-box-align: stretch;
11248 display: -moz-box;
11249 -moz-box-orient: horizontal;
11250 -moz-box-align: stretch;
11251 display: box;
11252 box-orient: horizontal;
11253 box-align: stretch;
11254 /* Modern browsers */
11255 display: flex;
11256 flex-direction: row;
11257 align-items: stretch;
11258 line-height: 1.8em;
11259 }
11260 .shortcut_key {
11261 display: inline-block;
11262 width: 21ex;
11263 text-align: right;
11264 font-family: monospace;
11265 }
11266 .shortcut_descr {
11267 display: inline-block;
11268 /* Old browsers */
11269 -webkit-box-flex: 1;
11270 -moz-box-flex: 1;
11271 box-flex: 1;
11272 /* Modern browsers */
11273 flex: 1;
11274 }
11275 span.save_widget {
11276 margin-top: 6px;
11277 }
11278 span.save_widget span.filename {
11279 height: 1em;
11280 line-height: 1em;
11281 padding: 3px;
11282 margin-left: 16px;
11283 border: none;
11284 font-size: 146.5%;
11285 border-radius: 2px;
11286 }
11287 span.save_widget span.filename:hover {
11288 background-color: #e6e6e6;
11289 }
11290 span.checkpoint_status,
11291 span.autosave_status {
11292 font-size: small;
11293 }
11294 @media (max-width: 767px) {
11295 span.save_widget {
11296 font-size: small;
11297 }
11298 span.checkpoint_status,
11299 span.autosave_status {
11300 display: none;
11301 }
11302 }
11303 @media (min-width: 768px) and (max-width: 991px) {
11304 span.checkpoint_status {
11305 display: none;
11306 }
11307 span.autosave_status {
11308 font-size: x-small;
11309 }
11310 }
11311 .toolbar {
11312 padding: 0px;
11313 margin-left: -5px;
11314 margin-top: 2px;
11315 margin-bottom: 5px;
11316 box-sizing: border-box;
11317 -moz-box-sizing: border-box;
11318 -webkit-box-sizing: border-box;
11319 }
11320 .toolbar select,
11321 .toolbar label {
11322 width: auto;
11323 vertical-align: middle;
11324 margin-right: 2px;
11325 margin-bottom: 0px;
11326 display: inline;
11327 font-size: 92%;
11328 margin-left: 0.3em;
11329 margin-right: 0.3em;
11330 padding: 0px;
11331 padding-top: 3px;
11332 }
11333 .toolbar .btn {
11334 padding: 2px 8px;
11335 }
11336 .toolbar .btn-group {
11337 margin-top: 0px;
11338 margin-left: 5px;
11339 }
11340 #maintoolbar {
11341 margin-bottom: -3px;
11342 margin-top: -8px;
11343 border: 0px;
11344 min-height: 27px;
11345 margin-left: 0px;
11346 padding-top: 11px;
11347 padding-bottom: 3px;
11348 }
11349 #maintoolbar .navbar-text {
11350 float: none;
11351 vertical-align: middle;
11352 text-align: right;
11353 margin-left: 5px;
11354 margin-right: 0px;
11355 margin-top: 0px;
11356 }
11357 .select-xs {
11358 height: 24px;
11359 }
11360 .pulse,
11361 .dropdown-menu > li > a.pulse,
11362 li.pulse > a.dropdown-toggle,
11363 li.pulse.open > a.dropdown-toggle {
11364 background-color: #F37626;
11365 color: white;
11366 }
11367 /**
11368 * Primary styles
11369 *
11370 * Author: Jupyter Development Team
11371 */
11372 /** WARNING IF YOU ARE EDITTING THIS FILE, if this is a .css file, It has a lot
11373 * of chance of beeing generated from the ../less/[samename].less file, you can
11374 * try to get back the less file by reverting somme commit in history
11375 **/
11376 /*
11377 * We'll try to get something pretty, so we
11378 * have some strange css to have the scroll bar on
11379 * the left with fix button on the top right of the tooltip
11380 */
11381 @-moz-keyframes fadeOut {
11382 from {
11383 opacity: 1;
11384 }
11385 to {
11386 opacity: 0;
11387 }
11388 }
11389 @-webkit-keyframes fadeOut {
11390 from {
11391 opacity: 1;
11392 }
11393 to {
11394 opacity: 0;
11395 }
11396 }
11397 @-moz-keyframes fadeIn {
11398 from {
11399 opacity: 0;
11400 }
11401 to {
11402 opacity: 1;
11403 }
11404 }
11405 @-webkit-keyframes fadeIn {
11406 from {
11407 opacity: 0;
11408 }
11409 to {
11410 opacity: 1;
11411 }
11412 }
11413 /*properties of tooltip after "expand"*/
11414 .bigtooltip {
11415 overflow: auto;
11416 height: 200px;
11417 -webkit-transition-property: height;
11418 -webkit-transition-duration: 500ms;
11419 -moz-transition-property: height;
11420 -moz-transition-duration: 500ms;
11421 transition-property: height;
11422 transition-duration: 500ms;
11423 }
11424 /*properties of tooltip before "expand"*/
11425 .smalltooltip {
11426 -webkit-transition-property: height;
11427 -webkit-transition-duration: 500ms;
11428 -moz-transition-property: height;
11429 -moz-transition-duration: 500ms;
11430 transition-property: height;
11431 transition-duration: 500ms;
11432 text-overflow: ellipsis;
11433 overflow: hidden;
11434 height: 80px;
11435 }
11436 .tooltipbuttons {
11437 position: absolute;
11438 padding-right: 15px;
11439 top: 0px;
11440 right: 0px;
11441 }
11442 .tooltiptext {
11443 /*avoid the button to overlap on some docstring*/
11444 padding-right: 30px;
11445 }
11446 .ipython_tooltip {
11447 max-width: 700px;
11448 /*fade-in animation when inserted*/
11449 -webkit-animation: fadeOut 400ms;
11450 -moz-animation: fadeOut 400ms;
11451 animation: fadeOut 400ms;
11452 -webkit-animation: fadeIn 400ms;
11453 -moz-animation: fadeIn 400ms;
11454 animation: fadeIn 400ms;
11455 vertical-align: middle;
11456 background-color: #f7f7f7;
11457 overflow: visible;
11458 border: #ababab 1px solid;
11459 outline: none;
11460 padding: 3px;
11461 margin: 0px;
11462 padding-left: 7px;
11463 font-family: monospace;
11464 min-height: 50px;
11465 -moz-box-shadow: 0px 6px 10px -1px #adadad;
11466 -webkit-box-shadow: 0px 6px 10px -1px #adadad;
11467 box-shadow: 0px 6px 10px -1px #adadad;
11468 border-radius: 2px;
11469 position: absolute;
11470 z-index: 1000;
11471 }
11472 .ipython_tooltip a {
11473 float: right;
11474 }
11475 .ipython_tooltip .tooltiptext pre {
11476 border: 0;
11477 border-radius: 0;
11478 font-size: 100%;
11479 background-color: #f7f7f7;
11480 }
11481 .pretooltiparrow {
11482 left: 0px;
11483 margin: 0px;
11484 top: -16px;
11485 width: 40px;
11486 height: 16px;
11487 overflow: hidden;
11488 position: absolute;
11489 }
11490 .pretooltiparrow:before {
11491 background-color: #f7f7f7;
11492 border: 1px #ababab solid;
11493 z-index: 11;
11494 content: "";
11495 position: absolute;
11496 left: 15px;
11497 top: 10px;
11498 width: 25px;
11499 height: 25px;
11500 -webkit-transform: rotate(45deg);
11501 -moz-transform: rotate(45deg);
11502 -ms-transform: rotate(45deg);
11503 -o-transform: rotate(45deg);
11504 }
11505 ul.typeahead-list i {
11506 margin-left: -10px;
11507 width: 18px;
11508 }
11509 ul.typeahead-list {
11510 max-height: 80vh;
11511 overflow: auto;
11512 }
11513 ul.typeahead-list > li > a {
11514 /** Firefox bug **/
11515 /* see https://github.com/jupyter/notebook/issues/559 */
11516 white-space: normal;
11517 }
11518 .cmd-palette .modal-body {
11519 padding: 7px;
11520 }
11521 .cmd-palette form {
11522 background: white;
11523 }
11524 .cmd-palette input {
11525 outline: none;
11526 }
11527 .no-shortcut {
11528 display: none;
11529 }
11530 .command-shortcut:before {
11531 content: "(command)";
11532 padding-right: 3px;
11533 color: #777777;
11534 }
11535 .edit-shortcut:before {
11536 content: "(edit)";
11537 padding-right: 3px;
11538 color: #777777;
11539 }
11540 #find-and-replace #replace-preview .match,
11541 #find-and-replace #replace-preview .insert {
11542 background-color: #BBDEFB;
11543 border-color: #90CAF9;
11544 border-style: solid;
11545 border-width: 1px;
11546 border-radius: 0px;
11547 }
11548 #find-and-replace #replace-preview .replace .match {
11549 background-color: #FFCDD2;
11550 border-color: #EF9A9A;
11551 border-radius: 0px;
11552 }
11553 #find-and-replace #replace-preview .replace .insert {
11554 background-color: #C8E6C9;
11555 border-color: #A5D6A7;
11556 border-radius: 0px;
11557 }
11558 #find-and-replace #replace-preview {
11559 max-height: 60vh;
11560 overflow: auto;
11561 }
11562 #find-and-replace #replace-preview pre {
11563 padding: 5px 10px;
11564 }
11565 .terminal-app {
11566 background: #EEE;
11567 }
11568 .terminal-app #header {
11569 background: #fff;
11570 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11571 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.2);
11572 }
11573 .terminal-app .terminal {
11574 width: 100%;
11575 float: left;
11576 font-family: monospace;
11577 color: white;
11578 background: black;
11579 padding: 0.4em;
11580 border-radius: 2px;
11581 -webkit-box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
11582 box-shadow: 0px 0px 12px 1px rgba(87, 87, 87, 0.4);
11583 }
11584 .terminal-app .terminal,
11585 .terminal-app .terminal dummy-screen {
11586 line-height: 1em;
11587 font-size: 14px;
11588 }
11589 .terminal-app .terminal .xterm-rows {
11590 padding: 10px;
11591 }
11592 .terminal-app .terminal-cursor {
11593 color: black;
11594 background: white;
11595 }
11596 .terminal-app #terminado-container {
11597 margin-top: 20px;
11598 }
11599 /*# sourceMappingURL=style.min.css.map */
11600 .c-ElasticMatch { background-color: #faffa6; padding: 0.2em;}
11601 .hll { background-color: #ffffcc }
11602 .c { color: #408080; font-style: italic } /* Comment */
11603 .err, .codehilite .err { border: none } /* Error */
11604 .k { color: #008000; font-weight: bold } /* Keyword */
11605 .o { color: #666666 } /* Operator */
11606 .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
11607 .cm { color: #408080; font-style: italic } /* Comment.Multiline */
11608 .cp { color: #BC7A00 } /* Comment.Preproc */
11609 .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
11610 .c1 { color: #408080; font-style: italic } /* Comment.Single */
11611 .cs { color: #408080; font-style: italic } /* Comment.Special */
11612 .gd { color: #A00000 } /* Generic.Deleted */
11613 .ge { font-style: italic } /* Generic.Emph */
11614 .gr { color: #FF0000 } /* Generic.Error */
11615 .gh { color: #000080; font-weight: bold } /* Generic.Heading */
11616 .gi { color: #00A000 } /* Generic.Inserted */
11617 .go { color: #888888 } /* Generic.Output */
11618 .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
11619 .gs { font-weight: bold } /* Generic.Strong */
11620 .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
11621 .gt { color: #0044DD } /* Generic.Traceback */
11622 .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
11623 .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
11624 .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
11625 .kp { color: #008000 } /* Keyword.Pseudo */
11626 .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
11627 .kt { color: #B00040 } /* Keyword.Type */
11628 .m { color: #666666 } /* Literal.Number */
11629 .s { color: #BA2121 } /* Literal.String */
11630 .na { color: #7D9029 } /* Name.Attribute */
11631 .nb { color: #008000 } /* Name.Builtin */
11632 .nc { color: #0000FF; font-weight: bold } /* Name.Class */
11633 .no { color: #880000 } /* Name.Constant */
11634 .nd { color: #AA22FF } /* Name.Decorator */
11635 .ni { color: #999999; font-weight: bold } /* Name.Entity */
11636 .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
11637 .nf { color: #0000FF } /* Name.Function */
11638 .nl { color: #A0A000 } /* Name.Label */
11639 .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
11640 .nt { color: #008000; font-weight: bold } /* Name.Tag */
11641 .nv { color: #19177C } /* Name.Variable */
11642 .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
11643 .w { color: #bbbbbb } /* Text.Whitespace */
11644 .mb { color: #666666 } /* Literal.Number.Bin */
11645 .mf { color: #666666 } /* Literal.Number.Float */
11646 .mh { color: #666666 } /* Literal.Number.Hex */
11647 .mi { color: #666666 } /* Literal.Number.Integer */
11648 .mo { color: #666666 } /* Literal.Number.Oct */
11649 .sa { color: #BA2121 } /* Literal.String.Affix */
11650 .sb { color: #BA2121 } /* Literal.String.Backtick */
11651 .sc { color: #BA2121 } /* Literal.String.Char */
11652 .dl { color: #BA2121 } /* Literal.String.Delimiter */
11653 .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
11654 .s2 { color: #BA2121 } /* Literal.String.Double */
11655 .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
11656 .sh { color: #BA2121 } /* Literal.String.Heredoc */
11657 .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
11658 .sx { color: #008000 } /* Literal.String.Other */
11659 .sr { color: #BB6688 } /* Literal.String.Regex */
11660 .s1 { color: #BA2121 } /* Literal.String.Single */
11661 .ss { color: #19177C } /* Literal.String.Symbol */
11662 .bp { color: #008000 } /* Name.Builtin.Pseudo */
11663 .fm { color: #0000FF } /* Name.Function.Magic */
11664 .vc { color: #19177C } /* Name.Variable.Class */
11665 .vg { color: #19177C } /* Name.Variable.Global */
11666 .vi { color: #19177C } /* Name.Variable.Instance */
11667 .vm { color: #19177C } /* Name.Variable.Magic */
11668 .il { color: #666666 } /* Literal.Number.Integer.Long */
11669 } No newline at end of file
This diff has been collapsed as it changes many lines, (623 lines changed) Show them Hide them
@@ -0,0 +1,623 b''
1 {
2 "name": "rcicons",
3 "css_prefix_text": "icon-",
4 "css_use_suffix": false,
5 "hinting": true,
6 "units_per_em": 1000,
7 "ascent": 850,
8 "copyright": "RhodeCode GmbH",
9 "glyphs": [
10 {
11 "uid": "a5f9b6d4d795603e6e29a5b8007cc139",
12 "css": "bookmark",
13 "code": 59395,
14 "src": "custom_icons",
15 "selected": true,
16 "svg": {
17 "path": "M780 990L520 700C510 690 495 690 485 700L225 995C205 1015 180 1000 180 965V35C175 15 190 0 205 0H795C810 0 825 15 825 35V960C825 995 795 1010 780 990Z",
18 "width": 1000
19 },
20 "search": [
21 "bookmark"
22 ]
23 },
24 {
25 "uid": "fbc028d3a6a0df72f8f508ff5dfbab72",
26 "css": "tag",
27 "code": 59397,
28 "src": "custom_icons",
29 "selected": true,
30 "svg": {
31 "path": "M459.8 62.5L93.8 53.6C75.9 53.6 62.5 67 62.5 84.8L75.9 450.9C75.9 459.8 80.4 464.3 84.8 473.2L549.1 937.5C562.5 950.9 580.4 950.9 593.8 937.5L946.4 584.8C959.8 571.4 959.8 553.6 946.4 540.2L477.7 71.4C473.2 67 464.3 62.5 459.8 62.5ZM357.1 285.7C357.1 321.4 325.9 352.7 290.2 352.7 254.5 352.7 223.2 321.4 223.2 285.7 223.2 250 254.5 218.8 290.2 218.8S357.1 245.5 357.1 285.7Z",
32 "width": 1000
33 },
34 "search": [
35 "tag"
36 ]
37 },
38 {
39 "uid": "1c67c02366438b324c184ff9e356dca1",
40 "css": "branch",
41 "code": 59396,
42 "src": "custom_icons",
43 "selected": true,
44 "svg": {
45 "path": "M875 250C875 174.1 817 116.1 741.1 116.1S607.1 174.1 607.1 250C607.1 299.1 633.9 339.3 669.6 361.6 651.8 504.5 531.3 544.6 459.8 558V245.5C504.5 223.2 531.3 183 531.3 133.9 531.3 58 473.2 0 397.3 0S263.4 58 263.4 133.9C263.4 183 290.2 227.7 330.4 250V750C290.2 772.3 263.4 817 263.4 866.1 263.4 942 321.4 1000 397.3 1000S531.3 942 531.3 866.1C531.3 817 504.5 772.3 464.3 750V692C526.8 683 629.5 660.7 709.8 580.4 767.9 522.3 799.1 450.9 808 366.1 848.2 343.8 875 299.1 875 250ZM397.3 89.3C424.1 89.3 442 107.1 442 133.9S424.1 178.6 397.3 178.6 352.7 160.7 352.7 133.9 370.5 89.3 397.3 89.3ZM397.3 910.7C370.5 910.7 352.7 892.9 352.7 866.1S370.5 821.4 397.3 821.4 442 839.3 442 866.1 419.6 910.7 397.3 910.7ZM741.1 205.4C767.9 205.4 785.7 223.2 785.7 250S767.9 294.6 741.1 294.6 696.4 276.8 696.4 250 718.8 205.4 741.1 205.4Z",
46 "width": 1000
47 },
48 "search": [
49 "branch"
50 ]
51 },
52 {
53 "uid": "b75f7b47706aebd803ef370082e8e334",
54 "css": "group",
55 "code": 59407,
56 "src": "custom_icons",
57 "selected": true,
58 "svg": {
59 "path": "M961.5 630.8V646.2C961.5 650 957.7 657.7 950 657.7H788.5 784.6C769.2 638.5 746.2 619.2 707.7 615.4 673.1 607.7 653.8 600 638.5 592.3 646.2 584.6 657.7 580.8 669.2 576.9 715.4 569.2 726.9 553.8 734.6 542.3 742.3 530.8 742.3 519.2 734.6 503.8 726.9 488.5 703.8 461.5 703.8 423.1 703.8 384.6 703.8 319.2 776.9 319.2H784.6 792.3C865.4 323.1 869.2 384.6 865.4 423.1 865.4 461.5 842.3 492.3 834.6 503.8 826.9 519.2 826.9 530.8 834.6 542.3 842.3 553.8 857.7 569.2 900 576.9 953.8 580.8 961.5 623.1 961.5 630.8 961.5 630.8 961.5 630.8 961.5 630.8ZM253.8 646.2C269.2 630.8 292.3 615.4 323.1 611.5 361.5 603.8 384.6 596.2 396.2 584.6 388.5 576.9 376.9 569.2 361.5 565.4 315.4 557.7 303.8 542.3 296.2 530.8 288.5 519.2 288.5 507.7 296.2 492.3 303.8 476.9 326.9 450 326.9 411.5 326.9 373.1 326.9 307.7 253.8 307.7H246.2 234.6C161.5 311.5 157.7 373.1 161.5 411.5 161.5 450 184.6 480.8 192.3 492.3 200 507.7 200 519.2 192.3 530.8 184.6 542.3 169.2 557.7 126.9 565.4 80.8 573.1 73.1 615.4 73.1 619.2 73.1 619.2 73.1 619.2 73.1 619.2V634.6C73.1 638.5 76.9 646.2 84.6 646.2H246.2 253.8ZM707.7 634.6C634.6 623.1 611.5 600 600 580.8 588.5 561.5 588.5 542.3 600 519.2 611.5 496.2 650 450 653.8 388.5 657.7 326.9 653.8 223.1 534.6 219.2H519.2 503.8C384.6 223.1 380.8 323.1 384.6 384.6 388.5 446.2 423.1 492.3 438.5 515.4 450 538.5 450 557.7 438.5 576.9 426.9 596.2 403.8 619.2 330.8 630.8 257.7 642.3 246.2 711.5 246.2 719.2 246.2 719.2 246.2 719.2 246.2 719.2V742.3C246.2 750 253.8 757.7 261.5 757.7H519.2 776.9C784.6 757.7 792.3 750 792.3 742.3V719.2C792.3 719.2 792.3 719.2 792.3 719.2 788.5 715.4 780.8 646.2 707.7 634.6Z",
60 "width": 1000
61 },
62 "search": [
63 "group"
64 ]
65 },
66 {
67 "uid": "7ae0ef039bb0217d9581e44b09448905",
68 "css": "fork",
69 "code": 59409,
70 "src": "custom_icons",
71 "selected": true,
72 "svg": {
73 "path": "M792.3 196.2C792.3 138.5 746.2 96.2 692.3 96.2 634.6 96.2 592.3 142.3 592.3 196.2 592.3 230.8 611.5 261.5 638.5 280.8 626.9 365.4 569.2 403.8 511.5 423.1 453.8 407.7 396.2 369.2 384.6 280.8 411.5 261.5 430.8 230.8 430.8 196.2 430.8 138.5 384.6 96.2 330.8 96.2S223.1 138.5 223.1 196.2C223.1 234.6 246.2 269.2 276.9 284.6 288.5 392.3 353.8 473.1 457.7 511.5V673.1C426.9 692.3 407.7 723.1 407.7 761.5 407.7 819.2 453.8 861.5 507.7 861.5S607.7 815.4 607.7 761.5C607.7 723.1 588.5 692.3 557.7 673.1V511.5C661.5 473.1 726.9 392.3 738.5 284.6 769.2 265.4 792.3 234.6 792.3 196.2ZM326.9 161.5C346.2 161.5 361.5 176.9 361.5 196.2S346.2 226.9 326.9 226.9 292.3 215.4 292.3 196.2 307.7 161.5 326.9 161.5ZM507.7 796.2C488.5 796.2 473.1 780.8 473.1 761.5S488.5 726.9 507.7 726.9C526.9 726.9 542.3 742.3 542.3 761.5S526.9 796.2 507.7 796.2ZM692.3 161.5C711.5 161.5 726.9 176.9 726.9 196.2S711.5 226.9 692.3 226.9 657.7 211.5 657.7 192.3 673.1 161.5 692.3 161.5Z",
74 "width": 1000
75 },
76 "search": [
77 "fork"
78 ]
79 },
80 {
81 "uid": "65e66c3e7d74e2c345fb78fadd400d3f",
82 "css": "rhodecode",
83 "code": 59441,
84 "src": "custom_icons",
85 "selected": true,
86 "svg": {
87 "path": "M174.6 216.8C173.4 220.9 172.2 225 171 229.1 168.1 239.1 165.2 249.1 162.3 259.1 158.7 271.6 155 284.2 151.4 296.7 148 308.4 144.6 320.1 141.2 331.8 139 339.3 136.8 346.8 134.7 354.3 134.4 355.4 134.1 356.5 133.7 357.6 133.7 357.7 133.9 358.2 134 358.3 134.3 359 134.5 359.7 134.8 360.5 137.2 367.3 139.7 374.1 142.1 381 146 392 149.9 403 153.9 414.1 158.3 426.5 162.8 439 167.2 451.4 171.1 462.5 175.1 473.6 179 484.7 181.5 491.7 184 498.6 186.4 505.6 186.8 506.7 187.2 507.7 187.5 508.8 187.8 509.6 188.6 510.4 189 511.1 192.8 516.9 196.5 522.6 200.3 528.4 206.5 537.9 212.7 547.4 219 556.9 226.2 567.9 233.4 578.9 240.6 590 247.3 600.3 254.1 610.6 260.8 620.9 265.6 628.2 270.4 635.6 275.2 642.9 276.4 644.8 277.6 646.6 278.9 648.5 279.2 649 279.5 649.5 279.8 649.8 282.7 652.6 285.5 655.4 288.4 658.2 294.6 664.3 300.9 670.5 307.1 676.6 315.5 684.9 323.9 693.2 332.4 701.4 341.8 710.6 351.2 719.9 360.6 729.1 369.8 738.1 378.9 747.1 388.1 756.1 395.8 763.7 403.6 771.3 411.3 778.9 416.4 783.9 421.5 788.9 426.6 793.9 428.2 795.5 429.8 797.3 431.6 798.6 438.9 803.9 446.1 809.2 453.4 814.5 463.7 822 473.9 829.5 484.2 837 487.6 839.5 491.1 842 494.5 844.5 495.3 845.1 496.1 845.7 496.9 846.3 497.2 846.5 497.2 846.6 497.6 846.4 504.7 842.7 511.8 839.1 518.9 835.4 530.3 829.5 541.7 823.6 553.1 817.7 559.2 814.5 565.4 811.4 571.5 808.2 571.9 808 572.3 807.1 572.6 806.8 573.7 805.4 574.8 804 576 802.5 580.2 797.2 584.3 791.9 588.5 786.7 594.7 778.9 600.8 771.1 607 763.3 614.5 753.8 622 744.3 629.5 734.8 637.7 724.5 645.8 714.1 654 703.8 662.1 693.5 670.3 683.2 678.4 672.9 685.9 663.5 693.3 654 700.8 644.6 706.9 636.9 713 629.2 719.1 621.5 723.2 616.4 727.2 611.2 731.3 606.1 732.7 604.4 734 602.6 735.4 600.9 735.2 600.8 734.8 600.8 734.6 600.7 733.8 600.5 733 600.4 732.2 600.2 729.1 599.6 726 598.9 722.9 598.2 718 597.1 713 596 708.1 594.8 701.5 593.2 694.9 591.5 688.3 589.7 680.2 587.5 672.2 585.2 664.1 582.9 654.7 580.1 645.4 577.2 636.1 574.1 625.6 570.6 615.2 567 604.8 563.3 593.4 559.1 582 554.8 570.8 550.2 558.6 545.3 546.6 540.1 534.6 534.8 521.9 529.1 509.3 523.1 496.8 516.8 483.7 510.2 470.7 503.4 457.9 496.2 444.6 488.7 431.4 480.9 418.5 472.8 405.1 464.4 392 455.6 379.1 446.4 365.9 437 352.9 427.1 340.3 416.9 327.4 406.4 314.8 395.5 302.7 384.2 290.3 372.6 278.3 360.6 266.8 348.1 255.1 335.3 243.8 322.1 233.2 308.4 222.3 294.4 212 279.9 202.4 265 192.5 249.7 183.4 233.9 175 217.8 175 217.4 174.8 217.1 174.6 216.8ZM172.1 214.2C170.7 218.7 169.3 223.3 167.8 227.8 164.5 238.5 161.1 249.2 157.8 259.9 153.9 272.4 150 285 146.1 297.5 143 307.5 139.9 317.4 136.7 327.4 135.9 330.1 135 332.7 134.2 335.4 134 336.1 133.6 336.7 133.8 337.4 135.4 342.2 137 347.1 138.6 351.9 141.9 361.9 145.2 371.8 148.6 381.8 152.7 394.1 156.8 406.5 160.9 418.8 164.9 430.8 168.9 442.8 172.9 454.8 175.9 463.7 178.8 472.6 181.8 481.4 182.6 483.8 183.4 486.2 184.2 488.7 184.4 489.4 184.6 490.1 184.9 490.8 187.2 495 189.5 499.2 191.8 503.4 196.8 512.6 201.9 521.8 206.9 531 213.2 542.4 219.4 553.9 225.7 565.3 231.7 576.2 237.6 587.1 243.6 598 247.8 605.6 251.9 613.2 256.1 620.8 257.3 623 258.2 625.4 259.9 627.2 264.1 631.7 268.3 636.2 272.5 640.7 280.2 648.9 287.9 657.2 295.5 665.4 304.5 675 313.5 684.7 322.4 694.3 330.5 703 338.6 711.7 346.7 720.4 351.8 725.8 356.8 731.3 361.9 736.7 363.5 738.4 365 740 366.6 741.6 372.3 747.3 378 753 383.7 758.7 392.5 767.5 401.2 776.2 410 785 419.1 794.1 428.3 803.3 437.4 812.4 444.2 819.2 451.1 826.1 457.9 832.9 459.6 834.6 461.3 836.3 463 838 463.3 838.3 463.6 838.6 463.8 838.8 463.9 838.9 465.1 838.7 465.3 838.6 475.9 837.2 486.5 835.8 497 834.5 505.6 833.4 514.1 832.3 522.7 831.2 523 831.2 523.7 830.1 523.9 829.9 525.1 828.6 526.3 827.2 527.6 825.9 532.1 820.9 536.7 815.9 541.2 810.9 547.9 803.5 554.6 796.1 561.4 788.7 569.6 779.7 577.7 770.7 585.9 761.8 594.8 752 603.6 742.3 612.5 732.5 621.3 722.8 630.1 713.1 639 703.4 647 694.5 655.1 685.7 663.1 676.8 669.6 669.6 676.2 662.4 682.7 655.2 687 650.5 691.3 645.8 695.6 641 696.6 639.9 697.7 638.7 698.7 637.6 698.9 637.4 699.6 636.9 699.6 636.6 699.6 636.5 696.6 635.7 696.5 635.7 693.5 634.8 690.4 633.9 687.4 633 682.6 631.5 677.8 630 673 628.4 666.6 626.3 660.1 624.1 653.8 621.8 645.9 619 638.1 616.1 630.3 613.1 621.2 609.6 612.1 606 603.1 602.2 592.9 598 582.8 593.6 572.8 589 561.8 584 550.8 578.8 540 573.4 528.3 567.6 516.7 561.6 505.2 555.3 493 548.7 480.9 541.8 469 534.6 456.5 527.1 444.1 519.3 431.9 511.2 419.2 502.8 406.7 494 394.5 484.9 381.8 475.5 369.5 465.8 357.4 455.7 345 445.3 332.8 434.6 321.1 423.4 309.1 412 297.4 400.2 286.2 388 274.7 375.5 263.7 362.6 253.2 349.3 242.5 335.7 232.3 321.7 222.8 307.2 213 292.4 203.9 277.2 195.5 261.7 186.8 246.5 179 230.5 172.1 214.2ZM169.5 204C168.8 207.8 168.1 211.6 167.3 215.4 165.5 224.9 163.7 234.5 161.9 244 159.5 256.5 157.1 269 154.7 281.5 152.3 294.2 149.8 307 147.4 319.7 145.5 329.9 143.5 340.1 141.6 350.3 140.7 355.2 139.7 360.1 138.8 365 138.7 365.7 139.1 366.4 139.3 367 140.2 369.6 141.1 372.2 142 374.8 145.4 384.5 148.7 394.3 152.1 404 156.4 416.4 160.7 428.7 165 441.1 168.8 452.1 172.6 463 176.4 474 178.3 479.5 180.2 485 182.1 490.5 182.3 491.2 182.7 491.8 183 492.4 184.2 494.8 185.4 497.1 186.5 499.5 190.9 508.4 195.4 517.2 199.8 526.1 205.6 537.7 211.4 549.3 217.2 560.9 222.7 571.9 228.2 583 233.8 594 237.4 601.2 241 608.3 244.6 615.5 245.2 616.6 245.7 617.7 246.3 618.8 246.7 619.6 247.6 620.4 248.2 621.1 252.8 626.6 257.4 632.1 262 637.7 269.5 646.7 276.9 655.6 284.4 664.6 292.8 674.7 301.3 684.9 309.7 695 317.2 704 324.8 713.1 332.3 722.1 337 727.8 341.8 733.5 346.5 739.1 347.2 740 347.9 740.8 348.7 741.7 348.9 741.9 349.2 742 349.4 742.2 350.2 742.7 350.9 743.2 351.7 743.7 358.7 748.5 365.8 753.3 372.8 758.1 383.3 765.3 393.9 772.5 404.4 779.7 414.6 786.6 424.7 793.6 434.9 800.5 440.8 804.5 446.7 808.6 452.7 812.6 456.3 815.1 459.5 818.1 462.9 820.8 472.5 828.7 482.1 836.7 491.7 844.6 498.5 850.2 505.4 855.9 512.2 861.5 512.8 862 512.7 861.9 513.3 861.3 514.2 860.3 515.2 859.2 516.1 858.2 520 853.9 524 849.6 527.9 845.3 534 838.6 540.2 831.9 546.3 825.2 554 816.8 561.7 808.3 569.4 799.9 578.1 790.4 586.7 781 595.4 771.5 604.4 761.7 613.3 751.9 622.3 742.1 630.9 732.6 639.6 723.2 648.2 713.7 655.9 705.3 663.6 696.9 671.3 688.5 677.4 681.8 683.5 675.1 689.6 668.4 693.5 664.1 697.4 659.9 701.3 655.6 702.4 654.4 703.5 653.2 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652.1 701.6 651.3 701.5 651.3 698.5 650.5 695.5 649.5 692.6 648.6 687.9 647.1 683.1 645.5 678.4 643.8 672.1 641.6 665.8 639.2 659.5 636.9 651.8 634 644.1 630.9 636.4 627.8 627.5 624.1 618.6 620.3 609.7 616.4 599.7 612 589.8 607.4 580 602.7 569.2 597.5 558.4 592.1 547.7 586.6 536.2 580.6 524.8 574.4 513.4 568 501.4 561.2 489.5 554.2 477.7 546.9 465.3 539.3 453.1 531.4 441.1 523.3 428.6 514.8 416.3 506.1 404.2 497 391.7 487.7 379.5 478 367.5 468 355.2 457.8 343.2 447.2 331.5 436.3 319.6 425.2 308 413.6 296.8 401.7 285.4 389.6 274.5 377.1 264 364.3 253.3 351.2 243.2 337.8 233.6 323.9 223.8 309.8 214.6 295.4 206.1 280.5 197.4 265.4 189.4 249.9 182.1 234 177.7 224.2 173.5 214.2 169.5 204ZM866 183.5C863.9 179.4 861.1 176.2 857.1 174 851.9 171.1 846.2 168.9 840.7 166.5 829.5 161.7 818.2 157.4 806.7 153.4 783.6 145.4 760 138.9 736.3 132.9 711.7 126.7 687.1 120.9 662.3 115.7 637.1 110.4 611.7 105.6 586.3 101.4 561.2 97.2 536 93.1 510.5 91.1 497.8 90.1 485 89.9 472.4 91.3 465.9 92 459.4 93.2 453 94.2 446.6 95.2 440.1 96.2 433.7 97.3 408.2 101.5 382.8 106 357.4 111 332.2 115.9 307.1 121.2 282.1 126.9 257.2 132.5 232.6 139.2 208.4 147.3 196.3 151.4 184.2 155.8 172.3 160.5 166.4 162.8 160.5 165.2 154.6 167.7 151.7 168.9 148.8 170.2 145.8 171.4 143.2 172.5 140.6 173.5 138.1 174.7 134 176.7 130.6 179.7 128.3 183.6 127 185.8 126.2 188.2 125.3 190.6 124.2 193.6 123.1 196.6 122.1 199.6 118.1 211.5 114.9 223.7 112.5 236 107.7 260.4 106 285.4 106.8 310.2 107.2 322.7 108.2 335.3 109.7 347.7 111.2 360.2 112.7 372.8 115.1 385.2 119.8 410.4 126.7 435.1 134.8 459.3 138.9 471.4 143.3 483.5 147.9 495.4 152.2 506.5 157.5 517.3 162.7 528 173 549.2 184.4 569.8 196.6 589.9 208.8 609.9 221.9 629.3 235.7 648.1 249.5 666.8 264.1 685 279.3 702.6 295.3 721.1 311.7 739.2 328.6 756.9 345.6 774.8 363 792.2 381 809 398.9 825.9 417.4 842.2 436.4 857.8 445.6 865.4 454.9 872.8 464.2 880.2 473.6 887.7 483.1 895.1 492 903.2 494.3 905.2 496.5 907.3 498.7 909.5 498.9 909.7 499.7 910.8 500 910.8 500.2 910.8 500.5 910.8 500.7 910.8 501.2 910.8 502 911 502.5 910.8 507.3 907.1 512 903.3 516.8 899.6 526.2 892.1 535.6 884.6 544.9 876.9 563.3 861.7 581.4 846.2 599.2 830.3 616.9 814.5 634.1 798.2 651 781.5 667.9 764.7 684.4 747.5 700.3 729.7 716.3 711.8 731.8 693.4 746.5 674.4 761 655.7 774.8 636.5 787.8 616.8 800.7 597.2 812.8 577 823.8 556.2 835 535.1 845.2 513.5 854.3 491.4 863.4 469.1 871.2 446.3 877.3 423 883.4 399.9 887.8 376.4 890.3 352.7 892.9 328.6 893.4 304.3 892 280 891.8 276.9 891 273.8 890.3 270.7 889.7 267.7 889 264.6 888.4 261.6 887.2 255.7 886 249.9 884.7 244 882.3 233 879.7 222 876.5 211.1 873.4 201.8 870.1 192.5 866 183.5 863.5 178.4 878.8 211.7 866 183.5ZM814.8 393.5C808.1 418.2 799.5 442.5 789.4 466 780 487.9 770 509.6 758.5 530.5 747.4 550.7 735.1 570.3 722 589.3 708.8 608.4 694.7 626.8 680 644.8 664.8 663.4 649 681.5 632.7 699.1 615.9 717.3 598.5 734.9 580.5 752 562.5 769.1 544.1 785.7 525.1 801.6 515.7 809.5 506.1 817.3 496.5 824.9 496.1 825.2 495.2 826.3 494.7 826.3 494 826.3 493.3 826.3 492.6 826.3 492 826.3 491.4 825.5 491 825.1 490.5 824.6 490 824.1 489.5 823.6 488.4 822.6 487.2 821.5 486.1 820.5 481.6 816.6 476.9 813.1 472.2 809.4 469.9 807.6 467.6 805.7 465.3 803.8 463.1 801.9 461 799.8 458.8 797.8 454.2 793.7 449.7 789.6 445.2 785.5 435.9 777 426.6 768.5 417.5 759.8 408.4 751.1 399.5 742.3 390.9 733.2 386.7 728.8 382.7 724.3 378.4 720 374.2 715.8 370 711.5 365.8 707.2 349.1 690 332.9 672.5 317.4 654.3 301.8 636 286.9 617 273.1 597.3 259.2 577.5 246.4 556.9 234.5 535.8 222.8 515 212.1 493.7 202.6 471.8 193.1 449.9 184.8 427.4 177.9 404.6 176.1 398.6 174.4 392.6 173.1 386.5 171.7 380.1 170.6 373.6 169.6 367.1 167.6 354.2 166.3 341.2 165.5 328.2 164.7 315.3 164.3 302.3 164.5 289.3 164.7 276.7 165.9 264.2 167.5 251.7 167.9 248.5 168.3 245.4 168.7 242.2 168.9 240.6 169.1 239.1 169.3 237.5 169.5 235.9 169.6 234.3 169.8 232.7 170.1 230.3 171.1 228.1 171.7 225.7 172 224.5 172.2 223.2 172.2 221.9 172.2 220.8 172.8 220.1 173.6 219.5 174.6 218.8 175.6 218.3 176.5 217.5 177.1 217 177.6 216.6 178.4 216.3 179.2 216 180.1 215.7 180.9 215.3 183.9 214.2 186.8 213 189.8 211.9 195.7 209.7 201.6 207.5 207.6 205.3 231.3 196.7 255.3 189 279.7 182.4 292 179.1 304.3 176.1 316.7 173.5 322.9 172.2 329.1 170.6 335.4 169.3 341.7 167.9 348 166.6 354.3 165.4 379.8 160.4 405.4 156.3 431.1 152.5 444 150.6 457 148.8 470 147 473.2 146.6 476.5 146.1 479.7 145.7 481.3 145.5 482.8 145.3 484.4 145.1 485.7 144.9 487.1 145 488.4 145.1 493.9 145.1 499.5 145.3 504.9 146.3 506.2 146.5 507.4 146.8 508.6 147.1 510.1 147.5 511.5 147.8 513 148 516.1 148.4 519.2 148.9 522.3 149.3 528.6 150.2 534.8 151.1 541.1 152 553.7 153.8 566.4 155.7 579 157.7 604.4 161.7 629.7 166 654.8 171.4 680 176.8 705 183.2 729.7 190.3 742.1 193.9 754.4 197.7 766.6 201.7 772.7 203.7 778.7 205.8 784.7 207.9 787.7 209 790.7 210 793.7 211.1 795.1 211.6 796.6 212.1 798 212.7 798.7 213 799.4 213.2 800.1 213.5 800.8 213.8 801.9 214 802.4 214.5 803.6 215.7 805.3 216.5 806.3 217.9 806.8 218.7 807.1 219.5 807.2 220.5 807.3 221.2 807.2 221.8 807.4 222.5 807.7 223.4 807.9 224.3 808.1 225.2 809.8 231.5 811.2 237.9 812.3 244.4 813.4 250.8 814.1 257.2 814.5 263.6 814.7 266.8 814.8 270 814.9 273.2 814.9 274 814.9 274.7 814.9 275.5 814.9 276.3 815.2 277.1 815.3 277.8 815.7 279.5 816 281.1 816.4 282.8 821.3 306.5 822.7 330.7 820.7 354.8 819.6 367.7 817.6 380.7 814.8 393.5 807.1 421.7 822.5 357.6 814.8 393.5ZM617.6 393.5C616.1 389 614.6 384.5 613.1 379.9 612.9 379.3 612.7 378.7 612.5 378.1 612.4 377.7 612.5 377.1 612.4 376.7 612.3 376.1 612.2 375.5 612.1 374.9 611.8 373.8 611.4 372.8 610.8 371.9 609.7 370.1 608.1 368.5 606.5 367 604.7 365.2 602.4 362.7 599.6 362.7 601.6 360.7 604.3 360 606.5 358.3 607.6 357.4 608.5 356.5 609.7 355.7 610.5 355.2 611.6 354.7 612.1 353.8 612.3 353.4 612.4 352.9 612.4 352.5 612.9 352 613.3 351.5 613.7 350.9 614.4 349.8 614.7 348.6 614.9 347.3 615.1 345.1 615 342.9 615 340.7 615 338.4 615 336.1 615 333.8 615 331.4 615 329 614.4 326.6 613.1 321.5 610 316.8 606.4 313.1 604.7 311.4 603 309.9 601 308.6 598.3 306.9 595.5 305.5 592.7 304.1 589.9 302.7 586.9 301.8 583.8 301.4 581.4 301.1 579 301.1 576.6 301.1 573.9 301.1 571.2 301.1 568.5 301.1 556.2 301.1 543.8 301.1 531.5 301.1 526.9 301.1 522.3 301.1 517.7 301.1 516.9 301.1 516.1 301.1 515.2 301.1 515.1 301.1 515.2 305.3 515.2 305.6 515.2 308.8 515.2 311.9 515.2 315.1 515.2 316.2 515.2 317.3 515.2 318.4 515.2 318.9 515 319.1 515.5 319.1 516.7 319.1 528 319 528 319.2 528 327.2 528 335.2 528 343.2 528 355.8 528 368.3 528 380.9 528 384.6 528 388.3 528 392 528 392.2 528.1 393.4 527.9 393.4 525.4 393.4 522.8 393.4 520.3 393.4 518.9 393.4 517.6 393.4 516.2 393.4 515.9 393.4 515.2 393.2 515.2 393.6 515.2 395.7 515.2 397.8 515.2 400 515.2 401 515.2 414 515.2 414 524.7 414 534.3 414 543.8 414 549.3 414 554.8 414 560.2 414 561.4 414 562.5 414 563.7 414 564 414 563.8 411.1 563.8 410.7 563.8 405.1 563.8 399.6 563.8 394 563.8 393.4 563.9 393.5 563.3 393.5 562 393.5 560.7 393.5 559.3 393.5 557.8 393.5 556.3 393.5 554.8 393.5 554.6 393.5 553.5 393.7 553.5 393.4 553.5 388.4 553.5 383.4 553.5 378.4 553.5 375.6 553.5 372.9 553.5 370.1 553.5 369.4 553.5 368.8 553.5 368.1 553.5 367.7 554.2 367.9 554.5 367.9 557.4 367.9 560.2 367.9 563.1 367.9 565 367.9 566.9 367.9 568.8 367.9 570.1 367.9 571.6 367.7 572.8 368.1 573.9 368.4 574.8 369 575.7 369.7 576.8 370.6 578.3 371.8 578.9 373.1 579.2 373.8 579.2 374.5 579.2 375.3 579.2 376.6 579.6 377.7 580.2 378.9 580.7 380 581.3 381 581.6 382.2 581.7 382.6 581.7 383 581.8 383.4 581.9 384 582 384.6 582.1 385.1 583.1 390.9 584.2 396.6 585.2 402.4 585.6 404.9 586.1 407.3 586.5 409.8 586.6 410.3 586.7 410.8 586.8 411.3 586.8 411.4 587.2 411.4 587.4 411.4 597.8 411.4 608.3 411.4 618.7 411.4 619.2 411.4 619.6 411.4 620.1 411.4 620.2 411.4 620.2 410.7 620.2 410.6 620.2 408.2 620.2 405.7 620.2 403.3 620.2 398.3 620.2 393.3 620.2 388.4 620.2 388.4 620.2 388.4 620.2 388.4 619.3 390.1 618.5 391.8 617.6 393.5ZM592 339.7C592 342 589.2 342.8 587.7 344.1 587.4 344.3 587.1 344.6 586.9 344.8 586.7 344.8 586.4 344.8 586.2 344.9 585.8 345 585.4 345.2 585.1 345.4 584.4 345.9 583.9 346.6 583.2 347 582.1 347.5 580.7 347.3 579.6 347.3 577.9 347.3 576.3 347.3 574.6 347.3 573.9 347.3 573.2 347.3 572.5 347.3 569.5 347.3 566.4 347.3 563.4 347.3 563 347.3 558.8 347.4 558.8 347.2 558.8 337.9 558.8 328.5 558.8 319.2 558.8 319.1 571.7 319.2 573 319.2 577 319.2 581 319.1 584.9 320.1 586.4 320.5 587.8 321 589.2 321.6 590.1 322.1 591 323.2 591.6 324 593.1 325.7 594.1 327.8 594.5 330 594.6 330.7 594.6 331.3 594.6 332 594.3 332.6 594 333.2 593.7 333.9 593.3 334.7 592.9 335.5 592.6 336.3 592.1 337.4 592 338.5 592 339.7ZM722.6 393.5C722.6 384.2 722.6 374.9 722.6 365.6 722.6 357.1 720.9 348 714.6 341.9 707.5 335.1 696.4 333.9 687 334.7 685.1 334.9 683.2 335.3 681.4 336.1 680.4 336.5 679.5 336.9 678.6 337.6 678 338.1 677.3 338.5 676.7 338.8 673.6 340.4 670.5 341.6 668.8 344.9 668.8 335.9 668.8 326.8 668.8 317.8 668.8 311.9 668.8 306 668.8 300.1 668.8 298.4 668.8 296.6 668.8 294.9 668.8 294.4 669.1 293.7 668.5 293.7 657.9 293.7 647.3 293.7 636.7 293.7 635.5 293.7 634.2 293.7 633 293.7 633 293.7 633 297.8 633 298.1 633 303.4 633 308.7 633 314 633 314.3 633.8 314.2 634 314.2 635.4 314.2 636.7 314.2 638.1 314.2 640.6 314.2 643.2 314.2 645.7 314.2 645.9 314.2 645.8 319.4 645.8 319.8 645.8 331.2 645.8 342.6 645.8 353.9 645.8 364.9 645.8 375.8 645.8 386.8 645.8 388 645.8 389.2 645.8 390.3 645.8 391.2 645.7 391 644.6 391 641.6 391 638.7 391 635.7 391 634.8 391 633.9 391 633 391 632.9 391 632.9 391.9 632.9 392 632.9 397.7 632.9 403.4 632.9 409 632.9 409.8 632.9 410.5 632.9 411.3 632.9 411.5 633 411.5 633.2 411.5 634.5 411.5 635.9 411.5 637.2 411.5 649.1 411.5 661 411.5 672.9 411.5 673.4 411.5 681.5 411.5 681.5 411.5 681.5 406.5 681.5 401.5 681.5 396.5 681.5 394.7 681.5 392.9 681.5 391.1 681.5 391.1 675.6 391.1 675.2 391.1 674.8 391.1 668.7 391.1 668.7 391.1 668.7 389.8 668.7 388.5 668.7 387.3 668.7 381.2 668.7 375 668.7 368.9 668.7 366.5 668.7 364.2 668.7 361.8 668.7 361.3 668.7 360.9 668.7 360.4 668.7 360 670.3 358.8 670.6 358.5 671.7 357.5 672.8 356.5 674.2 355.8 674.7 355.5 675.3 355.3 675.8 355.3 676.5 355.2 676.8 354.8 677.4 354.3 678.5 353.5 679.7 353 681 352.8 683.6 352.4 685.8 352.7 687.9 354.2 689.1 355.1 690.1 356.1 691.2 357.2 692 358 692.7 358.8 693.3 359.8 694.2 361.6 694.3 363.7 694.3 365.7 694.4 369.3 694.3 372.9 694.3 376.6 694.3 387.8 694.3 399 694.3 410.3 694.3 410.9 694 411.6 694.7 411.6 696.4 411.6 698.1 411.6 699.8 411.6 706 411.6 712.3 411.6 718.5 411.6 722.4 411.6 726.3 411.6 730.2 411.6 730.2 411.6 730.2 398.5 730.2 397.5 730.2 395.4 730.2 393.3 730.2 391.2 727.8 391.8 725.2 392.6 722.6 393.5ZM730.3 270.6C727.9 270.6 725.4 270.6 723 270.6 722 270.6 721.1 270.6 720.1 270.6 720 270.6 719.6 271.3 719.6 271.4 716.5 276 713.4 280.6 710.4 285.3 708.9 287.5 707.4 289.7 706 292 705.6 292.5 705.3 293.1 704.9 293.6 704.6 294.1 704.8 294.9 704.8 295.4 704.8 295.6 704.8 298.8 704.8 298.8 705.4 298.8 706 298.8 706.5 298.8 709.5 298.8 712.4 298.8 715.4 298.8 717.8 298.8 720.1 298.8 722.5 298.8 723 298.8 722.7 299.6 722.7 299.9 722.7 301.4 722.7 302.9 722.7 304.4 722.7 305.8 722.7 307.1 722.7 308.5 722.7 309.3 723 309.1 723.8 309.1 725.3 309.1 726.9 309.1 728.4 309.1 728.7 309.1 730.3 309.3 730.3 308.9 730.3 306.2 730.3 303.4 730.3 300.7 730.3 300.4 730.1 298.8 730.5 298.8 731.9 298.8 733.3 298.8 734.6 298.8 734.7 298.8 735.4 298.8 735.4 298.8 735.4 298.2 735.4 297.7 735.4 297.1 735.4 296.9 735.4 293.7 735.4 293.7 734.1 293.7 732.9 293.7 731.6 293.7 731.1 293.7 730.3 294 730.3 293.4 730.3 285.7 730.3 278.1 730.3 270.6ZM722.6 285.9C722.6 287.2 722.6 288.5 722.6 289.7 722.6 290.6 722.6 291.4 722.6 292.3 722.6 292.5 722.7 293.4 722.6 293.6 722.5 293.7 721.6 293.6 721.5 293.6 720.6 293.6 719.7 293.6 718.8 293.6 717.5 293.6 716.2 293.6 715 293.6 716.3 291.6 717.7 289.6 719 287.6 719.6 286.7 720.2 285.9 720.8 285.1 722.4 283.1 722.6 280.7 722.6 278.2 722.6 280.8 722.6 283.4 722.6 285.9ZM763.6 288.5C760.9 285.8 756.2 285.9 752.6 285.9 752 285.9 751.4 285.9 750.8 285.9 750.8 285.9 750.8 284.8 750.8 284.7 750.8 283.4 750.8 282.1 750.8 280.8 750.8 280.7 763.9 280.8 765.2 280.8 765.7 280.8 766.2 281 766.2 280.5 766.2 279.1 766.2 277.7 766.2 276.4 766.2 275.3 766.2 274.2 766.2 273.2 766.2 273.2 764.9 273.2 764.9 273.2 759.2 273.2 753.5 273.2 747.8 273.2 747.2 273.2 746.5 273.2 745.9 273.2 745.7 273.2 745.7 273.6 745.7 273.8 745.4 276 745.1 278.2 744.9 280.4 744.3 284.8 743.8 289.3 743.2 293.7 747 293.7 751.5 293.1 755.1 294.8 757.9 296.2 759 299.4 758.5 302.4 758 305.8 754.4 306.5 751.5 306.5 749.6 306.5 743.2 307 743.2 303.9 742.3 306.5 741.5 309 740.6 311.6 742.3 311.6 744 312.6 745.6 313.2 748 314.1 750.5 314.3 753 314.1 756.9 313.8 761 312.5 763.6 309.4 766.3 306.1 766.2 301.9 766.2 297.8 766.2 295.6 766.2 293.3 765.7 291.1 765.5 290.1 765 288.6 763.7 288.5 763.7 288.5 763.6 288.5 763.6 288.5 761 285.9 766.2 288.5 763.6 288.5Z",
88 "width": 1000
89 },
90 "search": [
91 "rhodecode"
92 ]
93 },
94 {
95 "uid": "e5ad8728e6d6290aff4b6ffcfcaa9167",
96 "css": "up",
97 "code": 59442,
98 "src": "custom_icons",
99 "selected": true,
100 "svg": {
101 "path": "M686.5 595.8L513.6 379.1C506.3 369.9 492.4 369.9 485.1 379.1L312.2 595.8C302.7 607.8 311.2 625.4 326.5 625.4H672.2C687.5 625.4 696 607.8 686.5 595.8Z",
102 "width": 1000
103 },
104 "search": [
105 "up"
106 ]
107 },
108 {
109 "uid": "6e459e39444c93a2c017f258186765d6",
110 "css": "unlock",
111 "code": 59399,
112 "src": "custom_icons",
113 "selected": true,
114 "svg": {
115 "path": "M780.8 434.6H396.2V342.3C396.2 284.6 438.5 238.5 492.3 226.9 492.3 226.9 492.3 226.9 496.2 226.9 503.8 226.9 507.7 226.9 515.4 226.9 515.4 226.9 519.2 226.9 519.2 226.9 519.2 226.9 519.2 226.9 523.1 226.9 530.8 226.9 538.5 226.9 546.2 230.8 546.2 230.8 546.2 230.8 546.2 230.8 553.8 230.8 557.7 234.6 565.4 238.5 565.4 238.5 569.2 238.5 569.2 242.3 573.1 246.2 580.8 246.2 584.6 250 584.6 250 584.6 250 584.6 250 588.5 253.8 596.2 257.7 600 261.5 600 261.5 603.8 265.4 603.8 265.4 607.7 269.2 611.5 273.1 615.4 276.9 615.4 276.9 615.4 276.9 619.2 280.8 623.1 284.6 626.9 292.3 630.8 300 630.8 300 630.8 303.8 630.8 303.8 634.6 307.7 634.6 315.4 634.6 319.2 634.6 319.2 634.6 323.1 634.6 323.1 634.6 323.1 634.6 323.1 634.6 326.9 638.5 338.5 646.2 346.2 657.7 346.2H715.4C730.8 346.2 742.3 334.6 738.5 319.2 738.5 319.2 738.5 319.2 738.5 319.2 738.5 319.2 738.5 315.4 738.5 315.4 738.5 307.7 734.6 303.8 734.6 296.2 734.6 292.3 734.6 292.3 730.8 288.5 730.8 273.1 730.8 269.2 726.9 261.5 726.9 261.5 726.9 257.7 723.1 257.7 719.2 250 715.4 242.3 711.5 234.6 711.5 234.6 707.7 230.8 707.7 230.8 703.8 223.1 700 219.2 696.2 215.4 696.2 211.5 692.3 211.5 692.3 207.7 688.5 203.8 684.6 196.2 680.8 192.3 680.8 192.3 676.9 188.5 676.9 188.5 669.2 180.8 665.4 176.9 657.7 169.2 657.7 169.2 653.8 169.2 653.8 165.4 650 161.5 642.3 157.7 634.6 153.8 630.8 153.8 630.8 150 626.9 150 623.1 146.2 615.4 142.3 611.5 142.3 607.7 142.3 607.7 138.5 603.8 138.5 596.2 134.6 588.5 130.8 580.8 130.8 580.8 130.8 580.8 130.8 580.8 130.8 573.1 126.9 565.4 126.9 553.8 123.1 550 123.1 550 123.1 546.2 123.1 538.5 123.1 534.6 123.1 526.9 119.2 523.1 119.2 519.2 119.2 519.2 119.2 511.5 119.2 503.8 119.2 496.2 119.2 496.2 119.2 492.3 119.2 492.3 119.2 484.6 119.2 476.9 123.1 465.4 123.1 461.5 123.1 453.8 126.9 450 126.9 450 126.9 446.2 126.9 446.2 126.9 353.8 153.8 288.5 242.3 288.5 342.3V434.6H246.2C230.8 434.6 223.1 446.2 223.1 457.7V857.7C223.1 873.1 234.6 880.8 246.2 880.8H780.8C796.2 880.8 803.8 869.2 803.8 857.7V457.7C807.7 446.2 796.2 434.6 780.8 434.6Z",
116 "width": 1000
117 },
118 "search": [
119 "unlock"
120 ]
121 },
122 {
123 "uid": "b077586592b9b69166b981325446c836",
124 "css": "delete",
125 "code": 59392,
126 "src": "custom_icons",
127 "selected": true,
128 "svg": {
129 "path": "M515.4 92.3C303.8 92.3 130.8 265.4 130.8 476.9 130.8 688.5 303.8 861.5 515.4 861.5S900 688.5 900 476.9C900 265.4 726.9 92.3 515.4 92.3ZM742.3 507.7C742.3 523.1 730.8 534.6 711.5 534.6H315.4C300 534.6 284.6 523.1 284.6 507.7V446.2C284.6 430.8 296.2 419.2 315.4 419.2H711.5C726.9 419.2 742.3 430.8 742.3 446.2V507.7Z",
130 "width": 1000
131 },
132 "search": [
133 "delete"
134 ]
135 },
136 {
137 "uid": "dca63ad885c0d6f1780a8d1d55bc2380",
138 "css": "ok",
139 "code": 59393,
140 "src": "custom_icons",
141 "selected": true,
142 "svg": {
143 "path": "M515.4 115.4C303.8 115.4 130.8 288.5 130.8 500 130.8 711.5 303.8 884.6 515.4 884.6S900 711.5 900 500C900 288.5 726.9 115.4 515.4 115.4ZM753.8 411.5L450 715.4C438.5 726.9 423.1 726.9 411.5 715.4L273.1 576.9C261.5 565.4 261.5 550 273.1 538.5L315.4 496.2C326.9 484.6 342.3 484.6 353.8 496.2L411.5 553.8C423.1 565.4 438.5 565.4 450 553.8L669.2 334.6C680.8 323.1 696.2 323.1 707.7 334.6L750 376.9C765.4 384.6 765.4 400 753.8 411.5Z",
144 "width": 1000
145 },
146 "search": [
147 "ok"
148 ]
149 },
150 {
151 "uid": "c158b3a004c055c6ad1471cd98932268",
152 "css": "down",
153 "code": 59403,
154 "src": "custom_icons",
155 "selected": true,
156 "svg": {
157 "path": "M703.8 396.2L530.8 615.4C523.1 623.1 507.7 623.1 503.8 615.4L330.8 396.2C323.1 384.6 330.8 365.4 346.2 365.4H692.3C703.8 365.4 711.5 384.6 703.8 396.2Z",
158 "width": 1000
159 },
160 "search": [
161 "arrow_down"
162 ]
163 },
164 {
165 "uid": "02f59f392ad28056845cfc04cb121f13",
166 "css": "comment",
167 "code": 59394,
168 "src": "custom_icons",
169 "selected": true,
170 "svg": {
171 "path": "M130.8 784.6V280.8C130.8 207.7 188.5 150 261.5 150H769.2C842.3 150 900 207.7 900 280.8V569.2C900 642.3 842.3 700 769.2 700H273.1C269.2 700 261.5 703.8 257.7 707.7L165.4 800C153.8 815.4 130.8 803.8 130.8 784.6ZM261.5 211.5C223.1 211.5 188.5 242.3 188.5 284.6V696.2L234.6 650C238.5 646.2 242.3 642.3 250 642.3H769.2C807.7 642.3 842.3 611.5 842.3 569.2V280.8C842.3 242.3 811.5 207.7 769.2 207.7H261.5Z",
172 "width": 1000
173 },
174 "search": [
175 "comment"
176 ]
177 },
178 {
179 "uid": "9a44b838872ca62b8aba7bbbbf67cc59",
180 "css": "feed",
181 "code": 59400,
182 "src": "custom_icons",
183 "selected": true,
184 "svg": {
185 "path": "M842.3 111.5H188.5C153.8 111.5 130.8 138.5 130.8 169.2V826.9C130.8 857.7 157.7 884.6 188.5 884.6H846.2C876.9 884.6 903.8 857.7 903.8 826.9V169.2C900 138.5 873.1 111.5 842.3 111.5ZM307.7 776.9C269.2 776.9 234.6 746.2 234.6 703.8S265.4 630.8 307.7 630.8C346.2 630.8 380.8 661.5 380.8 703.8S346.2 776.9 307.7 776.9ZM553.8 788.5C519.2 788.5 496.2 761.5 496.2 730.8 496.2 619.2 407.7 530.8 296.2 530.8 265.4 530.8 230.8 503.8 230.8 473.1 230.8 438.5 253.8 411.5 284.6 411.5L296.2 411.5C473.1 411.5 615.4 553.8 615.4 730.8 611.5 761.5 584.6 788.5 553.8 788.5ZM750 788.5C715.4 788.5 692.3 761.5 692.3 730.8 692.3 511.5 511.5 330.8 292.3 330.8 261.5 330.8 226.9 303.8 226.9 269.2 226.9 234.6 250 207.7 280.8 207.7L292.3 207.7C576.9 207.7 811.5 438.5 811.5 726.9 811.5 761.5 784.6 788.5 750 788.5Z",
186 "width": 1000
187 },
188 "search": [
189 "feed"
190 ]
191 },
192 {
193 "uid": "e0118d6f20b76d77317977ae8dc849d7",
194 "css": "left",
195 "code": 59401,
196 "src": "custom_icons",
197 "selected": true,
198 "svg": {
199 "path": "M692.3 76.9L761.5 146.2C773.1 157.7 773.1 173.1 761.5 184.6L473.1 473.1C461.5 484.6 461.5 500 473.1 511.5L769.2 807.7C780.8 819.2 780.8 834.6 769.2 846.2L700 915.4C688.5 926.9 673.1 926.9 661.5 915.4L257.7 511.5C246.2 500 246.2 484.6 257.7 473.1L653.8 76.9C665.4 65.4 680.8 65.4 692.3 76.9Z",
200 "width": 1000
201 },
202 "search": [
203 "left"
204 ]
205 },
206 {
207 "uid": "3cea97f90c8f2b0a90833855434f58de",
208 "css": "right",
209 "code": 59402,
210 "src": "custom_icons",
211 "selected": true,
212 "svg": {
213 "path": "M338.5 915.4L265.4 846.2C253.8 834.6 253.8 819.2 265.4 807.7L553.8 519.2C565.4 507.7 565.4 492.3 553.8 480.8L257.7 184.6C246.2 173.1 246.2 157.7 257.7 146.2L326.9 76.9C338.5 65.4 353.8 65.4 365.4 76.9L769.2 480.8C780.8 492.3 780.8 507.7 769.2 519.2L376.9 915.4C365.4 926.9 346.2 926.9 338.5 915.4Z",
214 "width": 1000
215 },
216 "search": [
217 "right"
218 ]
219 },
220 {
221 "uid": "820a44cb2e7fc1d0e28b1d2a8cd44cb9",
222 "css": "git",
223 "code": 59434,
224 "src": "custom_icons",
225 "selected": true,
226 "svg": {
227 "path": "M928.8 6.3H71.3C35 6.3 6.3 36.3 6.3 71.3V927.5C6.3 963.8 36.3 992.5 71.3 992.5H927.5C963.8 992.5 992.5 962.5 992.5 927.5V71.3C993.8 36.3 963.7 6.3 928.8 6.3ZM200 555C203.8 566.3 208.8 575 213.8 582.5 220 590 227.5 596.3 236.3 600 245 603.8 255 606.3 265 606.3 273.8 606.3 281.3 605 288.8 603.8 296.3 602.5 302.5 600 308.8 597.5L315 546.3H287.5C283.8 546.3 280 545 277.5 542.5 276.3 541.3 275 537.5 275 535L280 496.2H385L368.7 627.5C361.2 633.8 352.5 638.7 343.7 642.5 335 646.3 326.3 650 316.2 652.5 306.2 655 297.5 657.5 286.3 658.8 276.3 660 265 661.3 252.5 661.3 232.5 661.3 215 657.5 198.7 650 182.5 642.5 168.7 632.5 157.5 620 146.2 607.5 137.5 592.5 131.2 575 125 557.5 121.2 538.8 121.2 518.8 121.2 501.3 123.7 485 127.5 468.8 131.2 452.5 137.5 438.8 145 425 152.5 411.3 161.2 400 171.2 388.8 181.2 377.5 192.5 368.8 205 361.3 217.5 353.8 231.3 347.5 246.3 343.8 261.3 340 276.3 337.5 292.5 337.5 306.3 337.5 317.5 338.8 328.7 341.3 340 343.8 350 347.5 357.5 351.3 366.2 355 373.8 360 380 365 386.3 370 392.5 376.3 397.5 381.3L377.5 412.5C373.8 417.5 368.8 420 363.8 421.3 358.8 422.5 353.7 421.3 347.5 417.5 342.5 413.8 337.5 411.3 333.7 408.8 328.7 406.3 325 403.8 320 402.5 315 401.3 310 400 305 398.8 300 397.5 293.7 397.5 287.5 397.5 273.7 397.5 261.2 400 250 406.3 238.7 412.5 228.7 420 221.2 431.3 212.5 441.2 206.2 455 202.5 468.8 197.5 483.8 196.2 500 196.2 517.5 195 531.3 197.5 543.8 200 555ZM536.3 657.5H465L503.7 342.5H575L536.3 657.5ZM878.8 398.8H798.8L766.3 657.5H696.3L727.5 398.7H647.5L655 342.5H886.3L878.8 398.8Z",
228 "width": 1000
229 },
230 "search": [
231 "git"
232 ]
233 },
234 {
235 "uid": "ea152b092f5ad7d610de2c388553e188",
236 "css": "hg",
237 "code": 59437,
238 "src": "custom_icons",
239 "selected": true,
240 "svg": {
241 "path": "M926.6 9.2H73.9C37.9 9.2 8.7 38.5 8.7 74.4V927.1C8.7 963.1 38 992.3 73.9 992.3H926.6C962.6 992.3 991.8 963 991.8 927.1V74.4C991.8 38.4 962.6 9.2 926.6 9.2ZM444 657.4H373.5L389.8 524.1H276.7L260.4 657.4H189.9L228.6 344.2H299.1L282.8 476.4H395.9L412.2 344.2H482.7L444 657.4ZM621 555.8C624.3 566.8 629.1 576 635.3 583.5 641.5 591 648.8 596.8 657.5 600.8 666.1 604.8 675.6 606.8 686.1 606.8 694.7 606.8 702.4 606 709.3 604.5 716.2 603 722.8 600.8 729.1 598.1L735.1 546.9H708.4C704.1 546.9 700.8 545.8 698.6 543.6 696.4 541.4 695.5 538.5 695.9 534.9L700.6 496.2H805.1L788.8 627.1C780.8 633 772.5 638.1 763.9 642.3 755.3 646.6 746.3 650 736.9 652.7 727.5 655.5 717.6 657.5 707.2 658.7 696.8 660 685.7 660.6 674 660.6 654.6 660.6 637 657 621 650 605 642.9 591.3 633.1 579.9 620.7 568.5 608.2 559.7 593.5 553.5 576.4 547.2 559.3 544.1 540.9 544.1 520.9 544.1 503.6 546.1 487.1 550 471.3 554 455.6 559.6 441.1 566.9 427.8 574.2 414.5 583 402.4 593.2 391.7 603.4 381 614.9 371.8 627.4 364.2 639.9 356.6 653.5 350.7 667.9 346.6 682.4 342.6 697.6 340.5 713.5 340.5 726.8 340.5 738.9 341.7 749.7 344.2 760.5 346.6 770.2 349.9 778.8 353.9 787.4 358 795.1 362.8 801.8 368.1 808.6 373.5 814.5 379 819.7 384.8L797 413.2C793.3 418.2 788.8 421.3 783.7 422.3 778.6 423.4 773.2 422.2 767.8 418.8 762.8 415.4 758.1 412.4 753.6 409.9 749.2 407.4 744.7 405.3 740.1 403.7 735.5 402 730.7 400.8 725.6 400 720.5 399.2 714.8 398.8 708.5 398.8 694.9 398.8 682.4 401.7 671.1 407.5 659.8 413.3 650 421.5 641.9 432 633.7 442.5 627.4 455.2 622.9 469.9 618.4 484.7 616.1 501 616.1 518.7 615.9 532.5 617.6 544.8 621 555.8Z",
242 "width": 1000
243 },
244 "search": [
245 "hg"
246 ]
247 },
248 {
249 "uid": "4a842c0afb4c35dacd21da71f9fed3f1",
250 "css": "comment-add",
251 "code": 59439,
252 "src": "custom_icons",
253 "selected": true,
254 "svg": {
255 "path": "M952.4 591.9V274.9C952.4 268.4 952.3 261.9 951.8 255.4 950.7 242.9 948.2 230.6 944.1 218.8 936.5 196.6 923.8 176.2 907.3 159.6 890.8 143.1 870.6 130.4 848.5 122.7 836.6 118.6 824.2 115.9 811.6 114.8 805.3 114.2 798.9 114.2 792.6 114.2H216.9C204 114.2 191.3 114.1 178.5 116 166.3 117.9 154.4 121.2 143 125.9 121.4 134.8 101.9 148.7 86.4 166.2 70.8 183.8 59.3 205 53.1 227.7 49.7 240.1 47.9 252.8 47.6 265.6 47.3 278.7 47.6 291.8 47.6 304.9V861.8C47.6 870.7 52.5 878.6 60.5 882.5 67.3 885.9 75.6 886.2 82.4 882.7 84.8 881.5 86.9 879.7 88.8 877.8 91.1 875.5 93.4 873.2 95.6 871 100.3 866.3 105 861.6 109.7 856.9L137.9 828.6C147.3 819.2 156.6 809.9 166 800.5 175.2 791.3 184.6 782.1 193.7 772.7 197.7 768.5 201.9 764.4 207.6 762.7 210.4 761.9 213.2 761.8 216 761.8H782.7C795.5 761.8 808.3 762 821 760.1 844.8 756.5 867.7 747.3 887.3 733.3 906.2 719.9 922.1 702.1 933.2 681.8 945.1 660.2 951.5 636 952.2 611.4 952.5 604.9 952.4 598.4 952.4 591.9ZM883.4 285.1V602.5C883.4 608.8 883.4 615.1 882.5 621.4 881.7 627.5 880.2 633.6 878.1 639.4 874.4 649.4 868.8 658.7 861.7 666.7 846.6 683.6 825.1 693.8 802.5 695.1 796.3 695.4 790 695.2 783.8 695.2H207.8C201.2 695.2 194.7 695.2 188.1 695.2 185 695.2 181.8 695.2 178.8 696.1 176.2 696.9 173.9 698.2 171.8 699.9 169.6 701.7 167.6 703.7 165.6 705.7 163.3 708 161 710.3 158.7 712.6 154 717.3 149.4 721.9 144.7 726.6 135.3 736 126 745.3 116.6 754.7V270C116.6 257.8 118.8 245.7 123.7 234.6 128 224.9 134 215.9 141.5 208.4 157.5 192.4 179.6 183.3 202.2 183.3H791.5C797.6 183.3 803.7 183.3 809.7 184.2 832 187.4 852.4 199.4 866 217.4 872.8 226.4 877.7 236.7 880.5 247.6 882 253.5 882.9 259.6 883.1 265.8 883.6 272.2 883.4 278.7 883.4 285.1ZM668.8 402H538.2C534.4 402 526.7 394.3 526.7 390.5V263.7C526.7 256 519 248.3 515.2 248.3H465.3C457.6 248.3 449.9 256 449.9 259.8V390.4C449.9 394.2 442.2 401.9 438.4 401.9H311.7C304 401.9 296.3 409.6 296.3 413.4V463.3C296.3 471 304 478.7 307.8 478.7H434.5C442.2 478.7 449.9 486.4 449.9 490.2V617C449.9 624.7 457.6 632.4 461.4 632.4H511.3C519 632.4 526.7 624.7 526.7 620.9V494.1C526.7 486.4 534.4 478.7 538.2 478.7H665C672.7 478.7 680.4 471 680.4 467.2V417.3C680.3 409.6 672.6 402 668.8 402Z",
256 "width": 1000
257 },
258 "search": [
259 "comment-add"
260 ]
261 },
262 {
263 "uid": "2427f6b8d4379b9a0b41cf31780807cf",
264 "css": "comment-toggle",
265 "code": 59440,
266 "src": "custom_icons",
267 "selected": true,
268 "svg": {
269 "path": "M797.6 114.2H202.4C116.6 114.2 47.6 183.3 47.6 269V861.9C47.6 881.4 69.5 891.1 84.1 881.8 86.4 880.7 88.6 879.1 90.6 877.1L199.8 768C202.1 765.7 204.7 764 207.7 762.8 209.7 762.2 211.9 761.9 214.3 761.9H797.6C883.4 761.9 952.4 692.8 952.4 607.1V269C952.4 183.2 883.3 114.2 797.6 114.2ZM118.3 752.6V269.5C118.3 222.5 156.4 184.3 203.5 184.3H680.1C593.7 267.9 175.5 695.4 171.4 699.5L118.3 752.6Z",
270 "width": 1000
271 },
272 "search": [
273 "comment-toggle"
274 ]
275 },
276 {
277 "uid": "6533bdc16ab201eb3f3b27ce989cab33",
278 "css": "folder-open-empty",
279 "code": 61717,
280 "src": "fontawesome"
281 },
282 {
283 "uid": "d64b34fac1d9923b7d29d1550b628ecd",
284 "css": "lock",
285 "code": 59398,
286 "src": "custom_icons",
287 "selected": true,
288 "svg": {
289 "path": "M812.5 424.1H758.9V317C758.9 308 758.9 303.6 758.9 299.1 758.9 294.6 758.9 290.2 758.9 285.7 758.9 281.3 758.9 281.3 758.9 276.8 758.9 267.9 758.9 263.4 754.5 254.5 754.5 250 754.5 250 750 245.5 750 236.6 745.5 232.1 741.1 223.2 741.1 223.2 741.1 218.8 736.6 218.8 732.1 209.8 727.7 200.9 723.2 192 723.2 192 718.8 187.5 718.8 187.5 723.2 178.6 718.8 169.6 714.3 165.2 714.3 160.7 709.8 160.7 709.8 156.3 705.4 151.8 700.9 142.9 696.4 138.4 696.4 138.4 692 133.9 692 133.9 683 125 678.6 120.5 669.6 111.6 669.6 111.6 665.2 111.6 665.2 107.1 660.7 102.7 651.8 98.2 642.9 93.8 638.4 93.8 638.4 89.3 633.9 89.3 629.5 84.8 620.5 80.4 616.1 80.4 611.6 80.4 611.6 75.9 607.1 75.9 598.2 71.4 589.3 67 580.4 67 580.4 67 580.4 67 580.4 67 571.4 62.5 562.5 62.5 549.1 58 544.6 58 544.6 58 540.2 58 535.7 58 535.7 58 531.3 58 531.3 58 526.8 58 526.8 58 526.8 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 517.9 58 513.4 58 513.4 58 513.4 58 508.9 58 508.9 58 504.5 58 504.5 58 500 58 500 58 500 58 500 58 495.5 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 486.6 58 486.6 58 486.6 58 482.1 58 482.1 58 477.7 58 477.7 58 473.2 58 468.8 58 468.8 58 464.3 58 455.4 58 442 62.5 433 67 433 67 433 67 433 67 410.7 67 397.3 71.4 388.4 75.9 383.9 75.9 383.9 80.4 379.5 80.4 375 84.8 370.5 84.8 361.6 89.3 361.6 93.8 357.1 93.8 357.1 93.8 348.2 98.2 339.3 102.7 334.8 111.6 334.8 111.6 330.4 111.6 330.4 116.1 321.4 120.5 317 125 308 133.9 308 133.9 303.6 138.4 303.6 138.4 299.1 142.9 294.6 151.8 290.2 156.3 290.2 160.7 285.7 160.7 285.7 165.2 276.8 169.6 272.3 178.6 272.3 183 267.9 183 267.9 187.5 267.9 187.5 263.4 196.4 258.9 205.4 254.5 214.3 254.5 214.3 254.5 218.8 250 218.8 250 232.1 245.5 236.6 245.5 245.5 245.5 250 245.5 250 241.1 254.5 241.1 263.4 236.6 267.9 236.6 276.8 236.6 281.3 236.6 281.3 236.6 285.7 236.6 290.2 236.6 294.6 236.6 299.1 236.6 303.6 236.6 312.5 236.6 317V424.1H187.5C169.6 424.1 160.7 437.5 160.7 450.9V915.2C160.7 933 174.1 942 187.5 942H808C825.9 942 834.8 928.6 834.8 915.2V450.9C839.3 433 825.9 424.1 812.5 424.1ZM361.6 317C361.6 250 410.7 196.4 473.2 183 473.2 183 473.2 183 477.7 183 486.6 183 491.1 183 500 183 500 183 504.5 183 504.5 183 504.5 183 504.5 183 504.5 183 513.4 183 517.9 183 526.8 183 526.8 183 526.8 183 531.3 183 593.8 196.4 642.9 250 642.9 317V424.1H361.6V317Z",
290 "width": 1000
291 },
292 "search": [
293 "lock"
294 ]
295 },
296 {
297 "uid": "d95fde5e3bfeb3302efc47c90538a1c5",
298 "css": "more",
299 "code": 59410,
300 "src": "custom_icons",
301 "selected": true,
302 "svg": {
303 "path": "M546.2 415.4H446.2C430.8 415.4 419.2 426.9 419.2 442.3V542.3C419.2 557.7 430.8 569.2 446.2 569.2H546.2C561.5 569.2 573.1 557.7 573.1 542.3V442.3C573.1 426.9 561.5 415.4 546.2 415.4ZM546.2 107.7H446.2C430.8 107.7 419.2 119.2 419.2 134.6V234.6C419.2 250 430.8 261.5 446.2 261.5H546.2C561.5 261.5 573.1 250 573.1 234.6V134.6C573.1 119.2 561.5 107.7 546.2 107.7ZM546.2 723.1H446.2C430.8 723.1 419.2 734.6 419.2 750V850C419.2 865.4 430.8 876.9 446.2 876.9H546.2C561.5 876.9 573.1 865.4 573.1 850V750C573.1 734.6 561.5 723.1 546.2 723.1Z",
304 "width": 1000
305 },
306 "search": [
307 "more"
308 ]
309 },
310 {
311 "uid": "34e7772638ae3ca1bfb0a4eca2c39221",
312 "css": "merge",
313 "code": 59443,
314 "src": "custom_icons",
315 "selected": true,
316 "svg": {
317 "path": "M199.8 740.5C199.8 812.2 258.1 870.5 329.8 870.5S459.8 812.2 459.8 740.5C459.8 694.6 435.8 654.5 399.8 631.3 418.4 491.7 533.4 451.9 602.4 440.6V742.4C563.7 765 537.4 806.4 537.4 854.4 537.4 926.1 595.7 984.4 667.4 984.4S797.4 926.1 797.4 854.4C797.4 806.5 771.1 765 732.4 742.4V254.9C771.1 232.3 797.4 190.9 797.4 142.9 797.4 71.2 739.1 12.9 667.4 12.9S537.4 71.2 537.4 142.9C537.4 190.8 563.7 232.3 602.4 254.9V309.9C542.2 317.8 440.4 342.3 364.2 417.8 309.5 472.1 277.9 542.1 269.6 625.9 228.4 647.7 199.8 690.6 199.8 740.5ZM667.6 897.8C643.7 897.8 624.3 878.3 624.3 854.5S643.8 811.2 667.6 811.2C691.5 811.2 710.9 830.7 710.9 854.5S691.5 897.8 667.6 897.8ZM667.6 99.6C691.5 99.6 710.9 119 710.9 142.9S691.4 186.2 667.6 186.2C643.7 186.2 624.3 166.8 624.3 142.9S643.7 99.6 667.6 99.6ZM329.9 783.9C306 783.9 286.6 764.4 286.6 740.6S306.1 697.3 329.9 697.3C353.8 697.3 373.2 716.7 373.2 740.6S353.8 783.9 329.9 783.9Z",
318 "width": 1000
319 },
320 "search": [
321 "merge"
322 ]
323 },
324 {
325 "uid": "c95735c17a10af81448c7fed98a04546",
326 "css": "folder-open",
327 "code": 59405,
328 "src": "fontawesome"
329 },
330 {
331 "uid": "865ac833a8efcfc24a6f573705ce56b1",
332 "css": "svn",
333 "code": 59438,
334 "src": "custom_icons",
335 "selected": true,
336 "svg": {
337 "path": "M933.4 9.2H80.7C44.7 9.2 15.5 38.5 15.5 74.4V927.1C15.5 963.1 44.8 992.3 80.7 992.3H933.4C969.4 992.3 998.6 963 998.6 927.1V74.4C998.7 38.4 969.4 9.2 933.4 9.2ZM167.9 447.1C171.1 451 175.4 454.4 180.8 457.3 186.2 460.2 192.2 463 199 465.4 205.7 467.8 212.7 470.5 219.8 473.3 226.9 476.2 233.9 479.5 240.7 483.2 247.5 486.9 253.6 491.6 259 497.2 264.4 502.8 268.7 509.6 271.9 517.4 275.1 525.3 276.8 534.8 276.8 545.8 276.8 561.6 274.1 576.4 268.6 590.3 263.1 604.3 255.3 616.4 245.1 626.8 234.9 637.2 222.5 645.4 208 651.5 193.4 657.6 177 660.7 158.8 660.7 149.7 660.7 140.7 659.7 131.5 657.7S113.6 652.8 105.2 649.2C96.8 645.5 89 641.2 81.8 636.2 74.6 631.2 68.5 625.6 63.5 619.5L88.5 586.7C90.5 584.3 93 582.3 95.9 580.7 98.8 579.1 101.8 578.3 104.8 578.3 108.8 578.3 112.7 579.7 116.5 582.5 120.3 585.3 124.5 588.4 129.1 591.8 133.7 595.2 139 598.2 145.1 601.1 151.2 603.9 158.7 605.3 167.6 605.3 180.7 605.3 190.7 601.7 197.8 594.7 204.9 587.6 208.4 577.1 208.4 563.2 208.4 556.8 206.8 551.4 203.5 547.3 200.3 543.1 196 539.7 190.8 536.8 185.6 533.9 179.6 531.4 172.8 529.1 166 526.9 159.2 524.5 152.1 521.9 145.1 519.3 138.2 516.2 131.4 512.8 124.6 509.3 118.6 504.7 113.4 499 108.2 493.3 103.9 486.4 100.7 478.2 97.5 469.9 95.9 459.8 95.9 447.7 95.9 433.8 98.5 420.4 103.7 407.6 108.9 394.8 116.4 383.4 126.2 373.5 136 363.6 147.8 355.7 161.7 349.8 175.6 343.9 191.3 341 208.6 341 217.5 341 226.1 341.9 234.5 343.8S250.8 348.2 258.1 351.6C265.4 354.9 272.1 358.8 278.1 363.3 284.1 367.8 289.2 372.8 293.4 378.1L272.3 407C269.7 410.3 267.2 412.8 264.8 414.4 262.4 416 259.4 416.8 256 416.8 252.7 416.8 249.4 415.8 246.1 413.6 242.8 411.4 239.1 409.1 235 406.5 230.9 403.9 226.2 401.6 220.9 399.4 215.6 397.2 209.3 396.2 202.2 396.2 195.6 396.2 189.8 397.1 184.9 399 179.9 400.9 175.8 403.4 172.5 406.8 169.2 410.1 166.7 414 165.1 418.4 163.5 422.9 162.6 427.8 162.6 433 163.1 438.4 164.7 443.2 167.9 447.1ZM480 657.4H416.3L339.2 343.7H395.6C401.6 343.7 406.4 345.1 410 348 413.6 350.8 415.8 354.5 416.7 359L449.4 531.8C451.3 538.7 453 546.3 454.6 554.8 456.2 563.2 457.5 571.9 458.7 581 461.7 572 464.9 563.2 468.4 554.8 471.8 546.4 475.4 538.8 479.2 531.8L552.3 359C553.2 357.1 554.4 355.2 556.1 353.4 557.7 351.5 559.6 349.8 561.8 348.4 564 347 566.4 345.8 569 345 571.6 344.2 574.4 343.7 577.3 343.7H634.1L480 657.4ZM902.6 657.4H866C860.5 657.4 856.1 656.5 852.8 654.7 849.4 652.9 846.2 649.9 843.2 645.8L733.6 452.2C733.3 456.2 733 460.1 732.7 463.8 732.3 467.6 732 471.1 731.7 474.4L710.2 657.4H648.2L686.9 343.7H723.9C726.9 343.7 729.5 343.8 731.6 344 733.7 344.2 735.5 344.7 737.1 345.5 738.7 346.3 740.1 347.4 741.4 348.8S744.1 352.1 745.5 354.4L855.5 548.1C855.8 543.1 856.2 538.3 856.7 533.7 857.2 529.2 857.8 524.8 858.3 520.8L879.4 343.6H941.4L902.6 657.4Z",
338 "width": 1000
339 },
340 "search": [
341 "svn"
342 ]
343 },
344 {
345 "uid": "bbfb51903f40597f0b70fd75bc7b5cac",
346 "css": "trash",
347 "code": 61944,
348 "src": "fontawesome"
349 },
350 {
351 "uid": "f48ae54adfb27d8ada53d0fd9e34ee10",
352 "css": "trash-empty",
353 "code": 59406,
354 "src": "fontawesome"
355 },
356 {
357 "uid": "f8aa663c489bcbd6e68ec8147dca841e",
358 "css": "folder",
359 "code": 59404,
360 "src": "fontawesome"
361 },
362 {
363 "uid": "c8585e1e5b0467f28b70bce765d5840c",
364 "css": "docs",
365 "code": 61637,
366 "src": "fontawesome"
367 },
368 {
369 "uid": "1b5a5d7b7e3c71437f5a26befdd045ed",
370 "css": "doc",
371 "code": 59414,
372 "src": "fontawesome"
373 },
374 {
375 "uid": "5408be43f7c42bccee419c6be53fdef5",
376 "css": "doc-text",
377 "code": 61686,
378 "src": "fontawesome"
379 },
380 {
381 "uid": "b091a8bd0fdade174951f17d936f51e4",
382 "css": "folder-empty",
383 "code": 61716,
384 "src": "fontawesome"
385 },
386 {
387 "uid": "c08a1cde48d96cba21d8c05fa7d7feb1",
388 "css": "doc-text-inv",
389 "code": 61788,
390 "src": "fontawesome"
391 },
392 {
393 "uid": "178053298e3e5b03551d754d4b9acd8b",
394 "css": "doc-inv",
395 "code": 61787,
396 "src": "fontawesome"
397 },
398 {
399 "uid": "e99461abfef3923546da8d745372c995",
400 "css": "cog",
401 "code": 59415,
402 "src": "fontawesome"
403 },
404 {
405 "uid": "98687378abd1faf8f6af97c254eb6cd6",
406 "css": "cog-alt",
407 "code": 59416,
408 "src": "fontawesome"
409 },
410 {
411 "uid": "21b42d3c3e6be44c3cc3d73042faa216",
412 "css": "sliders",
413 "code": 61918,
414 "src": "fontawesome"
415 },
416 {
417 "uid": "559647a6f430b3aeadbecd67194451dd",
418 "css": "menu",
419 "code": 61641,
420 "src": "fontawesome"
421 },
422 {
423 "uid": "c5fd349cbd3d23e4ade333789c29c729",
424 "css": "eye",
425 "code": 59417,
426 "src": "fontawesome"
427 },
428 {
429 "uid": "7fd683b2c518ceb9e5fa6757f2276faa",
430 "css": "eye-off",
431 "code": 59418,
432 "src": "fontawesome"
433 },
434 {
435 "uid": "2e2dba0307a502a8507c1729084c7ab5",
436 "css": "cancel-circled2",
437 "code": 59419,
438 "src": "fontawesome"
439 },
440 {
441 "uid": "0f4cae16f34ae243a6144c18a003f2d8",
442 "css": "cancel-circled",
443 "code": 59420,
444 "src": "fontawesome"
445 },
446 {
447 "uid": "26613a2e6bc41593c54bead46f8c8ee3",
448 "css": "file-code",
449 "code": 61897,
450 "src": "fontawesome"
451 },
452 {
453 "uid": "5211af474d3a9848f67f945e2ccaf143",
454 "css": "remove",
455 "code": 59408,
456 "src": "fontawesome"
457 },
458 {
459 "uid": "44e04715aecbca7f266a17d5a7863c68",
460 "css": "plus",
461 "code": 59421,
462 "src": "fontawesome"
463 },
464 {
465 "uid": "4ba33d2607902cf690dd45df09774cb0",
466 "css": "plus-circled",
467 "code": 59422,
468 "src": "fontawesome"
469 },
470 {
471 "uid": "1a5cfa186647e8c929c2b17b9fc4dac1",
472 "css": "plus-squared",
473 "code": 61694,
474 "src": "fontawesome"
475 },
476 {
477 "uid": "2d3be3e856fc1e4ac067590d2ded1b07",
478 "css": "plus-squared-alt",
479 "code": 61846,
480 "src": "fontawesome"
481 },
482 {
483 "uid": "eeadb020bb75d089b25d8424aabe19e0",
484 "css": "minus-circled",
485 "code": 59423,
486 "src": "fontawesome"
487 },
488 {
489 "uid": "f755a58fb985eeb70bd47d9b31892a34",
490 "css": "minus-squared",
491 "code": 61766,
492 "src": "fontawesome"
493 },
494 {
495 "uid": "18ef25350258541e8e54148ed79845c0",
496 "css": "minus-squared-alt",
497 "code": 61767,
498 "src": "fontawesome"
499 },
500 {
501 "uid": "861ab06e455e2de3232ebef67d60d708",
502 "css": "minus",
503 "code": 59424,
504 "src": "fontawesome"
505 },
506 {
507 "uid": "e82cedfa1d5f15b00c5a81c9bd731ea2",
508 "css": "info-circled",
509 "code": 59425,
510 "src": "fontawesome"
511 },
512 {
513 "uid": "9dd9e835aebe1060ba7190ad2b2ed951",
514 "css": "search",
515 "code": 59411,
516 "src": "fontawesome"
517 },
518 {
519 "uid": "b429436ec5a518c78479d44ef18dbd60",
520 "css": "paste",
521 "code": 61674,
522 "src": "fontawesome"
523 },
524 {
525 "uid": "8772331a9fec983cdb5d72902a6f9e0e",
526 "css": "scissors",
527 "code": 59412,
528 "src": "fontawesome"
529 },
530 {
531 "uid": "9a76bc135eac17d2c8b8ad4a5774fc87",
532 "css": "download",
533 "code": 59413,
534 "src": "fontawesome"
535 },
536 {
537 "uid": "eeec3208c90b7b48e804919d0d2d4a41",
538 "css": "upload",
539 "code": 59426,
540 "src": "fontawesome"
541 },
542 {
543 "uid": "5d2d07f112b8de19f2c0dbfec3e42c05",
544 "css": "spin",
545 "code": 59448,
546 "src": "fontelico"
547 },
548 {
549 "uid": "9bd60140934a1eb9236fd7a8ab1ff6ba",
550 "css": "spin-alt",
551 "code": 59444,
552 "src": "fontelico"
553 },
554 {
555 "uid": "513ac180ff85bd275f2b736720cbbf5e",
556 "css": "home",
557 "code": 59427,
558 "src": "entypo"
559 },
560 {
561 "uid": "d4816c0845aa43767213d45574b3b145",
562 "css": "history",
563 "code": 61914,
564 "src": "fontawesome"
565 },
566 {
567 "uid": "c43db6645e7515889fc2193294f50767",
568 "css": "plus",
569 "code": 59411,
570 "src": "custom_icons",
571 "selected": false,
572 "svg": {
573 "path": "M873.1 446.2H619.2C603.8 446.2 592.3 434.6 592.3 419.2V165.4C592.3 150 580.8 138.5 565.4 138.5H465.4C450 138.5 438.5 150 438.5 165.4V419.2C438.5 434.6 426.9 446.2 411.5 446.2H157.7C142.3 446.2 130.8 457.7 130.8 473.1V573.1C130.8 588.5 142.3 600 157.7 600H411.5C426.9 600 438.5 611.5 438.5 626.9V880.8C438.5 896.2 450 907.7 465.4 907.7H565.4C580.8 907.7 592.3 896.2 592.3 880.8V626.9C592.3 611.5 603.8 600 619.2 600H873.1C888.5 600 900 588.5 900 573.1V473.1C900 457.7 888.5 446.2 873.1 446.2Z",
574 "width": 1000
575 },
576 "search": [
577 "plus"
578 ]
579 },
580 {
581 "uid": "7d7f338d90203f20c0d8d5c26091cc69",
582 "css": "minus",
583 "code": 59412,
584 "src": "custom_icons",
585 "selected": false,
586 "svg": {
587 "path": "M980 560H20C10 560 0 550 0 540V380C0 370 10 360 20 360H985C995 360 1005 370 1005 380V545C1000 550 990 560 980 560Z",
588 "width": 1000
589 },
590 "search": [
591 "minus"
592 ]
593 },
594 {
595 "uid": "4ccc61480001600f2e7e3c7dd0546c6e",
596 "css": "remove",
597 "code": 59413,
598 "src": "custom_icons",
599 "selected": false,
600 "svg": {
601 "path": "M975 140L860 25C845 10 825 10 810 25L525 310C510 325 490 325 475 310L190 25C175 10 155 10 140 25L25 140C10 155 10 175 25 190L310 475C325 490 325 510 310 525L25 810C10 825 10 845 25 860L140 975C155 990 175 990 190 975L475 690C490 675 510 675 525 690L810 975C825 990 845 990 860 975L975 860C990 845 990 825 975 810L690 525C675 510 675 490 690 475L975 190C990 180 990 155 975 140Z",
602 "width": 1000
603 },
604 "search": [
605 "remove"
606 ]
607 },
608 {
609 "uid": "b1afcccc053ecb95fbcacf06e5c0d554",
610 "css": "history",
611 "code": 59418,
612 "src": "custom_icons",
613 "selected": false,
614 "svg": {
615 "path": "",
616 "width": 1143
617 },
618 "search": [
619 "history"
620 ]
621 }
622 ]
623 } No newline at end of file
@@ -0,0 +1,78 b''
1
2 How To Build A New Icon Font
3 ============================
4
5 Welcome. Contained in this repo is everything you need to build a new custom
6 RhodeCode icon font for RhodeCode Community and Enterprise Editions. While the
7 files are here, this document references what needs to be done in the actual
8 Community Edition repository.
9
10 Creating New Icons
11 ------------------
12
13 Presumably, you're reading this because you'd like to update the icon font with
14 new icons. To create new icons, you'll want to use Illustrator. Start with an
15 empty 1000px x 1000px artboard, or use an existing .svg file if you'd like to
16 use an existing icon as a guide.
17
18 You'll need to make sure that your outlines are paths. This can be done using
19 the Shape Modes in the Pathfinder tool; see Window > Pathfinder in Illustrator
20 to build a compound image. It may happen that your image is rasterized, in which
21 case it will need to be converted to vector; check the results carefully.
22
23 .. note::
24 When adding to the existing icon collection, please maintain our
25 existing icon style.
26
27
28 Creating The Font
29 -----------------
30
31 *Fontello*
32
33 We use fontello.com to generate the font files. On the main page, there is a
34 section for clicking and dragging icons to add to a font. If you would like to
35 use the existing font icons, here you will need to drag the .json file from the
36 current fontello folder. Once it has preloaded all of the existing fonts, drag
37 any new .svg icons into this same section to add them.
38
39 Any icons which appear blank or incorrect will need to be rebuilt in Illustrator.
40 This likely means that the paths have not been generated correctly; check the
41 settings in the Pathfinder tool.
42
43 After all of the icons are loaded into fontello, resist the temptation to click
44 the big red button; there's another task to do. Each icon has a pencil button;
45 click *every* icon - including the pre-existing ones - and check the settings.
46 Each current icon should have the same hex code as that which is listed in
47 rcicons.less. The "default css name" should be its simplified name; this is what
48 will be prepended with "icon-" for the CSS classes. Also remove any unnecessary
49 information from the keywords.
50
51 Once you have checked the icons, click the button in fontello which downloads a
52 zip file of the new font.
53
54
55 Preparing The LESS Files
56 ------------------------
57
58 .. note::
59 It's a good idea to have `grunt watch` running in the background for this.
60
61 First, obviously the font files located in the unzipped folder under "font"
62 should replace the existing files in rhodecode/public/fonts/RCIcons/. While
63 doing this, check the permissions of the files that they have not changed; they
64 should be set to `chmod 644` but fontello's files may be different.
65
66 Next, you'll need to open the rcicons.css file which comes in the fontello .zip
67 and match the @font-face declaration to the one at the top of
68 rhodecode/public/css/rcicons.less, making sure to adjust the paths to
69 /fonts/RCIcons/.
70
71 In the same file, you will see the CSS for each icon. Take a quick look to make
72 sure that the existing icons haven't changed; if they have, you'll need to
73 adjust the content. Add any new icons to rcicons.less (note that similar ones
74 have been grouped together).
75
76 If you haven't yet, you'll need to run grunt to compile the LESS files; see the
77 developer documentation for instructions.
78
@@ -0,0 +1,52 b''
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.mako"/>
3
4 <%def name="title()">
5 ${_('Integrations administration')}
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
9 </%def>
10
11 <%def name="breadcrumbs_links()">
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 &raquo;
14 ${_('Integrations')}
15 </%def>
16
17 <%def name="menu_bar_nav()">
18 ${self.menu_items(active='admin')}
19 </%def>
20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='integrations')}
23 </%def>
24
25 <%def name="side_bar_nav()">
26 <li class="active">
27 <a href="${h.route_path('global_integrations_home')}">Global</a>
28 </li>
29 </%def>
30
31 <%def name="main_content()">
32 <%include file="/admin/settings/settings_${c.active}.mako"/>
33 </%def>
34
35 <%def name="main()">
36 <div class="box">
37
38 ##main
39 <div class='sidebar-col-wrapper'>
40 <div class="sidebar">
41 <ul class="nav nav-pills nav-stacked">
42 ${self.side_bar_nav()}
43 </ul>
44 </div>
45
46 <div class="main-content-auto-width">
47 ${self.main_content()}
48 </div>
49 </div>
50 </div>
51
52 </%def>
@@ -0,0 +1,68 b''
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.mako"/>
3
4 <%def name="title()">
5 ${_('Settings administration')}
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
9 </%def>
10
11 <%def name="breadcrumbs_links()"></%def>
12
13 <%def name="menu_bar_nav()">
14 ${self.menu_items(active='admin')}
15 </%def>
16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu()}
19 </%def>
20
21 <%def name="side_bar_nav()">
22
23 </%def>
24
25 <%def name="main_content()">
26 <h2>${_('Administration area')}</h2>
27
28 <table class="rctable">
29 <tr>
30 <td>${_('Repositories under administration')}</td>
31 <td class="delegated-admin-repos">${len(c.auth_user.repositories_admin)}</td>
32 <td>
33 % if c.can_create_repo:
34 <a href="${h.route_path('repo_new')}" class="">${_('Add Repository')}</a>
35 % endif
36 </td>
37 </tr>
38 <tr>
39 <td>${_('Repository groups under administration')}</td>
40 <td class="delegated-admin-repo-groups">${len(c.auth_user.repository_groups_admin)}</td>
41 <td>
42 % if c.can_create_repo_group:
43 <a href="${h.route_path('repo_group_new')}" class="">${_(u'Add Repository Group')}</a>
44 % endif
45 </td>
46 </tr>
47 <tr>
48 <td>${_('User groups under administration')}</td>
49 <td class="delegated-admin-user-groups">${len(c.auth_user.user_groups_admin)}</td>
50 <td>
51 % if c.can_create_user_group:
52 <a href="${h.route_path('user_groups_new')}" class="">${_(u'Add User Group')}</a>
53 % endif
54 </td>
55 </tr>
56 </table>
57 </%def>
58
59 <%def name="main()">
60 <div class="box">
61
62 ##main
63 <div class="main-content-auto-width">
64 ${self.main_content()}
65 </div>
66 </div>
67
68 </%def> No newline at end of file
@@ -0,0 +1,28 b''
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.mako"/>
3
4 <%def name="title()">
5 ${_('{} Artifacts').format(c.repo_name)}
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
9 </%def>
10
11 <%def name="breadcrumbs_links()"></%def>
12
13 <%def name="menu_bar_nav()">
14 ${self.menu_items(active='repositories')}
15 </%def>
16
17 <%def name="menu_bar_subnav()">
18 ${self.repo_menu(active='artifacts')}
19 </%def>
20
21 <%def name="main()">
22 <div class="box">
23
24 <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4>
25 ##<img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/repo_artifacts.png')}"/>
26 </div>
27
28 </%def>
@@ -0,0 +1,9 b''
1 <%namespace name="sourceblock" file="/codeblocks/source.mako"/>
2
3 <%def name="render_lines(lines)">
4 <table class="cb codehilite">
5 %for line_num, tokens in enumerate(lines, 1):
6 ${sourceblock.render_line(line_num, tokens)}
7 %endfor
8 </table>
9 </%def>
@@ -0,0 +1,211 b''
1 <%inherit file="/base/base.mako"/>
2
3 <%def name="title()">
4 ${_('{} Files Upload').format(c.repo_name)}
5 %if c.rhodecode_name:
6 &middot; ${h.branding(c.rhodecode_name)}
7 %endif
8 </%def>
9
10 <%def name="menu_bar_nav()">
11 ${self.menu_items(active='repositories')}
12 </%def>
13
14 <%def name="breadcrumbs_links()"></%def>
15
16 <%def name="menu_bar_subnav()">
17 ${self.repo_menu(active='files')}
18 </%def>
19
20 <%def name="main()">
21
22 <div class="box">
23 ## Template for uploads
24 <div style="display: none" id="tpl-dropzone">
25 <div class="dz-preview dz-file-preview">
26 <div class="dz-details">
27
28 <div class="dz-filename">
29 <span data-dz-name></span>
30 </div>
31 <div class="dz-filename-size">
32 <span class="dz-size" data-dz-size></span>
33
34 </div>
35
36 <div class="dz-sending" style="display: none">${_('Uploading...')}</div>
37 <div class="dz-response" style="display: none">
38 ${_('Uploaded')} 100%
39 </div>
40
41 </div>
42 <div class="dz-progress">
43 <span class="dz-upload" data-dz-uploadprogress></span>
44 </div>
45
46 <div class="dz-error-message">
47 </div>
48 </div>
49 </div>
50
51 <div class="edit-file-title">
52 <span class="title-heading">${_('Upload new file')} @ <code>${h.show_id(c.commit)}</code></span>
53 % if c.commit.branch:
54 <span class="tag branchtag">
55 <i class="icon-branch"></i> ${c.commit.branch}
56 </span>
57 % endif
58 </div>
59
60 <% form_url = h.route_path('repo_files_upload_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path) %>
61 ##${h.secure_form(form_url, id='eform', enctype="multipart/form-data", request=request)}
62 <div class="edit-file-fieldset">
63 <div class="path-items">
64 <ul>
65 <li class="breadcrumb-path">
66 <div>
67 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path='')}"><i class="icon-home"></i></a> /
68 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path)}">${c.f_path}</a> ${('/' if c.f_path else '')}
69 </div>
70 </li>
71 <li class="location-path">
72
73 </li>
74 </ul>
75 </div>
76
77 </div>
78
79 <div class="upload-form table">
80 <div id="files_data">
81
82 <div class="dropzone-wrapper" id="file-uploader">
83 <div class="dropzone-pure">
84 <div class="dz-message">
85 <i class="icon-upload" style="font-size:36px"></i></br>
86 ${_("Drag'n Drop files here or")} <span class="link">${_('Choose your files')}</span>.<br>
87 </div>
88 </div>
89
90 </div>
91 </div>
92
93 </div>
94
95 <div class="upload-form edit-file-fieldset">
96 <div class="fieldset">
97 <div class="message">
98 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
99 </div>
100 </div>
101 <div class="pull-left">
102 ${h.submit('commit_btn',_('Commit changes'), class_="btn btn-small btn-success")}
103 </div>
104 </div>
105 ##${h.end_form()}
106
107 <div class="file-upload-transaction-wrapper" style="display: none">
108 <div class="file-upload-transaction">
109 <h3>${_('Commiting...')}</h3>
110 <p>${_('Please wait while the files are being uploaded')}</p>
111 <p class="error" style="display: none">
112
113 </p>
114 <i class="icon-spin animate-spin"></i>
115 <p></p>
116 </div>
117 </div>
118
119 </div>
120
121 <script type="text/javascript">
122
123 $(document).ready(function () {
124
125 //see: https://www.dropzonejs.com/#configuration
126 myDropzone = new Dropzone("div#file-uploader", {
127 url: "${form_url}",
128 headers: {"X-CSRF-Token": CSRF_TOKEN},
129 paramName: function () {
130 return "files_upload"
131 }, // The name that will be used to transfer the file
132 parallelUploads: 20,
133 maxFiles: 20,
134 uploadMultiple: true,
135 //chunking: true, // use chunking transfer, not supported at the moment
136 //maxFilesize: 2, // in MBs
137 autoProcessQueue: false, // if false queue will not be processed automatically.
138 createImageThumbnails: false,
139 previewTemplate: document.querySelector('#tpl-dropzone').innerHTML,
140 accept: function (file, done) {
141 done();
142 },
143 init: function () {
144 this.on("addedfile", function (file) {
145
146 });
147
148 this.on("sending", function (file, xhr, formData) {
149 formData.append("message", $('#commit').val());
150 $(file.previewElement).find('.dz-sending').show();
151 });
152
153 this.on("success", function (file, response) {
154 $(file.previewElement).find('.dz-sending').hide();
155 $(file.previewElement).find('.dz-response').show();
156
157 if (response.error !== null) {
158 $('.file-upload-transaction-wrapper .error').html('ERROR: {0}'.format(response.error));
159 $('.file-upload-transaction-wrapper .error').show();
160 $('.file-upload-transaction-wrapper i').hide()
161 }
162
163 var redirect_url = response.redirect_url || '/';
164 window.location = redirect_url
165
166 });
167
168 this.on("error", function (file, errorMessage, xhr) {
169 var error = null;
170
171 if (xhr !== undefined){
172 var httpStatus = xhr.status + " " + xhr.statusText;
173 if (xhr.status >= 500) {
174 error = httpStatus;
175 }
176 }
177
178 if (error === null) {
179 error = errorMessage.error || errorMessage || httpStatus;
180 }
181
182 $(file.previewElement).find('.dz-error-message').html('ERROR: {0}'.format(error));
183 });
184 }
185 });
186
187 $('#commit_btn').on('click', function(e) {
188 e.preventDefault();
189 var button = $(this);
190 if (button.hasClass('clicked')) {
191 button.attr('disabled', true);
192 } else {
193 button.addClass('clicked');
194 }
195
196 var files = myDropzone.getQueuedFiles();
197 if (files.length === 0) {
198 alert("Missing files");
199 e.preventDefault();
200 }
201
202 $('.upload-form').hide();
203 $('.file-upload-transaction-wrapper').show();
204 myDropzone.processQueue();
205
206 });
207
208 });
209
210 </script>
211 </%def>
@@ -1,5 +1,5 b''
1 [bumpversion]
1 [bumpversion]
2 current_version = 4.16.2
2 current_version = 4.17.0
3 message = release: Bump version {current_version} to {new_version}
3 message = release: Bump version {current_version} to {new_version}
4
4
5 [bumpversion:file:rhodecode/VERSION]
5 [bumpversion:file:rhodecode/VERSION]
@@ -5,25 +5,20 b' done = false'
5 done = true
5 done = true
6
6
7 [task:rc_tools_pinned]
7 [task:rc_tools_pinned]
8 done = true
9
8
10 [task:fixes_on_stable]
9 [task:fixes_on_stable]
11 done = true
12
10
13 [task:pip2nix_generated]
11 [task:pip2nix_generated]
14 done = true
15
12
16 [task:changelog_updated]
13 [task:changelog_updated]
17 done = true
18
14
19 [task:generate_api_docs]
15 [task:generate_api_docs]
20 done = true
16
17 [task:updated_translation]
21
18
22 [release]
19 [release]
23 state = prepared
20 state = in_progress
24 version = 4.16.2
21 version = 4.17.0
25
26 [task:updated_translation]
27
22
28 [task:generate_js_routes]
23 [task:generate_js_routes]
29
24
@@ -53,3 +53,12 b' web-build:'
53
53
54 generate-pkgs:
54 generate-pkgs:
55 nix-shell pkgs/shell-generate.nix --command "pip2nix generate --licenses"
55 nix-shell pkgs/shell-generate.nix --command "pip2nix generate --licenses"
56
57 generate-js-pkgs:
58 rm -rf node_modules && \
59 nix-shell pkgs/shell-generate.nix --command "node2nix --input package.json -o pkgs/node-packages.nix -e pkgs/node-env.nix -c pkgs/node-default.nix -d --flatten --nodejs-8" && \
60 sed -i -e 's/http:\/\//https:\/\//g' pkgs/node-packages.nix
61
62 generate-license-meta:
63 nix-build pkgs/license-generate.nix -o result-license && \
64 cat result-license/licenses.json | python -m json.tool > rhodecode/config/licenses.json No newline at end of file
@@ -133,6 +133,11 b' rhodecode.api.url = /_admin/api'
133 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
133 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
134 #rhodecode.encrypted_values.strict = false
134 #rhodecode.encrypted_values.strict = false
135
135
136 ## Pick algorithm for encryption. Either fernet (more secure) or aes (default)
137 ## fernet is safer, and we strongly recommend switching to it.
138 ## Due to backward compatibility aes is used as default.
139 #rhodecode.encrypted_values.algorithm = fernet
140
136 ## return gzipped responses from RhodeCode (static files/application)
141 ## return gzipped responses from RhodeCode (static files/application)
137 gzip_responses = false
142 gzip_responses = false
138
143
@@ -374,6 +379,10 b' rc_cache.cache_repo_longterm.max_size = '
374 beaker.session.type = file
379 beaker.session.type = file
375 beaker.session.data_dir = %(here)s/data/sessions
380 beaker.session.data_dir = %(here)s/data/sessions
376
381
382 ## redis sessions
383 #beaker.session.type = ext:redis
384 #beaker.session.url = redis://127.0.0.1:6379/2
385
377 ## db based session, fast, and allows easy management over logged in users
386 ## db based session, fast, and allows easy management over logged in users
378 #beaker.session.type = ext:database
387 #beaker.session.type = ext:database
379 #beaker.session.table_name = db_session
388 #beaker.session.table_name = db_session
@@ -30,10 +30,12 b" loglevel = 'debug'"
30 # SECURITY
30 # SECURITY
31
31
32 # The maximum size of HTTP request line in bytes.
32 # The maximum size of HTTP request line in bytes.
33 limit_request_line = 4094
33 # 0 for unlimited
34 limit_request_line = 0
34
35
35 # Limit the number of HTTP headers fields in a request.
36 # Limit the number of HTTP headers fields in a request.
36 limit_request_fields = 1024
37 # By default this value is 100 and can’t be larger than 32768.
38 limit_request_fields = 10240
37
39
38 # Limit the allowed size of an HTTP request header field.
40 # Limit the allowed size of an HTTP request header field.
39 # Value is a positive number or 0.
41 # Value is a positive number or 0.
@@ -108,6 +108,11 b' use = egg:rhodecode-enterprise-ce'
108 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
108 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
109 #rhodecode.encrypted_values.strict = false
109 #rhodecode.encrypted_values.strict = false
110
110
111 ## Pick algorithm for encryption. Either fernet (more secure) or aes (default)
112 ## fernet is safer, and we strongly recommend switching to it.
113 ## Due to backward compatibility aes is used as default.
114 #rhodecode.encrypted_values.algorithm = fernet
115
111 ## return gzipped responses from RhodeCode (static files/application)
116 ## return gzipped responses from RhodeCode (static files/application)
112 gzip_responses = false
117 gzip_responses = false
113
118
@@ -349,6 +354,10 b' rc_cache.cache_repo_longterm.max_size = '
349 beaker.session.type = file
354 beaker.session.type = file
350 beaker.session.data_dir = %(here)s/data/sessions
355 beaker.session.data_dir = %(here)s/data/sessions
351
356
357 ## redis sessions
358 #beaker.session.type = ext:redis
359 #beaker.session.url = redis://127.0.0.1:6379/2
360
352 ## db based session, fast, and allows easy management over logged in users
361 ## db based session, fast, and allows easy management over logged in users
353 #beaker.session.type = ext:database
362 #beaker.session.type = ext:database
354 #beaker.session.table_name = db_session
363 #beaker.session.table_name = db_session
@@ -191,7 +191,7 b' let'
191 # check required files
191 # check required files
192 STATIC_CHECK="/robots.txt /502.html
192 STATIC_CHECK="/robots.txt /502.html
193 /js/scripts.js /js/rhodecode-components.js
193 /js/scripts.js /js/rhodecode-components.js
194 /css/style.css /css/style-polymer.css"
194 /css/style.css /css/style-polymer.css /css/style-ipython.css"
195
195
196 for file in $STATIC_CHECK;
196 for file in $STATIC_CHECK;
197 do
197 do
@@ -29,7 +29,7 b' 1. Go to :menuselection:`Admin --> Repos'
29 beside the |repo| to which you wish to add extra fields.
29 beside the |repo| to which you wish to add extra fields.
30 2. On the |repo| settings page, select the :guilabel:`Extra fields` tab.
30 2. On the |repo| settings page, select the :guilabel:`Extra fields` tab.
31
31
32 .. image:: ../images/extra-repo-fields.png
32 .. image:: ../../images/extra-repo-fields.png
33
33
34 The most important is the `New field key` variable which under the value will
34 The most important is the `New field key` variable which under the value will
35 be stored. It needs to be unique for each repository. The label and description
35 be stored. It needs to be unique for each repository. The label and description
1 NO CONTENT: file renamed from docs/admin/repo-hooks.rst to docs/admin/repo_admin/repo-hooks.rst
NO CONTENT: file renamed from docs/admin/repo-hooks.rst to docs/admin/repo_admin/repo-hooks.rst
1 NO CONTENT: file renamed from docs/admin/repo-issue-tracker.rst to docs/admin/repo_admin/repo-issue-tracker.rst
NO CONTENT: file renamed from docs/admin/repo-issue-tracker.rst to docs/admin/repo_admin/repo-issue-tracker.rst
1 NO CONTENT: file renamed from docs/admin/repo-perm-steps.rst to docs/admin/repo_admin/repo-perm-steps.rst
NO CONTENT: file renamed from docs/admin/repo-perm-steps.rst to docs/admin/repo_admin/repo-perm-steps.rst
1 NO CONTENT: file renamed from docs/admin/repo-vcs.rst to docs/admin/repo_admin/repo-vcs.rst
NO CONTENT: file renamed from docs/admin/repo-vcs.rst to docs/admin/repo_admin/repo-vcs.rst
1 NO CONTENT: file renamed from docs/admin/restore-deleted-repositories.rst to docs/admin/repo_admin/restore-deleted-repositories.rst
NO CONTENT: file renamed from docs/admin/restore-deleted-repositories.rst to docs/admin/repo_admin/restore-deleted-repositories.rst
@@ -16,19 +16,17 b' The following are the most common system'
16
16
17 .. toctree::
17 .. toctree::
18
18
19 config-files-overview
19 system_admin/config-files-overview
20 vcs-server
20 system_admin/vcs-server
21 svn-http
21 system_admin/svn-http
22 svn-path-permissions
22 system_admin/svn-path-permissions
23 gunicorn-ssl-support
23 system_admin/gunicorn-ssl-support
24 apache-config
24 system_admin/apache-config
25 nginx-config
25 system_admin/nginx-config
26 backup-restore
26 system_admin/backup-restore
27 tuning-rhodecode
27 system_admin/tuning-rhodecode
28 indexing
28 system_admin/indexing
29 reset-information
29 system_admin/reset-information
30 enable-debug
30 system_admin/enable-debug
31 admin-tricks
31 system_admin/admin-tricks
32 cleanup-cmds
32 system_admin/cleanup-cmds
33 restore-deleted-repositories
34
@@ -57,7 +57,7 b' 2. To add a message that will be display'
57 3. Select :guilabel:`Save`, and you will see the message once your page
57 3. Select :guilabel:`Save`, and you will see the message once your page
58 refreshes.
58 refreshes.
59
59
60 .. image:: ../images/server-wide-announcement.png
60 .. image:: ../../images/server-wide-announcement.png
61 :alt: Server Wide Announcement
61 :alt: Server Wide Announcement
62
62
63 .. _md-rst:
63 .. _md-rst:
@@ -207,7 +207,7 b' 2. Restart the |RCE| instance and check '
207 Instance "enterprise-2" successfully stopped.
207 Instance "enterprise-2" successfully stopped.
208 Instance "enterprise-2" successfully started.
208 Instance "enterprise-2" successfully started.
209
209
210 .. image:: ../images/language.png
210 .. image:: ../../images/language.png
211
211
212 .. _set-repo-pub:
212 .. _set-repo-pub:
213
213
@@ -239,3 +239,26 b' following URL: ``{instance-URL}/_admin/p'
239
239
240 .. _Markdown: http://daringfireball.net/projects/markdown/
240 .. _Markdown: http://daringfireball.net/projects/markdown/
241 .. _reStructured Text: http://docutils.sourceforge.net/docs/index.html
241 .. _reStructured Text: http://docutils.sourceforge.net/docs/index.html
242
243
244 Unarchiving a repository
245 ^^^^^^^^^^^^^^^^^^^^^^^^^
246
247 Archive operation for the repository is similar as delete. Archive keeps the data for future references
248 but makes the repository read-only. After archiving the repository it shouldn't be modified in any way.
249 This is why repository settings are disabled for an archived repository.
250
251 If there's a need for unarchiving a repository for some reasons, the interactive
252 ishell interface should be used.
253
254 .. code-block:: bash
255
256 # Open iShell from the terminal
257 $ rccontrol ishell enterprise-1/community-1
258
259 .. code-block:: python
260
261 # Set repository as un-archived
262 In [1]: repo = Repository.get_by_repo_name('SOME_REPO_NAME')
263 In [2]: repo.archived = False
264 In [3]: Session().add(repo);Session().commit()
@@ -8,7 +8,7 b' the information in the following section'
8
8
9 .. toctree::
9 .. toctree::
10
10
11 apache-conf-example
11 apache/apache-conf-example
12 apache-diffie-hellman
12 apache/apache-diffie-hellman
13 apache-subdirectory
13 apache/apache-subdirectory
14 apache-wsgi-coding
14 apache/apache-wsgi-coding
@@ -66,14 +66,18 b' Below config if for an Apache Reverse Pr'
66 # Directive to properly generate url (clone url) for RhodeCode
66 # Directive to properly generate url (clone url) for RhodeCode
67 ProxyPreserveHost On
67 ProxyPreserveHost On
68
68
69 # It allows request bodies to be sent to the backend using chunked transfer encoding.
70 SetEnv proxy-sendchunked 1
71
72 # Increase headers size for large Mercurial headers sent with many branches
73 LimitRequestLine 16380
74
69 # Url to running RhodeCode instance. This is shown as `- URL:` when
75 # Url to running RhodeCode instance. This is shown as `- URL:` when
70 # running rccontrol status.
76 # running rccontrol status.
77
71 ProxyPass / http://127.0.0.1:10002/ timeout=7200 Keepalive=On
78 ProxyPass / http://127.0.0.1:10002/ timeout=7200 Keepalive=On
72 ProxyPassReverse / http://127.0.0.1:10002/
79 ProxyPassReverse / http://127.0.0.1:10002/
73
80
74 # Increase headers for large Mercurial headers
75 LimitRequestLine 16380
76
77 # strict http prevents from https -> http downgrade
81 # strict http prevents from https -> http downgrade
78 Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
82 Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
79
83
1 NO CONTENT: file renamed from docs/admin/apache-diffie-hellman.rst to docs/admin/system_admin/apache/apache-diffie-hellman.rst
NO CONTENT: file renamed from docs/admin/apache-diffie-hellman.rst to docs/admin/system_admin/apache/apache-diffie-hellman.rst
1 NO CONTENT: file renamed from docs/admin/apache-subdirectory.rst to docs/admin/system_admin/apache/apache-subdirectory.rst
NO CONTENT: file renamed from docs/admin/apache-subdirectory.rst to docs/admin/system_admin/apache/apache-subdirectory.rst
1 NO CONTENT: file renamed from docs/admin/apache-wsgi-coding.rst to docs/admin/system_admin/apache/apache-wsgi-coding.rst
NO CONTENT: file renamed from docs/admin/apache-wsgi-coding.rst to docs/admin/system_admin/apache/apache-wsgi-coding.rst
1 NO CONTENT: file renamed from docs/admin/backup-restore.rst to docs/admin/system_admin/backup-restore.rst
NO CONTENT: file renamed from docs/admin/backup-restore.rst to docs/admin/system_admin/backup-restore.rst
1 NO CONTENT: file renamed from docs/admin/cleanup-cmds.rst to docs/admin/system_admin/cleanup-cmds.rst
NO CONTENT: file renamed from docs/admin/cleanup-cmds.rst to docs/admin/system_admin/cleanup-cmds.rst
1 NO CONTENT: file renamed from docs/admin/config-files-overview.rst to docs/admin/system_admin/config-files-overview.rst
NO CONTENT: file renamed from docs/admin/config-files-overview.rst to docs/admin/system_admin/config-files-overview.rst
1 NO CONTENT: file renamed from docs/admin/enable-debug.rst to docs/admin/system_admin/enable-debug.rst
NO CONTENT: file renamed from docs/admin/enable-debug.rst to docs/admin/system_admin/enable-debug.rst
1 NO CONTENT: file renamed from docs/admin/gunicorn-ssl-support.rst to docs/admin/system_admin/gunicorn-ssl-support.rst
NO CONTENT: file renamed from docs/admin/gunicorn-ssl-support.rst to docs/admin/system_admin/gunicorn-ssl-support.rst
1 NO CONTENT: file renamed from docs/admin/indexing.rst to docs/admin/system_admin/indexing.rst
NO CONTENT: file renamed from docs/admin/indexing.rst to docs/admin/system_admin/indexing.rst
@@ -8,7 +8,7 b' the information in the following section'
8
8
9 .. toctree::
9 .. toctree::
10
10
11 nginx-config-example
11 nginx/nginx-config-example
12 nginx-diffie-hellman
12 nginx/nginx-diffie-hellman
13 nginx-proxy-conf
13 nginx/nginx-proxy-conf
14 nginx-url-prefix
14 nginx/nginx-url-prefix
1 NO CONTENT: file renamed from docs/admin/nginx-config-example.rst to docs/admin/system_admin/nginx/nginx-config-example.rst
NO CONTENT: file renamed from docs/admin/nginx-config-example.rst to docs/admin/system_admin/nginx/nginx-config-example.rst
1 NO CONTENT: file renamed from docs/admin/nginx-diffie-hellman.rst to docs/admin/system_admin/nginx/nginx-diffie-hellman.rst
NO CONTENT: file renamed from docs/admin/nginx-diffie-hellman.rst to docs/admin/system_admin/nginx/nginx-diffie-hellman.rst
1 NO CONTENT: file renamed from docs/admin/nginx-proxy-conf.rst to docs/admin/system_admin/nginx/nginx-proxy-conf.rst
NO CONTENT: file renamed from docs/admin/nginx-proxy-conf.rst to docs/admin/system_admin/nginx/nginx-proxy-conf.rst
1 NO CONTENT: file renamed from docs/admin/nginx-url-prefix.rst to docs/admin/system_admin/nginx/nginx-url-prefix.rst
NO CONTENT: file renamed from docs/admin/nginx-url-prefix.rst to docs/admin/system_admin/nginx/nginx-url-prefix.rst
1 NO CONTENT: file renamed from docs/admin/reset-information.rst to docs/admin/system_admin/reset-information.rst
NO CONTENT: file renamed from docs/admin/reset-information.rst to docs/admin/system_admin/reset-information.rst
1 NO CONTENT: file renamed from docs/admin/svn-http.rst to docs/admin/system_admin/svn-http.rst
NO CONTENT: file renamed from docs/admin/svn-http.rst to docs/admin/system_admin/svn-http.rst
1 NO CONTENT: file renamed from docs/admin/svn-path-permissions.rst to docs/admin/system_admin/svn-path-permissions.rst
NO CONTENT: file renamed from docs/admin/svn-path-permissions.rst to docs/admin/system_admin/svn-path-permissions.rst
@@ -8,14 +8,14 b' may find some of the following methods u'
8
8
9 .. toctree::
9 .. toctree::
10
10
11 tuning-gunicorn
11 tuning/tuning-gunicorn
12 tuning-vcs-memory-cache
12 tuning/tuning-vcs-memory-cache
13 tuning-user-sessions-performance
13 tuning/tuning-user-sessions-performance
14 tuning-increase-db-performance
14 tuning/tuning-increase-db-performance
15 tuning-scale-horizontally-cluster
15 tuning/tuning-scale-horizontally-cluster
16 tuning-mount-cache-memory
16 tuning/tuning-mount-cache-memory
17 tuning-change-encoding
17 tuning/tuning-change-encoding
18 tuning-change-large-file-dir
18 tuning/tuning-change-large-file-dir
19 tuning-change-lfs-dir
19 tuning/tuning-change-lfs-dir
20 tuning-hg-auth-loop
20 tuning/tuning-hg-auth-loop
21
21
1 NO CONTENT: file renamed from docs/admin/tuning-change-encoding.rst to docs/admin/system_admin/tuning/tuning-change-encoding.rst
NO CONTENT: file renamed from docs/admin/tuning-change-encoding.rst to docs/admin/system_admin/tuning/tuning-change-encoding.rst
1 NO CONTENT: file renamed from docs/admin/tuning-change-large-file-dir.rst to docs/admin/system_admin/tuning/tuning-change-large-file-dir.rst
NO CONTENT: file renamed from docs/admin/tuning-change-large-file-dir.rst to docs/admin/system_admin/tuning/tuning-change-large-file-dir.rst
1 NO CONTENT: file renamed from docs/admin/tuning-change-lfs-dir.rst to docs/admin/system_admin/tuning/tuning-change-lfs-dir.rst
NO CONTENT: file renamed from docs/admin/tuning-change-lfs-dir.rst to docs/admin/system_admin/tuning/tuning-change-lfs-dir.rst
@@ -42,7 +42,7 b' 2. In the ``[server:main]`` section, cha'
42 ## restarted, could prevent memory leaks
42 ## restarted, could prevent memory leaks
43 max_requests = 1000
43 max_requests = 1000
44 max_requests_jitter = 30
44 max_requests_jitter = 30
45 ## amount of time a worker can spend with handling a request before it
45 ## amount of time a worker can spend with handling a request tuning-change-lfs-dir.before it
46 ## gets killed and restarted. Set to 6hrs
46 ## gets killed and restarted. Set to 6hrs
47 timeout = 21600
47 timeout = 21600
48
48
1 NO CONTENT: file renamed from docs/admin/tuning-hg-auth-loop.rst to docs/admin/system_admin/tuning/tuning-hg-auth-loop.rst
NO CONTENT: file renamed from docs/admin/tuning-hg-auth-loop.rst to docs/admin/system_admin/tuning/tuning-hg-auth-loop.rst
1 NO CONTENT: file renamed from docs/admin/tuning-increase-db-performance.rst to docs/admin/system_admin/tuning/tuning-increase-db-performance.rst
NO CONTENT: file renamed from docs/admin/tuning-increase-db-performance.rst to docs/admin/system_admin/tuning/tuning-increase-db-performance.rst
1 NO CONTENT: file renamed from docs/admin/tuning-mount-cache-memory.rst to docs/admin/system_admin/tuning/tuning-mount-cache-memory.rst
NO CONTENT: file renamed from docs/admin/tuning-mount-cache-memory.rst to docs/admin/system_admin/tuning/tuning-mount-cache-memory.rst
1 NO CONTENT: file renamed from docs/admin/tuning-scale-horizontally-cluster.rst to docs/admin/system_admin/tuning/tuning-scale-horizontally-cluster.rst
NO CONTENT: file renamed from docs/admin/tuning-scale-horizontally-cluster.rst to docs/admin/system_admin/tuning/tuning-scale-horizontally-cluster.rst
1 NO CONTENT: file renamed from docs/admin/tuning-user-sessions-performance.rst to docs/admin/system_admin/tuning/tuning-user-sessions-performance.rst
NO CONTENT: file renamed from docs/admin/tuning-user-sessions-performance.rst to docs/admin/system_admin/tuning/tuning-user-sessions-performance.rst
1 NO CONTENT: file renamed from docs/admin/tuning-vcs-memory-cache.rst to docs/admin/system_admin/tuning/tuning-vcs-memory-cache.rst
NO CONTENT: file renamed from docs/admin/tuning-vcs-memory-cache.rst to docs/admin/system_admin/tuning/tuning-vcs-memory-cache.rst
1 NO CONTENT: file renamed from docs/admin/vcs-server.rst to docs/admin/system_admin/vcs-server.rst
NO CONTENT: file renamed from docs/admin/vcs-server.rst to docs/admin/system_admin/vcs-server.rst
@@ -13,11 +13,12 b' permissions applied to it; |perm|.'
13
13
14 .. toctree::
14 .. toctree::
15
15
16 public-access
16 user_admin/public-access
17 default-user-perms
17 user_admin/default-user-perms
18 adding-anonymous-user
18 user_admin/adding-anonymous-user
19 adding-new-user
19 user_admin/adding-new-user
20 setting-default-permissions
20 user_admin/setting-default-permissions
21 setting-usergroup-permissions
21 user_admin/setting-usergroup-permissions
22 user_admin/user-admin-tasks
22
23
23 .. |perm| replace:: **None**, **Read**, **Write**, or **Admin** No newline at end of file
24 .. |perm| replace:: **None**, **Read**, **Write**, or **Admin**
1 NO CONTENT: file renamed from docs/admin/adding-anonymous-user.rst to docs/admin/user_admin/adding-anonymous-user.rst
NO CONTENT: file renamed from docs/admin/adding-anonymous-user.rst to docs/admin/user_admin/adding-anonymous-user.rst
1 NO CONTENT: file renamed from docs/admin/adding-new-user.rst to docs/admin/user_admin/adding-new-user.rst
NO CONTENT: file renamed from docs/admin/adding-new-user.rst to docs/admin/user_admin/adding-new-user.rst
1 NO CONTENT: file renamed from docs/admin/default-user-perms.rst to docs/admin/user_admin/default-user-perms.rst
NO CONTENT: file renamed from docs/admin/default-user-perms.rst to docs/admin/user_admin/default-user-perms.rst
1 NO CONTENT: file renamed from docs/admin/public-access.rst to docs/admin/user_admin/public-access.rst
NO CONTENT: file renamed from docs/admin/public-access.rst to docs/admin/user_admin/public-access.rst
1 NO CONTENT: file renamed from docs/admin/setting-default-permissions.rst to docs/admin/user_admin/setting-default-permissions.rst
NO CONTENT: file renamed from docs/admin/setting-default-permissions.rst to docs/admin/user_admin/setting-default-permissions.rst
1 NO CONTENT: file renamed from docs/admin/setting-usergroup-permissions.rst to docs/admin/user_admin/setting-usergroup-permissions.rst
NO CONTENT: file renamed from docs/admin/setting-usergroup-permissions.rst to docs/admin/user_admin/setting-usergroup-permissions.rst
@@ -204,6 +204,7 b' are not required in args.'
204 methods/pull-request-methods
204 methods/pull-request-methods
205 methods/repo-methods
205 methods/repo-methods
206 methods/repo-group-methods
206 methods/repo-group-methods
207 methods/search-methods
207 methods/server-methods
208 methods/server-methods
208 methods/user-methods
209 methods/user-methods
209 methods/user-group-methods
210 methods/user-group-methods
@@ -462,6 +462,7 b' get_repo_file'
462 :param cache: Use internal caches for fetching files. If disabled fetching
462 :param cache: Use internal caches for fetching files. If disabled fetching
463 files is slower but more memory efficient
463 files is slower but more memory efficient
464 :type cache: Optional(bool)
464 :type cache: Optional(bool)
465
465 Example output:
466 Example output:
466
467
467 .. code-block:: bash
468 .. code-block:: bash
@@ -532,9 +533,7 b' get_repo_nodes'
532 result: [
533 result: [
533 {
534 {
534 "binary": false,
535 "binary": false,
535 "content": "File line
536 "content": "File line",
536 Line2
537 ",
538 "extension": "md",
537 "extension": "md",
539 "lines": 2,
538 "lines": 2,
540 "md5": "059fa5d29b19c0657e384749480f6422",
539 "md5": "059fa5d29b19c0657e384749480f6422",
@@ -32,9 +32,9 b' The most important this id needs to be u'
32
32
33 In [1]: saml2user = {
33 In [1]: saml2user = {
34 ...: # OneLogin, uses externalID available to read from in the UI
34 ...: # OneLogin, uses externalID available to read from in the UI
35 ...: 123: {'id: '48253211'},
35 ...: 123: {'id': '48253211'},
36 ...: # for Google/DuoSecurity email is also an option for unique ID
36 ...: # for Google/DuoSecurity email is also an option for unique ID
37 ...: 124: {'id: 'email@domain.com'},
37 ...: 124: {'id': 'email@domain.com'},
38 ...: }
38 ...: }
39
39
40
40
@@ -70,7 +70,7 b' Enter in the ishell prompt'
70 ...: new_external_identity.external_id = external_id
70 ...: new_external_identity.external_id = external_id
71 ...: new_external_identity.external_username = '{}-saml-{}'.format(user.username, user.user_id)
71 ...: new_external_identity.external_username = '{}-saml-{}'.format(user.username, user.user_id)
72 ...: new_external_identity.provider_name = provider
72 ...: new_external_identity.provider_name = provider
73 ...: new_external_identity.local_user_id = user_id
73 ...: new_external_identity.local_user_id = user.user_id
74 ...: new_external_identity.access_token = ''
74 ...: new_external_identity.access_token = ''
75 ...: new_external_identity.token_secret = ''
75 ...: new_external_identity.token_secret = ''
76 ...: new_external_identity.alt_token = ''
76 ...: new_external_identity.alt_token = ''
@@ -46,7 +46,7 b' and commit files and |repos| while manag'
46 nix/default-env
46 nix/default-env
47 admin/system-admin
47 admin/system-admin
48 admin/user-admin
48 admin/user-admin
49 admin/setting-repo-perms
49 admin/repo-admin
50 admin/security-tips
50 admin/security-tips
51 auth/auth
51 auth/auth
52 issue-trackers/issue-trackers
52 issue-trackers/issue-trackers
@@ -64,6 +64,13 b' and commit files and |repos| while manag'
64
64
65 .. toctree::
65 .. toctree::
66 :maxdepth: 1
66 :maxdepth: 1
67 :caption: User Documentation
68
69 usage/basic-usage
70 tutorials/tutorials
71
72 .. toctree::
73 :maxdepth: 1
67 :caption: Developer Documentation
74 :caption: Developer Documentation
68
75
69 api/api
76 api/api
@@ -73,13 +80,6 b' and commit files and |repos| while manag'
73
80
74 .. toctree::
81 .. toctree::
75 :maxdepth: 1
82 :maxdepth: 1
76 :caption: User Documentation
77
78 usage/basic-usage
79 tutorials/tutorials
80
81 .. toctree::
82 :maxdepth: 1
83 :caption: About
83 :caption: About
84
84
85 known-issues/known-issues
85 known-issues/known-issues
@@ -9,6 +9,7 b' Release Notes'
9 .. toctree::
9 .. toctree::
10 :maxdepth: 1
10 :maxdepth: 1
11
11
12 release-notes-4.17.0.rst
12 release-notes-4.16.2.rst
13 release-notes-4.16.2.rst
13 release-notes-4.16.1.rst
14 release-notes-4.16.1.rst
14 release-notes-4.16.0.rst
15 release-notes-4.16.0.rst
@@ -35,6 +35,7 b''
35 "<%= dirs.js.node_modules %>/moment/min/moment.min.js",
35 "<%= dirs.js.node_modules %>/moment/min/moment.min.js",
36 "<%= dirs.js.node_modules %>/clipboard/dist/clipboard.min.js",
36 "<%= dirs.js.node_modules %>/clipboard/dist/clipboard.min.js",
37 "<%= dirs.js.node_modules %>/favico.js/favico-0.3.10.min.js",
37 "<%= dirs.js.node_modules %>/favico.js/favico-0.3.10.min.js",
38 "<%= dirs.js.node_modules %>/dropzone/dist/dropzone.js",
38 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/sticky-sidebar.min.js",
39 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/sticky-sidebar.min.js",
39 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/jquery.sticky-sidebar.min.js",
40 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/jquery.sticky-sidebar.min.js",
40 "<%= dirs.js.node_modules %>/waypoints/lib/noframework.waypoints.min.js",
41 "<%= dirs.js.node_modules %>/waypoints/lib/noframework.waypoints.min.js",
@@ -107,7 +108,8 b''
107 },
108 },
108 "files": {
109 "files": {
109 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
110 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
110 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
111 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less",
112 "<%= dirs.css.dest %>/style-ipython.css": "<%= dirs.css.src %>/ipython.less"
111 }
113 }
112 },
114 },
113 "production": {
115 "production": {
@@ -118,7 +120,8 b''
118 },
120 },
119 "files": {
121 "files": {
120 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
122 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
121 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
123 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less",
124 "<%= dirs.css.dest %>/style-ipython.css": "<%= dirs.css.src %>/ipython.less"
122 }
125 }
123 },
126 },
124 "components": {
127 "components": {
@@ -13,6 +13,7 b''
13 "clipboard": "^2.0.1",
13 "clipboard": "^2.0.1",
14 "exports-loader": "^0.6.4",
14 "exports-loader": "^0.6.4",
15 "favico.js": "^0.3.10",
15 "favico.js": "^0.3.10",
16 "dropzone": "^5.5.0",
16 "grunt": "^0.4.5",
17 "grunt": "^0.4.5",
17 "grunt-cli": "^1.3.1",
18 "grunt-cli": "^1.3.1",
18 "grunt-contrib-concat": "^0.5.1",
19 "grunt-contrib-concat": "^0.5.1",
@@ -1,3 +1,3 b''
1 [pip2nix]
1 [pip2nix]
2 requirements = ., -r ./requirements.txt
2 requirements = ., -r ./requirements.txt, -r ./requirements_pinned.txt
3 output = ./pkgs/python-packages.nix
3 output = ./pkgs/python-packages.nix
This diff has been collapsed as it changes many lines, (990 lines changed) Show them Hide them
@@ -166,13 +166,13 b' let'
166 sha512 = "dgOe12GyCF1VZBLUQqnzGWlf3xb255FajNCVB1VFj/AtskYtoamnafa7m3a+1vs+C8qbg4Benn5KwgxVDSW4cg==";
166 sha512 = "dgOe12GyCF1VZBLUQqnzGWlf3xb255FajNCVB1VFj/AtskYtoamnafa7m3a+1vs+C8qbg4Benn5KwgxVDSW4cg==";
167 };
167 };
168 };
168 };
169 "@polymer/paper-spinner-3.0.1" = {
169 "@polymer/paper-spinner-3.0.2" = {
170 name = "_at_polymer_slash_paper-spinner";
170 name = "_at_polymer_slash_paper-spinner";
171 packageName = "@polymer/paper-spinner";
171 packageName = "@polymer/paper-spinner";
172 version = "3.0.1";
172 version = "3.0.2";
173 src = fetchurl {
173 src = fetchurl {
174 url = "https://registry.npmjs.org/@polymer/paper-spinner/-/paper-spinner-3.0.1.tgz";
174 url = "https://registry.npmjs.org/@polymer/paper-spinner/-/paper-spinner-3.0.2.tgz";
175 sha512 = "MYIU6qWZnhZ5yNFOBzROPgBteGfxKEnDZ6bCgjrvUtJkBuQEz0MQZzSE/zmZc0oaJ9u5QK5xAFuYdudsGv7+sQ==";
175 sha512 = "XUzu8/4NH+pnNZUTI2MxtOKFAr0EOsW7eGhTg3VBhTh7DDW/q3ewzwYRWnqNJokX9BEnxKMiXXaIeTEBq4k2dw==";
176 };
176 };
177 };
177 };
178 "@polymer/paper-styles-3.0.1" = {
178 "@polymer/paper-styles-3.0.1" = {
@@ -211,13 +211,13 b' let'
211 sha512 = "yiUk09opTEnE1lK+tb501ENb+yQBi4p++Ep0eGJAHesVYKVMPNgPphVKkIizkDaU+n0SE+zXfTsRbYyOMDYXSg==";
211 sha512 = "yiUk09opTEnE1lK+tb501ENb+yQBi4p++Ep0eGJAHesVYKVMPNgPphVKkIizkDaU+n0SE+zXfTsRbYyOMDYXSg==";
212 };
212 };
213 };
213 };
214 "@polymer/polymer-3.1.0" = {
214 "@polymer/polymer-3.2.0" = {
215 name = "_at_polymer_slash_polymer";
215 name = "_at_polymer_slash_polymer";
216 packageName = "@polymer/polymer";
216 packageName = "@polymer/polymer";
217 version = "3.1.0";
217 version = "3.2.0";
218 src = fetchurl {
218 src = fetchurl {
219 url = "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.1.0.tgz";
219 url = "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.2.0.tgz";
220 sha512 = "hwN8IMERsFATz/9dSMxYHL+84J9uBkPuuarxJWlTsppZ4CAYTZKnepBfNrKoyNsafBmA3yXBiiKPPf+fJtza7A==";
220 sha512 = "L6uV1oM6T6xbwbVx6t3biG5T2VSSB03LxnIrUd9M2pr6RkHVPFHJ37pC5MUwBAEhkGFJif7eks7fdMMSGZTeEQ==";
221 };
221 };
222 };
222 };
223 "@types/clone-0.1.30" = {
223 "@types/clone-0.1.30" = {
@@ -229,13 +229,13 b' let'
229 sha1 = "e7365648c1b42136a59c7d5040637b3b5c83b614";
229 sha1 = "e7365648c1b42136a59c7d5040637b3b5c83b614";
230 };
230 };
231 };
231 };
232 "@types/node-6.14.2" = {
232 "@types/node-6.14.6" = {
233 name = "_at_types_slash_node";
233 name = "_at_types_slash_node";
234 packageName = "@types/node";
234 packageName = "@types/node";
235 version = "6.14.2";
235 version = "6.14.6";
236 src = fetchurl {
236 src = fetchurl {
237 url = "https://registry.npmjs.org/@types/node/-/node-6.14.2.tgz";
237 url = "https://registry.npmjs.org/@types/node/-/node-6.14.6.tgz";
238 sha512 = "JWB3xaVfsfnFY8Ofc9rTB/op0fqqTSqy4vBcVk1LuRJvta7KTX+D//fCkiTMeLGhdr2EbFZzQjC97gvmPilk9Q==";
238 sha512 = "rFs9zCFtSHuseiNXxYxFlun8ibu+jtZPgRM+2ILCmeLiGeGLiIGxuOzD+cNyHegI1GD+da3R/cIbs9+xCLp13w==";
239 };
239 };
240 };
240 };
241 "@types/parse5-2.2.34" = {
241 "@types/parse5-2.2.34" = {
@@ -409,22 +409,22 b' let'
409 sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA==";
409 sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA==";
410 };
410 };
411 };
411 };
412 "@webcomponents/shadycss-1.7.1" = {
412 "@webcomponents/shadycss-1.9.1" = {
413 name = "_at_webcomponents_slash_shadycss";
413 name = "_at_webcomponents_slash_shadycss";
414 packageName = "@webcomponents/shadycss";
414 packageName = "@webcomponents/shadycss";
415 version = "1.7.1";
415 version = "1.9.1";
416 src = fetchurl {
416 src = fetchurl {
417 url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.7.1.tgz";
417 url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.9.1.tgz";
418 sha512 = "6SZqLajRPWL0rrKDZOGF8PCBq5B9JqgFmE5rX5psk6i8WrqiMkSCuO8+rnirzViTsU5CqnjQPFC3OvG4YJdMrQ==";
418 sha512 = "IaZOnWOKXHghqk/WfPNDRIgDBi3RsVPY2IFAw6tYiL9UBGvQRy5R6uC+Fk7qTZsReTJ0xh5MTT8yAcb3MUR4mQ==";
419 };
419 };
420 };
420 };
421 "@webcomponents/webcomponentsjs-2.2.1" = {
421 "@webcomponents/webcomponentsjs-2.2.10" = {
422 name = "_at_webcomponents_slash_webcomponentsjs";
422 name = "_at_webcomponents_slash_webcomponentsjs";
423 packageName = "@webcomponents/webcomponentsjs";
423 packageName = "@webcomponents/webcomponentsjs";
424 version = "2.2.1";
424 version = "2.2.10";
425 src = fetchurl {
425 src = fetchurl {
426 url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.1.tgz";
426 url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.10.tgz";
427 sha512 = "lZZ+Lkke6JhsJcQQqSVk1Pny6/8y4qhJ98LO7a/MwBSRO8WqHqK1X2vscfeL8vOnYGFnmBUyVG95lwYv/AXyLQ==";
427 sha512 = "5dzhUhP+h0qMiK0IWb7VNb0OGBoXO3AuI6Qi8t9PoKT50s5L1jv0xnwnLq+cFgPuTB8FLTNP8xIDmyoOsKBy9Q==";
428 };
428 };
429 };
429 };
430 "@xtuc/ieee754-1.2.0" = {
430 "@xtuc/ieee754-1.2.0" = {
@@ -499,22 +499,22 b' let'
499 sha1 = "82ffb02b29e662ae53bdc20af15947706739c536";
499 sha1 = "82ffb02b29e662ae53bdc20af15947706739c536";
500 };
500 };
501 };
501 };
502 "ajv-6.6.2" = {
502 "ajv-6.10.0" = {
503 name = "ajv";
503 name = "ajv";
504 packageName = "ajv";
504 packageName = "ajv";
505 version = "6.6.2";
505 version = "6.10.0";
506 src = fetchurl {
506 src = fetchurl {
507 url = "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz";
507 url = "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz";
508 sha512 = "FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==";
508 sha512 = "nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==";
509 };
509 };
510 };
510 };
511 "ajv-keywords-3.2.0" = {
511 "ajv-keywords-3.4.0" = {
512 name = "ajv-keywords";
512 name = "ajv-keywords";
513 packageName = "ajv-keywords";
513 packageName = "ajv-keywords";
514 version = "3.2.0";
514 version = "3.4.0";
515 src = fetchurl {
515 src = fetchurl {
516 url = "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz";
516 url = "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz";
517 sha1 = "e86b819c602cf8821ad637413698f1dec021847a";
517 sha512 = "aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==";
518 };
518 };
519 };
519 };
520 "align-text-0.1.4" = {
520 "align-text-0.1.4" = {
@@ -716,15 +716,6 b' let'
716 sha1 = "a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428";
716 sha1 = "a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428";
717 };
717 };
718 };
718 };
719 "arrify-1.0.1" = {
720 name = "arrify";
721 packageName = "arrify";
722 version = "1.0.1";
723 src = fetchurl {
724 url = "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz";
725 sha1 = "898508da2226f380df904728456849c1501a4b0d";
726 };
727 };
728 "asap-2.0.6" = {
719 "asap-2.0.6" = {
729 name = "asap";
720 name = "asap";
730 packageName = "asap";
721 packageName = "asap";
@@ -752,13 +743,13 b' let'
752 sha512 = "p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==";
743 sha512 = "p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==";
753 };
744 };
754 };
745 };
755 "assert-1.4.1" = {
746 "assert-1.5.0" = {
756 name = "assert";
747 name = "assert";
757 packageName = "assert";
748 packageName = "assert";
758 version = "1.4.1";
749 version = "1.5.0";
759 src = fetchurl {
750 src = fetchurl {
760 url = "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz";
751 url = "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz";
761 sha1 = "99912d591836b5a6f5b345c0f07eefc08fc65d91";
752 sha512 = "EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==";
762 };
753 };
763 };
754 };
764 "assert-plus-0.2.0" = {
755 "assert-plus-0.2.0" = {
@@ -815,22 +806,22 b' let'
815 sha1 = "b6bbe0b0674b9d719708ca38de8c237cb526c3d1";
806 sha1 = "b6bbe0b0674b9d719708ca38de8c237cb526c3d1";
816 };
807 };
817 };
808 };
818 "async-2.6.1" = {
809 "async-2.6.2" = {
819 name = "async";
810 name = "async";
820 packageName = "async";
811 packageName = "async";
821 version = "2.6.1";
812 version = "2.6.2";
822 src = fetchurl {
813 src = fetchurl {
823 url = "https://registry.npmjs.org/async/-/async-2.6.1.tgz";
814 url = "https://registry.npmjs.org/async/-/async-2.6.2.tgz";
824 sha512 = "fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==";
815 sha512 = "H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==";
825 };
816 };
826 };
817 };
827 "async-each-1.0.1" = {
818 "async-each-1.0.3" = {
828 name = "async-each";
819 name = "async-each";
829 packageName = "async-each";
820 packageName = "async-each";
830 version = "1.0.1";
821 version = "1.0.3";
831 src = fetchurl {
822 src = fetchurl {
832 url = "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz";
823 url = "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz";
833 sha1 = "19d386a1d9edc6e7c1c85d388aedbcc56d33602d";
824 sha512 = "z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==";
834 };
825 };
835 };
826 };
836 "asynckit-0.4.0" = {
827 "asynckit-0.4.0" = {
@@ -1445,22 +1436,22 b' let'
1445 sha512 = "vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==";
1436 sha512 = "vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==";
1446 };
1437 };
1447 };
1438 };
1448 "binary-extensions-1.12.0" = {
1439 "binary-extensions-1.13.1" = {
1449 name = "binary-extensions";
1440 name = "binary-extensions";
1450 packageName = "binary-extensions";
1441 packageName = "binary-extensions";
1451 version = "1.12.0";
1442 version = "1.13.1";
1452 src = fetchurl {
1443 src = fetchurl {
1453 url = "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz";
1444 url = "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz";
1454 sha512 = "DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==";
1445 sha512 = "Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==";
1455 };
1446 };
1456 };
1447 };
1457 "bluebird-3.5.3" = {
1448 "bluebird-3.5.4" = {
1458 name = "bluebird";
1449 name = "bluebird";
1459 packageName = "bluebird";
1450 packageName = "bluebird";
1460 version = "3.5.3";
1451 version = "3.5.4";
1461 src = fetchurl {
1452 src = fetchurl {
1462 url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz";
1453 url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz";
1463 sha512 = "/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==";
1454 sha512 = "FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==";
1464 };
1455 };
1465 };
1456 };
1466 "bn.js-4.11.8" = {
1457 "bn.js-4.11.8" = {
@@ -1661,13 +1652,13 b' let'
1661 sha1 = "9bb5304d2e0b56698b2c758b08a3eaa9daa58a39";
1652 sha1 = "9bb5304d2e0b56698b2c758b08a3eaa9daa58a39";
1662 };
1653 };
1663 };
1654 };
1664 "camelcase-5.0.0" = {
1655 "camelcase-5.3.1" = {
1665 name = "camelcase";
1656 name = "camelcase";
1666 packageName = "camelcase";
1657 packageName = "camelcase";
1667 version = "5.0.0";
1658 version = "5.3.1";
1668 src = fetchurl {
1659 src = fetchurl {
1669 url = "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz";
1660 url = "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz";
1670 sha512 = "faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==";
1661 sha512 = "L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==";
1671 };
1662 };
1672 };
1663 };
1673 "caniuse-api-1.6.1" = {
1664 "caniuse-api-1.6.1" = {
@@ -1679,22 +1670,22 b' let'
1679 sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c";
1670 sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c";
1680 };
1671 };
1681 };
1672 };
1682 "caniuse-db-1.0.30000927" = {
1673 "caniuse-db-1.0.30000967" = {
1683 name = "caniuse-db";
1674 name = "caniuse-db";
1684 packageName = "caniuse-db";
1675 packageName = "caniuse-db";
1685 version = "1.0.30000927";
1676 version = "1.0.30000967";
1686 src = fetchurl {
1677 src = fetchurl {
1687 url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000927.tgz";
1678 url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000967.tgz";
1688 sha512 = "CX/QvLA8oh7kQ9cHCCzFm0UZW4KwSyQSRJ5A1XtH42HaMJQ0yh+9fEVWagMqv9I1vSCtaqA5Mb8k0uKfv7jhDw==";
1679 sha512 = "70gk6cLSD5rItxnZ7WUxyCpM9LAjEb1tVzlENQfXQXZS/IiGnfAC6u32G5cZFlDBKjNPBIta/QSx5CZLZepxRA==";
1689 };
1680 };
1690 };
1681 };
1691 "caniuse-lite-1.0.30000927" = {
1682 "caniuse-lite-1.0.30000967" = {
1692 name = "caniuse-lite";
1683 name = "caniuse-lite";
1693 packageName = "caniuse-lite";
1684 packageName = "caniuse-lite";
1694 version = "1.0.30000927";
1685 version = "1.0.30000967";
1695 src = fetchurl {
1686 src = fetchurl {
1696 url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000927.tgz";
1687 url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000967.tgz";
1697 sha512 = "ogq4NbUWf1uG/j66k0AmiO3GjqJAlQyF8n4w8a954cbCyFKmYGvRtgz6qkq2fWuduTXHibX7GyYL5Pg58Aks2g==";
1688 sha512 = "rUBIbap+VJfxTzrM4akJ00lkvVb5/n5v3EGXfWzSH5zT8aJmGzjA8HWhJ4U6kCpzxozUSnB+yvAYDRPY6mRpgQ==";
1698 };
1689 };
1699 };
1690 };
1700 "caseless-0.12.0" = {
1691 "caseless-0.12.0" = {
@@ -1742,13 +1733,13 b' let'
1742 sha512 = "Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==";
1733 sha512 = "Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==";
1743 };
1734 };
1744 };
1735 };
1745 "chokidar-2.0.4" = {
1736 "chokidar-2.1.5" = {
1746 name = "chokidar";
1737 name = "chokidar";
1747 packageName = "chokidar";
1738 packageName = "chokidar";
1748 version = "2.0.4";
1739 version = "2.1.5";
1749 src = fetchurl {
1740 src = fetchurl {
1750 url = "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz";
1741 url = "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz";
1751 sha512 = "z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==";
1742 sha512 = "i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==";
1752 };
1743 };
1753 };
1744 };
1754 "chownr-1.1.1" = {
1745 "chownr-1.1.1" = {
@@ -1976,13 +1967,13 b' let'
1976 sha512 = "mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==";
1967 sha512 = "mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==";
1977 };
1968 };
1978 };
1969 };
1979 "combined-stream-1.0.7" = {
1970 "combined-stream-1.0.8" = {
1980 name = "combined-stream";
1971 name = "combined-stream";
1981 packageName = "combined-stream";
1972 packageName = "combined-stream";
1982 version = "1.0.7";
1973 version = "1.0.8";
1983 src = fetchurl {
1974 src = fetchurl {
1984 url = "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz";
1975 url = "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz";
1985 sha512 = "brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==";
1976 sha512 = "FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==";
1986 };
1977 };
1987 };
1978 };
1988 "commander-2.14.1" = {
1979 "commander-2.14.1" = {
@@ -2003,6 +1994,15 b' let'
2003 sha512 = "wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==";
1994 sha512 = "wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==";
2004 };
1995 };
2005 };
1996 };
1997 "commander-2.19.0" = {
1998 name = "commander";
1999 packageName = "commander";
2000 version = "2.19.0";
2001 src = fetchurl {
2002 url = "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz";
2003 sha512 = "6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==";
2004 };
2005 };
2006 "commondir-1.0.1" = {
2006 "commondir-1.0.1" = {
2007 name = "commondir";
2007 name = "commondir";
2008 packageName = "commondir";
2008 packageName = "commondir";
@@ -2012,13 +2012,13 b' let'
2012 sha1 = "ddd800da0c66127393cca5950ea968a3aaf1253b";
2012 sha1 = "ddd800da0c66127393cca5950ea968a3aaf1253b";
2013 };
2013 };
2014 };
2014 };
2015 "component-emitter-1.2.1" = {
2015 "component-emitter-1.3.0" = {
2016 name = "component-emitter";
2016 name = "component-emitter";
2017 packageName = "component-emitter";
2017 packageName = "component-emitter";
2018 version = "1.2.1";
2018 version = "1.3.0";
2019 src = fetchurl {
2019 src = fetchurl {
2020 url = "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz";
2020 url = "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz";
2021 sha1 = "137918d6d78283f7df7a6b7c5a63e140e69425e6";
2021 sha512 = "Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==";
2022 };
2022 };
2023 };
2023 };
2024 "concat-map-0.0.1" = {
2024 "concat-map-0.0.1" = {
@@ -2093,13 +2093,13 b' let'
2093 sha512 = "Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==";
2093 sha512 = "Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==";
2094 };
2094 };
2095 };
2095 };
2096 "core-js-2.6.1" = {
2096 "core-js-2.6.5" = {
2097 name = "core-js";
2097 name = "core-js";
2098 packageName = "core-js";
2098 packageName = "core-js";
2099 version = "2.6.1";
2099 version = "2.6.5";
2100 src = fetchurl {
2100 src = fetchurl {
2101 url = "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz";
2101 url = "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz";
2102 sha512 = "L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==";
2102 sha512 = "klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==";
2103 };
2103 };
2104 };
2104 };
2105 "core-util-is-1.0.2" = {
2105 "core-util-is-1.0.2" = {
@@ -2201,13 +2201,13 b' let'
2201 sha512 = "xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==";
2201 sha512 = "xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==";
2202 };
2202 };
2203 };
2203 };
2204 "css-what-2.1.2" = {
2204 "css-what-2.1.3" = {
2205 name = "css-what";
2205 name = "css-what";
2206 packageName = "css-what";
2206 packageName = "css-what";
2207 version = "2.1.2";
2207 version = "2.1.3";
2208 src = fetchurl {
2208 src = fetchurl {
2209 url = "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz";
2209 url = "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz";
2210 sha512 = "wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==";
2210 sha512 = "a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==";
2211 };
2211 };
2212 };
2212 };
2213 "cssesc-0.1.0" = {
2213 "cssesc-0.1.0" = {
@@ -2417,13 +2417,13 b' let'
2417 sha512 = "kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==";
2417 sha512 = "kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==";
2418 };
2418 };
2419 };
2419 };
2420 "dir-glob-2.0.0" = {
2420 "dir-glob-2.2.2" = {
2421 name = "dir-glob";
2421 name = "dir-glob";
2422 packageName = "dir-glob";
2422 packageName = "dir-glob";
2423 version = "2.0.0";
2423 version = "2.2.2";
2424 src = fetchurl {
2424 src = fetchurl {
2425 url = "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz";
2425 url = "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz";
2426 sha512 = "37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==";
2426 sha512 = "f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==";
2427 };
2427 };
2428 };
2428 };
2429 "dom-converter-0.2.0" = {
2429 "dom-converter-0.2.0" = {
@@ -2435,13 +2435,13 b' let'
2435 sha512 = "gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==";
2435 sha512 = "gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==";
2436 };
2436 };
2437 };
2437 };
2438 "dom-serializer-0.1.0" = {
2438 "dom-serializer-0.1.1" = {
2439 name = "dom-serializer";
2439 name = "dom-serializer";
2440 packageName = "dom-serializer";
2440 packageName = "dom-serializer";
2441 version = "0.1.0";
2441 version = "0.1.1";
2442 src = fetchurl {
2442 src = fetchurl {
2443 url = "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz";
2443 url = "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz";
2444 sha1 = "073c697546ce0780ce23be4a28e293e40bc30c82";
2444 sha512 = "l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==";
2445 };
2445 };
2446 };
2446 };
2447 "dom5-2.3.0" = {
2447 "dom5-2.3.0" = {
@@ -2462,15 +2462,6 b' let'
2462 sha512 = "jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==";
2462 sha512 = "jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==";
2463 };
2463 };
2464 };
2464 };
2465 "domelementtype-1.1.3" = {
2466 name = "domelementtype";
2467 packageName = "domelementtype";
2468 version = "1.1.3";
2469 src = fetchurl {
2470 url = "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz";
2471 sha1 = "bd28773e2642881aec51544924299c5cd822185b";
2472 };
2473 };
2474 "domelementtype-1.3.1" = {
2465 "domelementtype-1.3.1" = {
2475 name = "domelementtype";
2466 name = "domelementtype";
2476 packageName = "domelementtype";
2467 packageName = "domelementtype";
@@ -2480,15 +2471,6 b' let'
2480 sha512 = "BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==";
2471 sha512 = "BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==";
2481 };
2472 };
2482 };
2473 };
2483 "domhandler-2.1.0" = {
2484 name = "domhandler";
2485 packageName = "domhandler";
2486 version = "2.1.0";
2487 src = fetchurl {
2488 url = "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz";
2489 sha1 = "d2646f5e57f6c3bab11cf6cb05d3c0acf7412594";
2490 };
2491 };
2492 "domhandler-2.3.0" = {
2474 "domhandler-2.3.0" = {
2493 name = "domhandler";
2475 name = "domhandler";
2494 packageName = "domhandler";
2476 packageName = "domhandler";
@@ -2498,15 +2480,6 b' let'
2498 sha1 = "2de59a0822d5027fabff6f032c2b25a2a8abe738";
2480 sha1 = "2de59a0822d5027fabff6f032c2b25a2a8abe738";
2499 };
2481 };
2500 };
2482 };
2501 "domutils-1.1.6" = {
2502 name = "domutils";
2503 packageName = "domutils";
2504 version = "1.1.6";
2505 src = fetchurl {
2506 url = "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz";
2507 sha1 = "bddc3de099b9a2efacc51c623f28f416ecc57485";
2508 };
2509 };
2510 "domutils-1.5.1" = {
2483 "domutils-1.5.1" = {
2511 name = "domutils";
2484 name = "domutils";
2512 packageName = "domutils";
2485 packageName = "domutils";
@@ -2516,13 +2489,22 b' let'
2516 sha1 = "dcd8488a26f563d61079e48c9f7b7e32373682cf";
2489 sha1 = "dcd8488a26f563d61079e48c9f7b7e32373682cf";
2517 };
2490 };
2518 };
2491 };
2519 "duplexify-3.6.1" = {
2492 "dropzone-5.5.1" = {
2493 name = "dropzone";
2494 packageName = "dropzone";
2495 version = "5.5.1";
2496 src = fetchurl {
2497 url = "https://registry.npmjs.org/dropzone/-/dropzone-5.5.1.tgz";
2498 sha512 = "3VduRWLxx9hbVr42QieQN25mx/I61/mRdUSuxAmDGdDqZIN8qtP7tcKMa3KfpJjuGjOJGYYUzzeq6eGDnkzesA==";
2499 };
2500 };
2501 "duplexify-3.7.1" = {
2520 name = "duplexify";
2502 name = "duplexify";
2521 packageName = "duplexify";
2503 packageName = "duplexify";
2522 version = "3.6.1";
2504 version = "3.7.1";
2523 src = fetchurl {
2505 src = fetchurl {
2524 url = "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz";
2506 url = "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz";
2525 sha512 = "vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==";
2507 sha512 = "07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==";
2526 };
2508 };
2527 };
2509 };
2528 "ecc-jsbn-0.1.2" = {
2510 "ecc-jsbn-0.1.2" = {
@@ -2534,13 +2516,13 b' let'
2534 sha1 = "3a83a904e54353287874c564b7549386849a98c9";
2516 sha1 = "3a83a904e54353287874c564b7549386849a98c9";
2535 };
2517 };
2536 };
2518 };
2537 "electron-to-chromium-1.3.98" = {
2519 "electron-to-chromium-1.3.133" = {
2538 name = "electron-to-chromium";
2520 name = "electron-to-chromium";
2539 packageName = "electron-to-chromium";
2521 packageName = "electron-to-chromium";
2540 version = "1.3.98";
2522 version = "1.3.133";
2541 src = fetchurl {
2523 src = fetchurl {
2542 url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.98.tgz";
2524 url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.133.tgz";
2543 sha512 = "WIZdNuvE3dFr6kkPgv4d/cfswNZD6XbeLBM8baOIQTsnbf4xWrVEaLvp7oNnbnMWWXDqq7Tbv+H5JfciLTJm4Q==";
2525 sha512 = "lyoC8aoqbbDqsprb6aPdt9n3DpOZZzdz/T4IZKsR0/dkZIxnJVUjjcpOSwA66jPRIOyDAamCTAUqweU05kKNSg==";
2544 };
2526 };
2545 };
2527 };
2546 "elliptic-6.4.1" = {
2528 "elliptic-6.4.1" = {
@@ -2651,13 +2633,13 b' let'
2651 sha1 = "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4";
2633 sha1 = "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4";
2652 };
2634 };
2653 };
2635 };
2654 "eslint-scope-4.0.0" = {
2636 "eslint-scope-4.0.3" = {
2655 name = "eslint-scope";
2637 name = "eslint-scope";
2656 packageName = "eslint-scope";
2638 packageName = "eslint-scope";
2657 version = "4.0.0";
2639 version = "4.0.3";
2658 src = fetchurl {
2640 src = fetchurl {
2659 url = "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz";
2641 url = "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz";
2660 sha512 = "1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==";
2642 sha512 = "p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==";
2661 };
2643 };
2662 };
2644 };
2663 "espree-3.5.4" = {
2645 "espree-3.5.4" = {
@@ -2732,13 +2714,13 b' let'
2732 sha1 = "8f61b75cde012b2e9eb284d4545583b5643b61ab";
2714 sha1 = "8f61b75cde012b2e9eb284d4545583b5643b61ab";
2733 };
2715 };
2734 };
2716 };
2735 "events-1.1.1" = {
2717 "events-3.0.0" = {
2736 name = "events";
2718 name = "events";
2737 packageName = "events";
2719 packageName = "events";
2738 version = "1.1.1";
2720 version = "3.0.0";
2739 src = fetchurl {
2721 src = fetchurl {
2740 url = "https://registry.npmjs.org/events/-/events-1.1.1.tgz";
2722 url = "https://registry.npmjs.org/events/-/events-3.0.0.tgz";
2741 sha1 = "9ebdb7635ad099c70dcc4c2a1f5004288e8bd924";
2723 sha512 = "Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==";
2742 };
2724 };
2743 };
2725 };
2744 "evp_bytestokey-1.0.3" = {
2726 "evp_bytestokey-1.0.3" = {
@@ -2948,13 +2930,13 b' let'
2948 sha1 = "9326b1488c22d1a6088650a86901b2d9a90a2cbc";
2930 sha1 = "9326b1488c22d1a6088650a86901b2d9a90a2cbc";
2949 };
2931 };
2950 };
2932 };
2951 "fined-1.1.1" = {
2933 "fined-1.2.0" = {
2952 name = "fined";
2934 name = "fined";
2953 packageName = "fined";
2935 packageName = "fined";
2954 version = "1.1.1";
2936 version = "1.2.0";
2955 src = fetchurl {
2937 src = fetchurl {
2956 url = "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz";
2938 url = "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz";
2957 sha512 = "jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==";
2939 sha512 = "ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==";
2958 };
2940 };
2959 };
2941 };
2960 "flagged-respawn-1.0.1" = {
2942 "flagged-respawn-1.0.1" = {
@@ -2975,13 +2957,13 b' let'
2975 sha1 = "dae46a9d78fbe25292258cc1e780a41d95c03782";
2957 sha1 = "dae46a9d78fbe25292258cc1e780a41d95c03782";
2976 };
2958 };
2977 };
2959 };
2978 "flush-write-stream-1.0.3" = {
2960 "flush-write-stream-1.1.1" = {
2979 name = "flush-write-stream";
2961 name = "flush-write-stream";
2980 packageName = "flush-write-stream";
2962 packageName = "flush-write-stream";
2981 version = "1.0.3";
2963 version = "1.1.1";
2982 src = fetchurl {
2964 src = fetchurl {
2983 url = "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz";
2965 url = "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz";
2984 sha512 = "calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==";
2966 sha512 = "3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==";
2985 };
2967 };
2986 };
2968 };
2987 "for-in-1.0.2" = {
2969 "for-in-1.0.2" = {
@@ -3056,13 +3038,13 b' let'
3056 sha1 = "1504ad2523158caa40db4a2787cb01411994ea4f";
3038 sha1 = "1504ad2523158caa40db4a2787cb01411994ea4f";
3057 };
3039 };
3058 };
3040 };
3059 "fsevents-1.2.4" = {
3041 "fsevents-1.2.9" = {
3060 name = "fsevents";
3042 name = "fsevents";
3061 packageName = "fsevents";
3043 packageName = "fsevents";
3062 version = "1.2.4";
3044 version = "1.2.9";
3063 src = fetchurl {
3045 src = fetchurl {
3064 url = "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz";
3046 url = "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz";
3065 sha512 = "z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==";
3047 sha512 = "oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==";
3066 };
3048 };
3067 };
3049 };
3068 "function-bind-1.1.1" = {
3050 "function-bind-1.1.1" = {
@@ -3146,13 +3128,13 b' let'
3146 sha1 = "4a973f635b9190f715d10987d5c00fd2815ebe3d";
3128 sha1 = "4a973f635b9190f715d10987d5c00fd2815ebe3d";
3147 };
3129 };
3148 };
3130 };
3149 "glob-7.1.3" = {
3131 "glob-7.1.4" = {
3150 name = "glob";
3132 name = "glob";
3151 packageName = "glob";
3133 packageName = "glob";
3152 version = "7.1.3";
3134 version = "7.1.4";
3153 src = fetchurl {
3135 src = fetchurl {
3154 url = "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz";
3136 url = "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz";
3155 sha512 = "vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==";
3137 sha512 = "hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==";
3156 };
3138 };
3157 };
3139 };
3158 "glob-parent-3.1.0" = {
3140 "glob-parent-3.1.0" = {
@@ -3524,13 +3506,13 b' let'
3524 sha1 = "e36c3f2d2cae7d746a857e38d18d5f32a7882db8";
3506 sha1 = "e36c3f2d2cae7d746a857e38d18d5f32a7882db8";
3525 };
3507 };
3526 };
3508 };
3527 "homedir-polyfill-1.0.1" = {
3509 "homedir-polyfill-1.0.3" = {
3528 name = "homedir-polyfill";
3510 name = "homedir-polyfill";
3529 packageName = "homedir-polyfill";
3511 packageName = "homedir-polyfill";
3530 version = "1.0.1";
3512 version = "1.0.3";
3531 src = fetchurl {
3513 src = fetchurl {
3532 url = "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz";
3514 url = "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz";
3533 sha1 = "4c2bbc8a758998feebf5ed68580f76d46768b4bc";
3515 sha512 = "eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==";
3534 };
3516 };
3535 };
3517 };
3536 "hooker-0.2.3" = {
3518 "hooker-0.2.3" = {
@@ -3587,15 +3569,6 b' let'
3587 sha1 = "b01abbd723acaaa7b37b6af4492ebda03d9dd37b";
3569 sha1 = "b01abbd723acaaa7b37b6af4492ebda03d9dd37b";
3588 };
3570 };
3589 };
3571 };
3590 "htmlparser2-3.3.0" = {
3591 name = "htmlparser2";
3592 packageName = "htmlparser2";
3593 version = "3.3.0";
3594 src = fetchurl {
3595 url = "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz";
3596 sha1 = "cc70d05a59f6542e43f0e685c982e14c924a9efe";
3597 };
3598 };
3599 "htmlparser2-3.8.3" = {
3572 "htmlparser2-3.8.3" = {
3600 name = "htmlparser2";
3573 name = "htmlparser2";
3601 packageName = "htmlparser2";
3574 packageName = "htmlparser2";
@@ -3650,13 +3623,13 b' let'
3650 sha1 = "83f0a0ec378bf3246178b6c2ad9136f135b1c962";
3623 sha1 = "83f0a0ec378bf3246178b6c2ad9136f135b1c962";
3651 };
3624 };
3652 };
3625 };
3653 "ieee754-1.1.12" = {
3626 "ieee754-1.1.13" = {
3654 name = "ieee754";
3627 name = "ieee754";
3655 packageName = "ieee754";
3628 packageName = "ieee754";
3656 version = "1.1.12";
3629 version = "1.1.13";
3657 src = fetchurl {
3630 src = fetchurl {
3658 url = "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz";
3631 url = "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz";
3659 sha512 = "GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==";
3632 sha512 = "4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==";
3660 };
3633 };
3661 };
3634 };
3662 "iferr-0.1.5" = {
3635 "iferr-0.1.5" = {
@@ -3974,13 +3947,13 b' let'
3974 sha1 = "7ba5ae24217804ac70707b96922567486cc3e84a";
3947 sha1 = "7ba5ae24217804ac70707b96922567486cc3e84a";
3975 };
3948 };
3976 };
3949 };
3977 "is-glob-4.0.0" = {
3950 "is-glob-4.0.1" = {
3978 name = "is-glob";
3951 name = "is-glob";
3979 packageName = "is-glob";
3952 packageName = "is-glob";
3980 version = "4.0.0";
3953 version = "4.0.1";
3981 src = fetchurl {
3954 src = fetchurl {
3982 url = "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz";
3955 url = "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz";
3983 sha1 = "9521c76845cc2610a85203ddf080a958c2ffabc0";
3956 sha512 = "5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==";
3984 };
3957 };
3985 };
3958 };
3986 "is-number-3.0.0" = {
3959 "is-number-3.0.0" = {
@@ -4145,13 +4118,13 b' let'
4145 sha1 = "dd8b74278b27102d29df63eae28308a8cfa1b583";
4118 sha1 = "dd8b74278b27102d29df63eae28308a8cfa1b583";
4146 };
4119 };
4147 };
4120 };
4148 "js-base64-2.5.0" = {
4121 "js-base64-2.5.1" = {
4149 name = "js-base64";
4122 name = "js-base64";
4150 packageName = "js-base64";
4123 packageName = "js-base64";
4151 version = "2.5.0";
4124 version = "2.5.1";
4152 src = fetchurl {
4125 src = fetchurl {
4153 url = "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz";
4126 url = "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz";
4154 sha512 = "wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==";
4127 sha512 = "M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==";
4155 };
4128 };
4156 };
4129 };
4157 "js-tokens-3.0.2" = {
4130 "js-tokens-3.0.2" = {
@@ -4208,6 +4181,15 b' let'
4208 sha1 = "46c3fec8c1892b12b0833db9bc7622176dbab34b";
4181 sha1 = "46c3fec8c1892b12b0833db9bc7622176dbab34b";
4209 };
4182 };
4210 };
4183 };
4184 "jshint-2.10.2" = {
4185 name = "jshint";
4186 packageName = "jshint";
4187 version = "2.10.2";
4188 src = fetchurl {
4189 url = "https://registry.npmjs.org/jshint/-/jshint-2.10.2.tgz";
4190 sha512 = "e7KZgCSXMJxznE/4WULzybCMNXNAd/bf5TSrvVEq78Q/K8ZwFpmBqQeDtNiHc3l49nV4E/+YeHU/JZjSUIrLAA==";
4191 };
4192 };
4211 "jshint-2.9.7" = {
4193 "jshint-2.9.7" = {
4212 name = "jshint";
4194 name = "jshint";
4213 packageName = "jshint";
4195 packageName = "jshint";
@@ -4370,13 +4352,13 b' let'
4370 sha1 = "2009291bb31cea861bbf10a7c15a28caf75c31ec";
4352 sha1 = "2009291bb31cea861bbf10a7c15a28caf75c31ec";
4371 };
4353 };
4372 };
4354 };
4373 "loader-runner-2.3.1" = {
4355 "loader-runner-2.4.0" = {
4374 name = "loader-runner";
4356 name = "loader-runner";
4375 packageName = "loader-runner";
4357 packageName = "loader-runner";
4376 version = "2.3.1";
4358 version = "2.4.0";
4377 src = fetchurl {
4359 src = fetchurl {
4378 url = "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz";
4360 url = "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz";
4379 sha512 = "By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==";
4361 sha512 = "Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==";
4380 };
4362 };
4381 };
4363 };
4382 "loader-utils-0.2.17" = {
4364 "loader-utils-0.2.17" = {
@@ -4460,15 +4442,6 b' let'
4460 sha1 = "b28aa6288a2b9fc651035c7711f65ab6190331a6";
4442 sha1 = "b28aa6288a2b9fc651035c7711f65ab6190331a6";
4461 };
4443 };
4462 };
4444 };
4463 "lodash.debounce-4.0.8" = {
4464 name = "lodash.debounce";
4465 packageName = "lodash.debounce";
4466 version = "4.0.8";
4467 src = fetchurl {
4468 url = "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz";
4469 sha1 = "82d79bff30a67c4005ffd5e2515300ad9ca4d7af";
4470 };
4471 };
4472 "lodash.isplainobject-4.0.6" = {
4445 "lodash.isplainobject-4.0.6" = {
4473 name = "lodash.isplainobject";
4446 name = "lodash.isplainobject";
4474 packageName = "lodash.isplainobject";
4447 packageName = "lodash.isplainobject";
@@ -4613,13 +4586,13 b' let'
4613 sha512 = "xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==";
4586 sha512 = "xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==";
4614 };
4587 };
4615 };
4588 };
4616 "mem-4.0.0" = {
4589 "mem-4.3.0" = {
4617 name = "mem";
4590 name = "mem";
4618 packageName = "mem";
4591 packageName = "mem";
4619 version = "4.0.0";
4592 version = "4.3.0";
4620 src = fetchurl {
4593 src = fetchurl {
4621 url = "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz";
4594 url = "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz";
4622 sha512 = "WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==";
4595 sha512 = "qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==";
4623 };
4596 };
4624 };
4597 };
4625 "memory-fs-0.4.1" = {
4598 "memory-fs-0.4.1" = {
@@ -4658,31 +4631,31 b' let'
4658 sha512 = "x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==";
4631 sha512 = "x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==";
4659 };
4632 };
4660 };
4633 };
4661 "mime-db-1.37.0" = {
4634 "mime-db-1.40.0" = {
4662 name = "mime-db";
4635 name = "mime-db";
4663 packageName = "mime-db";
4636 packageName = "mime-db";
4664 version = "1.37.0";
4637 version = "1.40.0";
4665 src = fetchurl {
4638 src = fetchurl {
4666 url = "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz";
4639 url = "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz";
4667 sha512 = "R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==";
4640 sha512 = "jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==";
4668 };
4641 };
4669 };
4642 };
4670 "mime-types-2.1.21" = {
4643 "mime-types-2.1.24" = {
4671 name = "mime-types";
4644 name = "mime-types";
4672 packageName = "mime-types";
4645 packageName = "mime-types";
4673 version = "2.1.21";
4646 version = "2.1.24";
4674 src = fetchurl {
4647 src = fetchurl {
4675 url = "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz";
4648 url = "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz";
4676 sha512 = "3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==";
4649 sha512 = "WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==";
4677 };
4650 };
4678 };
4651 };
4679 "mimic-fn-1.2.0" = {
4652 "mimic-fn-2.1.0" = {
4680 name = "mimic-fn";
4653 name = "mimic-fn";
4681 packageName = "mimic-fn";
4654 packageName = "mimic-fn";
4682 version = "1.2.0";
4655 version = "2.1.0";
4683 src = fetchurl {
4656 src = fetchurl {
4684 url = "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz";
4657 url = "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz";
4685 sha512 = "jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==";
4658 sha512 = "OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==";
4686 };
4659 };
4687 };
4660 };
4688 "minimalistic-assert-1.0.1" = {
4661 "minimalistic-assert-1.0.1" = {
@@ -4775,22 +4748,22 b' let'
4775 sha1 = "30057438eac6cf7f8c4767f38648d6697d75c903";
4748 sha1 = "30057438eac6cf7f8c4767f38648d6697d75c903";
4776 };
4749 };
4777 };
4750 };
4778 "moment-2.23.0" = {
4751 "moment-2.24.0" = {
4779 name = "moment";
4752 name = "moment";
4780 packageName = "moment";
4753 packageName = "moment";
4781 version = "2.23.0";
4754 version = "2.24.0";
4782 src = fetchurl {
4755 src = fetchurl {
4783 url = "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz";
4756 url = "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz";
4784 sha512 = "3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA==";
4757 sha512 = "bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==";
4785 };
4758 };
4786 };
4759 };
4787 "mousetrap-1.6.2" = {
4760 "mousetrap-1.6.3" = {
4788 name = "mousetrap";
4761 name = "mousetrap";
4789 packageName = "mousetrap";
4762 packageName = "mousetrap";
4790 version = "1.6.2";
4763 version = "1.6.3";
4791 src = fetchurl {
4764 src = fetchurl {
4792 url = "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.2.tgz";
4765 url = "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.3.tgz";
4793 sha512 = "jDjhi7wlHwdO6q6DS7YRmSHcuI+RVxadBkLt3KHrhd3C2b+w5pKefg3oj5beTcHZyVFA9Aksf+yEE1y5jxUjVA==";
4766 sha512 = "bd+nzwhhs9ifsUrC2tWaSgm24/oo2c83zaRyZQF06hYA6sANfsXHtnZ19AbbbDXCDzeH5nZBSQ4NvCjgD62tJA==";
4794 };
4767 };
4795 };
4768 };
4796 "move-concurrently-1.0.1" = {
4769 "move-concurrently-1.0.1" = {
@@ -4811,13 +4784,13 b' let'
4811 sha1 = "5608aeadfc00be6c2901df5f9861788de0d597c8";
4784 sha1 = "5608aeadfc00be6c2901df5f9861788de0d597c8";
4812 };
4785 };
4813 };
4786 };
4814 "nan-2.12.1" = {
4787 "nan-2.13.2" = {
4815 name = "nan";
4788 name = "nan";
4816 packageName = "nan";
4789 packageName = "nan";
4817 version = "2.12.1";
4790 version = "2.13.2";
4818 src = fetchurl {
4791 src = fetchurl {
4819 url = "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz";
4792 url = "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz";
4820 sha512 = "JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==";
4793 sha512 = "TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==";
4821 };
4794 };
4822 };
4795 };
4823 "nanomatch-1.2.13" = {
4796 "nanomatch-1.2.13" = {
@@ -4829,13 +4802,13 b' let'
4829 sha512 = "fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==";
4802 sha512 = "fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==";
4830 };
4803 };
4831 };
4804 };
4832 "neo-async-2.6.0" = {
4805 "neo-async-2.6.1" = {
4833 name = "neo-async";
4806 name = "neo-async";
4834 packageName = "neo-async";
4807 packageName = "neo-async";
4835 version = "2.6.0";
4808 version = "2.6.1";
4836 src = fetchurl {
4809 src = fetchurl {
4837 url = "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz";
4810 url = "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz";
4838 sha512 = "MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==";
4811 sha512 = "iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==";
4839 };
4812 };
4840 };
4813 };
4841 "nice-try-1.0.5" = {
4814 "nice-try-1.0.5" = {
@@ -4856,13 +4829,13 b' let'
4856 sha512 = "rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==";
4829 sha512 = "rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==";
4857 };
4830 };
4858 };
4831 };
4859 "node-libs-browser-2.1.0" = {
4832 "node-libs-browser-2.2.0" = {
4860 name = "node-libs-browser";
4833 name = "node-libs-browser";
4861 packageName = "node-libs-browser";
4834 packageName = "node-libs-browser";
4862 version = "2.1.0";
4835 version = "2.2.0";
4863 src = fetchurl {
4836 src = fetchurl {
4864 url = "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz";
4837 url = "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz";
4865 sha512 = "5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==";
4838 sha512 = "5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==";
4866 };
4839 };
4867 };
4840 };
4868 "nopt-1.0.10" = {
4841 "nopt-1.0.10" = {
@@ -4910,6 +4883,15 b' let'
4910 sha1 = "1ab28b556e198363a8c1a6f7e6fa20137fe6aed9";
4883 sha1 = "1ab28b556e198363a8c1a6f7e6fa20137fe6aed9";
4911 };
4884 };
4912 };
4885 };
4886 "normalize-path-3.0.0" = {
4887 name = "normalize-path";
4888 packageName = "normalize-path";
4889 version = "3.0.0";
4890 src = fetchurl {
4891 url = "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz";
4892 sha512 = "6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==";
4893 };
4894 };
4913 "normalize-range-0.1.2" = {
4895 "normalize-range-0.1.2" = {
4914 name = "normalize-range";
4896 name = "normalize-range";
4915 packageName = "normalize-range";
4897 packageName = "normalize-range";
@@ -4991,13 +4973,13 b' let'
4991 sha1 = "7e7d858b781bd7c991a41ba975ed3812754e998c";
4973 sha1 = "7e7d858b781bd7c991a41ba975ed3812754e998c";
4992 };
4974 };
4993 };
4975 };
4994 "object-keys-1.0.12" = {
4976 "object-keys-1.1.1" = {
4995 name = "object-keys";
4977 name = "object-keys";
4996 packageName = "object-keys";
4978 packageName = "object-keys";
4997 version = "1.0.12";
4979 version = "1.1.1";
4998 src = fetchurl {
4980 src = fetchurl {
4999 url = "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz";
4981 url = "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz";
5000 sha512 = "FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==";
4982 sha512 = "NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==";
5001 };
4983 };
5002 };
4984 };
5003 "object-visit-1.0.1" = {
4985 "object-visit-1.0.1" = {
@@ -5117,13 +5099,13 b' let'
5117 sha1 = "3fbcfb15b899a44123b34b6dcc18b724336a2cae";
5099 sha1 = "3fbcfb15b899a44123b34b6dcc18b724336a2cae";
5118 };
5100 };
5119 };
5101 };
5120 "p-is-promise-1.1.0" = {
5102 "p-is-promise-2.1.0" = {
5121 name = "p-is-promise";
5103 name = "p-is-promise";
5122 packageName = "p-is-promise";
5104 packageName = "p-is-promise";
5123 version = "1.1.0";
5105 version = "2.1.0";
5124 src = fetchurl {
5106 src = fetchurl {
5125 url = "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz";
5107 url = "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz";
5126 sha1 = "9c9456989e9f6588017b0434d56097675c3da05e";
5108 sha512 = "Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==";
5127 };
5109 };
5128 };
5110 };
5129 "p-limit-1.3.0" = {
5111 "p-limit-1.3.0" = {
@@ -5135,13 +5117,13 b' let'
5135 sha512 = "vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==";
5117 sha512 = "vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==";
5136 };
5118 };
5137 };
5119 };
5138 "p-limit-2.1.0" = {
5120 "p-limit-2.2.0" = {
5139 name = "p-limit";
5121 name = "p-limit";
5140 packageName = "p-limit";
5122 packageName = "p-limit";
5141 version = "2.1.0";
5123 version = "2.2.0";
5142 src = fetchurl {
5124 src = fetchurl {
5143 url = "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz";
5125 url = "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz";
5144 sha512 = "NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==";
5126 sha512 = "pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==";
5145 };
5127 };
5146 };
5128 };
5147 "p-locate-2.0.0" = {
5129 "p-locate-2.0.0" = {
@@ -5171,22 +5153,22 b' let'
5171 sha1 = "cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3";
5153 sha1 = "cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3";
5172 };
5154 };
5173 };
5155 };
5174 "p-try-2.0.0" = {
5156 "p-try-2.2.0" = {
5175 name = "p-try";
5157 name = "p-try";
5176 packageName = "p-try";
5158 packageName = "p-try";
5177 version = "2.0.0";
5159 version = "2.2.0";
5178 src = fetchurl {
5160 src = fetchurl {
5179 url = "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz";
5161 url = "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz";
5180 sha512 = "hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==";
5162 sha512 = "R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==";
5181 };
5163 };
5182 };
5164 };
5183 "pako-1.0.7" = {
5165 "pako-1.0.10" = {
5184 name = "pako";
5166 name = "pako";
5185 packageName = "pako";
5167 packageName = "pako";
5186 version = "1.0.7";
5168 version = "1.0.10";
5187 src = fetchurl {
5169 src = fetchurl {
5188 url = "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz";
5170 url = "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz";
5189 sha512 = "3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==";
5171 sha512 = "0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==";
5190 };
5172 };
5191 };
5173 };
5192 "parallel-transform-1.1.0" = {
5174 "parallel-transform-1.1.0" = {
@@ -5207,13 +5189,13 b' let'
5207 sha1 = "df94fd8cf6531ecf75e6bef9a0858fbc72be2247";
5189 sha1 = "df94fd8cf6531ecf75e6bef9a0858fbc72be2247";
5208 };
5190 };
5209 };
5191 };
5210 "parse-asn1-5.1.1" = {
5192 "parse-asn1-5.1.4" = {
5211 name = "parse-asn1";
5193 name = "parse-asn1";
5212 packageName = "parse-asn1";
5194 packageName = "parse-asn1";
5213 version = "5.1.1";
5195 version = "5.1.4";
5214 src = fetchurl {
5196 src = fetchurl {
5215 url = "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz";
5197 url = "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz";
5216 sha512 = "KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==";
5198 sha512 = "Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==";
5217 };
5199 };
5218 };
5200 };
5219 "parse-filepath-1.0.2" = {
5201 "parse-filepath-1.0.2" = {
@@ -5927,13 +5909,13 b' let'
5927 sha1 = "9ec61f79049875707d69414596fd907a4d711e73";
5909 sha1 = "9ec61f79049875707d69414596fd907a4d711e73";
5928 };
5910 };
5929 };
5911 };
5930 "randombytes-2.0.6" = {
5912 "randombytes-2.1.0" = {
5931 name = "randombytes";
5913 name = "randombytes";
5932 packageName = "randombytes";
5914 packageName = "randombytes";
5933 version = "2.0.6";
5915 version = "2.1.0";
5934 src = fetchurl {
5916 src = fetchurl {
5935 url = "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz";
5917 url = "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz";
5936 sha512 = "CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==";
5918 sha512 = "vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==";
5937 };
5919 };
5938 };
5920 };
5939 "randomfill-1.0.4" = {
5921 "randomfill-1.0.4" = {
@@ -5954,15 +5936,6 b' let'
5954 sha512 = "guh4ZNAf96f+CDwfnPbFeFiO5YcfPllUmZrgcoOmx6iqZPq+DcKbnyjPuBxEAtQ3tqqd++qChsQfQB+VBzFT0Q==";
5936 sha512 = "guh4ZNAf96f+CDwfnPbFeFiO5YcfPllUmZrgcoOmx6iqZPq+DcKbnyjPuBxEAtQ3tqqd++qChsQfQB+VBzFT0Q==";
5955 };
5937 };
5956 };
5938 };
5957 "readable-stream-1.0.34" = {
5958 name = "readable-stream";
5959 packageName = "readable-stream";
5960 version = "1.0.34";
5961 src = fetchurl {
5962 url = "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz";
5963 sha1 = "125820e34bc842d2f2aaafafe4c2916ee32c157c";
5964 };
5965 };
5966 "readable-stream-1.1.14" = {
5939 "readable-stream-1.1.14" = {
5967 name = "readable-stream";
5940 name = "readable-stream";
5968 packageName = "readable-stream";
5941 packageName = "readable-stream";
@@ -6116,13 +6089,13 b' let'
6116 sha1 = "c24bce2a283adad5bc3f58e0d48249b92379d8ef";
6089 sha1 = "c24bce2a283adad5bc3f58e0d48249b92379d8ef";
6117 };
6090 };
6118 };
6091 };
6119 "renderkid-2.0.2" = {
6092 "renderkid-2.0.3" = {
6120 name = "renderkid";
6093 name = "renderkid";
6121 packageName = "renderkid";
6094 packageName = "renderkid";
6122 version = "2.0.2";
6095 version = "2.0.3";
6123 src = fetchurl {
6096 src = fetchurl {
6124 url = "https://registry.npmjs.org/renderkid/-/renderkid-2.0.2.tgz";
6097 url = "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz";
6125 sha512 = "FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg==";
6098 sha512 = "z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==";
6126 };
6099 };
6127 };
6100 };
6128 "repeat-element-1.1.3" = {
6101 "repeat-element-1.1.3" = {
@@ -6179,13 +6152,13 b' let'
6179 sha1 = "97f717b69d48784f5f526a6c5aa8ffdda055a4d1";
6152 sha1 = "97f717b69d48784f5f526a6c5aa8ffdda055a4d1";
6180 };
6153 };
6181 };
6154 };
6182 "resolve-1.9.0" = {
6155 "resolve-1.10.1" = {
6183 name = "resolve";
6156 name = "resolve";
6184 packageName = "resolve";
6157 packageName = "resolve";
6185 version = "1.9.0";
6158 version = "1.10.1";
6186 src = fetchurl {
6159 src = fetchurl {
6187 url = "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz";
6160 url = "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz";
6188 sha512 = "TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==";
6161 sha512 = "KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==";
6189 };
6162 };
6190 };
6163 };
6191 "resolve-cwd-2.0.0" = {
6164 "resolve-cwd-2.0.0" = {
@@ -6332,22 +6305,22 b' let'
6332 sha1 = "0e7350acdec80b1108528786ec1d4418d11b396d";
6305 sha1 = "0e7350acdec80b1108528786ec1d4418d11b396d";
6333 };
6306 };
6334 };
6307 };
6335 "semver-5.6.0" = {
6308 "semver-5.7.0" = {
6336 name = "semver";
6309 name = "semver";
6337 packageName = "semver";
6310 packageName = "semver";
6338 version = "5.6.0";
6311 version = "5.7.0";
6339 src = fetchurl {
6312 src = fetchurl {
6340 url = "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz";
6313 url = "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz";
6341 sha512 = "RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==";
6314 sha512 = "Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==";
6342 };
6315 };
6343 };
6316 };
6344 "serialize-javascript-1.6.1" = {
6317 "serialize-javascript-1.7.0" = {
6345 name = "serialize-javascript";
6318 name = "serialize-javascript";
6346 packageName = "serialize-javascript";
6319 packageName = "serialize-javascript";
6347 version = "1.6.1";
6320 version = "1.7.0";
6348 src = fetchurl {
6321 src = fetchurl {
6349 url = "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz";
6322 url = "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz";
6350 sha512 = "A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==";
6323 sha512 = "ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==";
6351 };
6324 };
6352 };
6325 };
6353 "set-blocking-2.0.0" = {
6326 "set-blocking-2.0.0" = {
@@ -6593,13 +6566,13 b' let'
6593 sha1 = "04e6926f662895354f3dd015203633b857297e2c";
6566 sha1 = "04e6926f662895354f3dd015203633b857297e2c";
6594 };
6567 };
6595 };
6568 };
6596 "sshpk-1.16.0" = {
6569 "sshpk-1.16.1" = {
6597 name = "sshpk";
6570 name = "sshpk";
6598 packageName = "sshpk";
6571 packageName = "sshpk";
6599 version = "1.16.0";
6572 version = "1.16.1";
6600 src = fetchurl {
6573 src = fetchurl {
6601 url = "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz";
6574 url = "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz";
6602 sha512 = "Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==";
6575 sha512 = "HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==";
6603 };
6576 };
6604 };
6577 };
6605 "ssri-5.3.0" = {
6578 "ssri-5.3.0" = {
@@ -6629,13 +6602,13 b' let'
6629 sha1 = "142bf6b64c2b416e4b707ebf8f09b8b5a5043877";
6602 sha1 = "142bf6b64c2b416e4b707ebf8f09b8b5a5043877";
6630 };
6603 };
6631 };
6604 };
6632 "stream-browserify-2.0.1" = {
6605 "stream-browserify-2.0.2" = {
6633 name = "stream-browserify";
6606 name = "stream-browserify";
6634 packageName = "stream-browserify";
6607 packageName = "stream-browserify";
6635 version = "2.0.1";
6608 version = "2.0.2";
6636 src = fetchurl {
6609 src = fetchurl {
6637 url = "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz";
6610 url = "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz";
6638 sha1 = "66266ee5f9bdb9940a4e4514cafb43bb71e5c9db";
6611 sha512 = "nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==";
6639 };
6612 };
6640 };
6613 };
6641 "stream-each-1.2.3" = {
6614 "stream-each-1.2.3" = {
@@ -6836,13 +6809,13 b' let'
6836 sha512 = "2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==";
6809 sha512 = "2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==";
6837 };
6810 };
6838 };
6811 };
6839 "tapable-1.1.1" = {
6812 "tapable-1.1.3" = {
6840 name = "tapable";
6813 name = "tapable";
6841 packageName = "tapable";
6814 packageName = "tapable";
6842 version = "1.1.1";
6815 version = "1.1.3";
6843 src = fetchurl {
6816 src = fetchurl {
6844 url = "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz";
6817 url = "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz";
6845 sha512 = "9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==";
6818 sha512 = "4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==";
6846 };
6819 };
6847 };
6820 };
6848 "through-2.3.8" = {
6821 "through-2.3.8" = {
@@ -6872,13 +6845,13 b' let'
6872 sha512 = "YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==";
6845 sha512 = "YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==";
6873 };
6846 };
6874 };
6847 };
6875 "tiny-emitter-2.0.2" = {
6848 "tiny-emitter-2.1.0" = {
6876 name = "tiny-emitter";
6849 name = "tiny-emitter";
6877 packageName = "tiny-emitter";
6850 packageName = "tiny-emitter";
6878 version = "2.0.2";
6851 version = "2.1.0";
6879 src = fetchurl {
6852 src = fetchurl {
6880 url = "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz";
6853 url = "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz";
6881 sha512 = "2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==";
6854 sha512 = "NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==";
6882 };
6855 };
6883 };
6856 };
6884 "tiny-lr-fork-0.0.5" = {
6857 "tiny-lr-fork-0.0.5" = {
@@ -7034,13 +7007,13 b' let'
7034 sha1 = "29c5733148057bb4e1f75df35b7a9cb72e6a59dd";
7007 sha1 = "29c5733148057bb4e1f75df35b7a9cb72e6a59dd";
7035 };
7008 };
7036 };
7009 };
7037 "uglify-js-3.4.9" = {
7010 "uglify-js-3.4.10" = {
7038 name = "uglify-js";
7011 name = "uglify-js";
7039 packageName = "uglify-js";
7012 packageName = "uglify-js";
7040 version = "3.4.9";
7013 version = "3.4.10";
7041 src = fetchurl {
7014 src = fetchurl {
7042 url = "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz";
7015 url = "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz";
7043 sha512 = "8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==";
7016 sha512 = "Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==";
7044 };
7017 };
7045 };
7018 };
7046 "uglify-to-browserify-1.0.2" = {
7019 "uglify-to-browserify-1.0.2" = {
@@ -7160,13 +7133,13 b' let'
7160 sha1 = "8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559";
7133 sha1 = "8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559";
7161 };
7134 };
7162 };
7135 };
7163 "upath-1.1.0" = {
7136 "upath-1.1.2" = {
7164 name = "upath";
7137 name = "upath";
7165 packageName = "upath";
7138 packageName = "upath";
7166 version = "1.1.0";
7139 version = "1.1.2";
7167 src = fetchurl {
7140 src = fetchurl {
7168 url = "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz";
7141 url = "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz";
7169 sha512 = "bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==";
7142 sha512 = "kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==";
7170 };
7143 };
7171 };
7144 };
7172 "upper-case-1.1.3" = {
7145 "upper-case-1.1.3" = {
@@ -7223,13 +7196,13 b' let'
7223 sha1 = "7afb1afe50805246489e3db7fe0ed379336ac0f9";
7196 sha1 = "7afb1afe50805246489e3db7fe0ed379336ac0f9";
7224 };
7197 };
7225 };
7198 };
7226 "util-0.10.4" = {
7199 "util-0.11.1" = {
7227 name = "util";
7200 name = "util";
7228 packageName = "util";
7201 packageName = "util";
7229 version = "0.10.4";
7202 version = "0.11.1";
7230 src = fetchurl {
7203 src = fetchurl {
7231 url = "https://registry.npmjs.org/util/-/util-0.10.4.tgz";
7204 url = "https://registry.npmjs.org/util/-/util-0.11.1.tgz";
7232 sha512 = "0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==";
7205 sha512 = "HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==";
7233 };
7206 };
7234 };
7207 };
7235 "util-deprecate-1.0.2" = {
7208 "util-deprecate-1.0.2" = {
@@ -7268,31 +7241,31 b' let'
7268 sha512 = "yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==";
7241 sha512 = "yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==";
7269 };
7242 };
7270 };
7243 };
7271 "v8-compile-cache-2.0.2" = {
7244 "v8-compile-cache-2.0.3" = {
7272 name = "v8-compile-cache";
7245 name = "v8-compile-cache";
7273 packageName = "v8-compile-cache";
7246 packageName = "v8-compile-cache";
7274 version = "2.0.2";
7247 version = "2.0.3";
7275 src = fetchurl {
7248 src = fetchurl {
7276 url = "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz";
7249 url = "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz";
7277 sha512 = "1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==";
7250 sha512 = "CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==";
7278 };
7251 };
7279 };
7252 };
7280 "v8flags-3.1.2" = {
7253 "v8flags-3.1.3" = {
7281 name = "v8flags";
7254 name = "v8flags";
7282 packageName = "v8flags";
7255 packageName = "v8flags";
7283 version = "3.1.2";
7256 version = "3.1.3";
7284 src = fetchurl {
7257 src = fetchurl {
7285 url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz";
7258 url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz";
7286 sha512 = "MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==";
7259 sha512 = "amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==";
7287 };
7260 };
7288 };
7261 };
7289 "vendors-1.0.2" = {
7262 "vendors-1.0.3" = {
7290 name = "vendors";
7263 name = "vendors";
7291 packageName = "vendors";
7264 packageName = "vendors";
7292 version = "1.0.2";
7265 version = "1.0.3";
7293 src = fetchurl {
7266 src = fetchurl {
7294 url = "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz";
7267 url = "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz";
7295 sha512 = "w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==";
7268 sha512 = "fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==";
7296 };
7269 };
7297 };
7270 };
7298 "verror-1.10.0" = {
7271 "verror-1.10.0" = {
@@ -7430,13 +7403,13 b' let'
7430 sha1 = "b79669bb42ecb409f83d583cad52ca17eaa1643f";
7403 sha1 = "b79669bb42ecb409f83d583cad52ca17eaa1643f";
7431 };
7404 };
7432 };
7405 };
7433 "worker-farm-1.6.0" = {
7406 "worker-farm-1.7.0" = {
7434 name = "worker-farm";
7407 name = "worker-farm";
7435 packageName = "worker-farm";
7408 packageName = "worker-farm";
7436 version = "1.6.0";
7409 version = "1.7.0";
7437 src = fetchurl {
7410 src = fetchurl {
7438 url = "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz";
7411 url = "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz";
7439 sha512 = "6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==";
7412 sha512 = "rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==";
7440 };
7413 };
7441 };
7414 };
7442 "wrap-ansi-2.1.0" = {
7415 "wrap-ansi-2.1.0" = {
@@ -7536,14 +7509,14 b' let'
7536 sources."@polymer/paper-behaviors-3.0.1"
7509 sources."@polymer/paper-behaviors-3.0.1"
7537 sources."@polymer/paper-button-3.0.1"
7510 sources."@polymer/paper-button-3.0.1"
7538 sources."@polymer/paper-ripple-3.0.1"
7511 sources."@polymer/paper-ripple-3.0.1"
7539 sources."@polymer/paper-spinner-3.0.1"
7512 sources."@polymer/paper-spinner-3.0.2"
7540 sources."@polymer/paper-styles-3.0.1"
7513 sources."@polymer/paper-styles-3.0.1"
7541 sources."@polymer/paper-toast-3.0.1"
7514 sources."@polymer/paper-toast-3.0.1"
7542 sources."@polymer/paper-toggle-button-3.0.1"
7515 sources."@polymer/paper-toggle-button-3.0.1"
7543 sources."@polymer/paper-tooltip-3.0.1"
7516 sources."@polymer/paper-tooltip-3.0.1"
7544 sources."@polymer/polymer-3.1.0"
7517 sources."@polymer/polymer-3.2.0"
7545 sources."@types/clone-0.1.30"
7518 sources."@types/clone-0.1.30"
7546 sources."@types/node-6.14.2"
7519 sources."@types/node-6.14.6"
7547 sources."@types/parse5-2.2.34"
7520 sources."@types/parse5-2.2.34"
7548 sources."@webassemblyjs/ast-1.7.10"
7521 sources."@webassemblyjs/ast-1.7.10"
7549 sources."@webassemblyjs/floating-point-hex-parser-1.7.10"
7522 sources."@webassemblyjs/floating-point-hex-parser-1.7.10"
@@ -7563,8 +7536,8 b' let'
7563 sources."@webassemblyjs/wasm-parser-1.7.10"
7536 sources."@webassemblyjs/wasm-parser-1.7.10"
7564 sources."@webassemblyjs/wast-parser-1.7.10"
7537 sources."@webassemblyjs/wast-parser-1.7.10"
7565 sources."@webassemblyjs/wast-printer-1.7.10"
7538 sources."@webassemblyjs/wast-printer-1.7.10"
7566 sources."@webcomponents/shadycss-1.7.1"
7539 sources."@webcomponents/shadycss-1.9.1"
7567 sources."@webcomponents/webcomponentsjs-2.2.1"
7540 sources."@webcomponents/webcomponentsjs-2.2.10"
7568 sources."@xtuc/ieee754-1.2.0"
7541 sources."@xtuc/ieee754-1.2.0"
7569 sources."@xtuc/long-4.2.1"
7542 sources."@xtuc/long-4.2.1"
7570 sources."abbrev-1.1.1"
7543 sources."abbrev-1.1.1"
@@ -7576,7 +7549,7 b' let'
7576 ];
7549 ];
7577 })
7550 })
7578 sources."ajv-4.11.8"
7551 sources."ajv-4.11.8"
7579 sources."ajv-keywords-3.2.0"
7552 sources."ajv-keywords-3.4.0"
7580 (sources."align-text-0.1.4" // {
7553 (sources."align-text-0.1.4" // {
7581 dependencies = [
7554 dependencies = [
7582 sources."kind-of-3.2.2"
7555 sources."kind-of-3.2.2"
@@ -7586,7 +7559,11 b' let'
7586 sources."amdefine-1.0.1"
7559 sources."amdefine-1.0.1"
7587 sources."ansi-regex-0.2.1"
7560 sources."ansi-regex-0.2.1"
7588 sources."ansi-styles-1.1.0"
7561 sources."ansi-styles-1.1.0"
7589 sources."anymatch-2.0.0"
7562 (sources."anymatch-2.0.0" // {
7563 dependencies = [
7564 sources."normalize-path-2.1.1"
7565 ];
7566 })
7590 sources."appenlight-client-git+https://git@github.com/AppEnlight/appenlight-client-js.git#0.5.1"
7567 sources."appenlight-client-git+https://git@github.com/AppEnlight/appenlight-client-js.git#0.5.1"
7591 sources."aproba-1.2.0"
7568 sources."aproba-1.2.0"
7592 (sources."argparse-0.1.16" // {
7569 (sources."argparse-0.1.16" // {
@@ -7602,11 +7579,10 b' let'
7602 sources."array-union-1.0.2"
7579 sources."array-union-1.0.2"
7603 sources."array-uniq-1.0.3"
7580 sources."array-uniq-1.0.3"
7604 sources."array-unique-0.3.2"
7581 sources."array-unique-0.3.2"
7605 sources."arrify-1.0.1"
7606 sources."asap-2.0.6"
7582 sources."asap-2.0.6"
7607 sources."asn1-0.2.4"
7583 sources."asn1-0.2.4"
7608 sources."asn1.js-4.10.1"
7584 sources."asn1.js-4.10.1"
7609 (sources."assert-1.4.1" // {
7585 (sources."assert-1.5.0" // {
7610 dependencies = [
7586 dependencies = [
7611 sources."inherits-2.0.1"
7587 sources."inherits-2.0.1"
7612 sources."util-0.10.3"
7588 sources."util-0.10.3"
@@ -7616,7 +7592,7 b' let'
7616 sources."assign-symbols-1.0.0"
7592 sources."assign-symbols-1.0.0"
7617 sources."ast-types-0.9.6"
7593 sources."ast-types-0.9.6"
7618 sources."async-0.1.22"
7594 sources."async-0.1.22"
7619 sources."async-each-1.0.1"
7595 sources."async-each-1.0.3"
7620 sources."asynckit-0.4.0"
7596 sources."asynckit-0.4.0"
7621 sources."atob-2.1.2"
7597 sources."atob-2.1.2"
7622 (sources."autoprefixer-6.7.7" // {
7598 (sources."autoprefixer-6.7.7" // {
@@ -7738,8 +7714,8 b' let'
7738 sources."base64-js-1.3.0"
7714 sources."base64-js-1.3.0"
7739 sources."bcrypt-pbkdf-1.0.2"
7715 sources."bcrypt-pbkdf-1.0.2"
7740 sources."big.js-5.2.2"
7716 sources."big.js-5.2.2"
7741 sources."binary-extensions-1.12.0"
7717 sources."binary-extensions-1.13.1"
7742 sources."bluebird-3.5.3"
7718 sources."bluebird-3.5.4"
7743 sources."bn.js-4.11.8"
7719 sources."bn.js-4.11.8"
7744 sources."boolbase-1.0.0"
7720 sources."boolbase-1.0.0"
7745 sources."boom-2.10.1"
7721 sources."boom-2.10.1"
@@ -7763,7 +7739,7 b' let'
7763 sources."builtin-status-codes-3.0.0"
7739 sources."builtin-status-codes-3.0.0"
7764 (sources."cacache-10.0.4" // {
7740 (sources."cacache-10.0.4" // {
7765 dependencies = [
7741 dependencies = [
7766 sources."glob-7.1.3"
7742 sources."glob-7.1.4"
7767 sources."graceful-fs-4.1.15"
7743 sources."graceful-fs-4.1.15"
7768 sources."lru-cache-4.1.5"
7744 sources."lru-cache-4.1.5"
7769 sources."minimatch-3.0.4"
7745 sources."minimatch-3.0.4"
@@ -7772,20 +7748,20 b' let'
7772 })
7748 })
7773 sources."cache-base-1.0.1"
7749 sources."cache-base-1.0.1"
7774 sources."camel-case-3.0.0"
7750 sources."camel-case-3.0.0"
7775 sources."camelcase-5.0.0"
7751 sources."camelcase-5.3.1"
7776 (sources."caniuse-api-1.6.1" // {
7752 (sources."caniuse-api-1.6.1" // {
7777 dependencies = [
7753 dependencies = [
7778 sources."browserslist-1.7.7"
7754 sources."browserslist-1.7.7"
7779 ];
7755 ];
7780 })
7756 })
7781 sources."caniuse-db-1.0.30000927"
7757 sources."caniuse-db-1.0.30000967"
7782 sources."caniuse-lite-1.0.30000927"
7758 sources."caniuse-lite-1.0.30000967"
7783 sources."caseless-0.12.0"
7759 sources."caseless-0.12.0"
7784 sources."center-align-0.1.3"
7760 sources."center-align-0.1.3"
7785 sources."chalk-0.5.1"
7761 sources."chalk-0.5.1"
7786 (sources."chokidar-2.0.4" // {
7762 (sources."chokidar-2.1.5" // {
7787 dependencies = [
7763 dependencies = [
7788 sources."is-glob-4.0.0"
7764 sources."is-glob-4.0.1"
7789 ];
7765 ];
7790 })
7766 })
7791 sources."chownr-1.1.1"
7767 sources."chownr-1.1.1"
@@ -7825,7 +7801,7 b' let'
7825 })
7801 })
7826 (sources."cli-1.0.1" // {
7802 (sources."cli-1.0.1" // {
7827 dependencies = [
7803 dependencies = [
7828 sources."glob-7.1.3"
7804 sources."glob-7.1.4"
7829 sources."minimatch-3.0.4"
7805 sources."minimatch-3.0.4"
7830 ];
7806 ];
7831 })
7807 })
@@ -7848,10 +7824,10 b' let'
7848 sources."color-string-0.3.0"
7824 sources."color-string-0.3.0"
7849 sources."colormin-1.1.2"
7825 sources."colormin-1.1.2"
7850 sources."colors-0.6.2"
7826 sources."colors-0.6.2"
7851 sources."combined-stream-1.0.7"
7827 sources."combined-stream-1.0.8"
7852 sources."commander-2.14.1"
7828 sources."commander-2.14.1"
7853 sources."commondir-1.0.1"
7829 sources."commondir-1.0.1"
7854 sources."component-emitter-1.2.1"
7830 sources."component-emitter-1.3.0"
7855 sources."concat-map-0.0.1"
7831 sources."concat-map-0.0.1"
7856 (sources."concat-stream-1.6.2" // {
7832 (sources."concat-stream-1.6.2" // {
7857 dependencies = [
7833 dependencies = [
@@ -7864,7 +7840,7 b' let'
7864 sources."convert-source-map-1.6.0"
7840 sources."convert-source-map-1.6.0"
7865 (sources."copy-concurrently-1.0.5" // {
7841 (sources."copy-concurrently-1.0.5" // {
7866 dependencies = [
7842 dependencies = [
7867 sources."glob-7.1.3"
7843 sources."glob-7.1.4"
7868 sources."minimatch-3.0.4"
7844 sources."minimatch-3.0.4"
7869 sources."rimraf-2.6.3"
7845 sources."rimraf-2.6.3"
7870 ];
7846 ];
@@ -7872,11 +7848,11 b' let'
7872 sources."copy-descriptor-0.1.1"
7848 sources."copy-descriptor-0.1.1"
7873 (sources."copy-webpack-plugin-4.6.0" // {
7849 (sources."copy-webpack-plugin-4.6.0" // {
7874 dependencies = [
7850 dependencies = [
7875 sources."is-glob-4.0.0"
7851 sources."is-glob-4.0.1"
7876 sources."minimatch-3.0.4"
7852 sources."minimatch-3.0.4"
7877 ];
7853 ];
7878 })
7854 })
7879 sources."core-js-2.6.1"
7855 sources."core-js-2.6.5"
7880 sources."core-util-is-1.0.2"
7856 sources."core-util-is-1.0.2"
7881 sources."create-ecdh-4.0.3"
7857 sources."create-ecdh-4.0.3"
7882 sources."create-hash-1.2.0"
7858 sources."create-hash-1.2.0"
@@ -7896,7 +7872,7 b' let'
7896 sources."regexpu-core-1.0.0"
7872 sources."regexpu-core-1.0.0"
7897 ];
7873 ];
7898 })
7874 })
7899 sources."css-what-2.1.2"
7875 sources."css-what-2.1.3"
7900 sources."cssesc-0.1.0"
7876 sources."cssesc-0.1.0"
7901 sources."cssnano-3.10.0"
7877 sources."cssnano-3.10.0"
7902 sources."csso-2.3.2"
7878 sources."csso-2.3.2"
@@ -7921,11 +7897,10 b' let'
7921 sources."detect-file-1.0.0"
7897 sources."detect-file-1.0.0"
7922 sources."detect-indent-4.0.0"
7898 sources."detect-indent-4.0.0"
7923 sources."diffie-hellman-5.0.3"
7899 sources."diffie-hellman-5.0.3"
7924 sources."dir-glob-2.0.0"
7900 sources."dir-glob-2.2.2"
7925 sources."dom-converter-0.2.0"
7901 sources."dom-converter-0.2.0"
7926 (sources."dom-serializer-0.1.0" // {
7902 (sources."dom-serializer-0.1.1" // {
7927 dependencies = [
7903 dependencies = [
7928 sources."domelementtype-1.1.3"
7929 sources."entities-1.1.2"
7904 sources."entities-1.1.2"
7930 ];
7905 ];
7931 })
7906 })
@@ -7939,14 +7914,15 b' let'
7939 sources."domelementtype-1.3.1"
7914 sources."domelementtype-1.3.1"
7940 sources."domhandler-2.3.0"
7915 sources."domhandler-2.3.0"
7941 sources."domutils-1.5.1"
7916 sources."domutils-1.5.1"
7942 (sources."duplexify-3.6.1" // {
7917 sources."dropzone-5.5.1"
7918 (sources."duplexify-3.7.1" // {
7943 dependencies = [
7919 dependencies = [
7944 sources."readable-stream-2.3.6"
7920 sources."readable-stream-2.3.6"
7945 sources."string_decoder-1.1.1"
7921 sources."string_decoder-1.1.1"
7946 ];
7922 ];
7947 })
7923 })
7948 sources."ecc-jsbn-0.1.2"
7924 sources."ecc-jsbn-0.1.2"
7949 sources."electron-to-chromium-1.3.98"
7925 sources."electron-to-chromium-1.3.133"
7950 sources."elliptic-6.4.1"
7926 sources."elliptic-6.4.1"
7951 sources."emojis-list-2.1.0"
7927 sources."emojis-list-2.1.0"
7952 sources."end-of-stream-1.4.1"
7928 sources."end-of-stream-1.4.1"
@@ -7961,14 +7937,14 b' let'
7961 sources."es-to-primitive-1.2.0"
7937 sources."es-to-primitive-1.2.0"
7962 sources."es6-templates-0.2.3"
7938 sources."es6-templates-0.2.3"
7963 sources."escape-string-regexp-1.0.5"
7939 sources."escape-string-regexp-1.0.5"
7964 sources."eslint-scope-4.0.0"
7940 sources."eslint-scope-4.0.3"
7965 sources."espree-3.5.4"
7941 sources."espree-3.5.4"
7966 sources."esprima-1.0.4"
7942 sources."esprima-1.0.4"
7967 sources."esrecurse-4.2.1"
7943 sources."esrecurse-4.2.1"
7968 sources."estraverse-4.2.0"
7944 sources."estraverse-4.2.0"
7969 sources."esutils-2.0.2"
7945 sources."esutils-2.0.2"
7970 sources."eventemitter2-0.4.14"
7946 sources."eventemitter2-0.4.14"
7971 sources."events-1.1.1"
7947 sources."events-3.0.0"
7972 sources."evp_bytestokey-1.0.3"
7948 sources."evp_bytestokey-1.0.3"
7973 sources."execa-1.0.0"
7949 sources."execa-1.0.0"
7974 sources."exit-0.1.2"
7950 sources."exit-0.1.2"
@@ -8025,10 +8001,10 b' let'
8025 sources."minimatch-0.3.0"
8001 sources."minimatch-0.3.0"
8026 ];
8002 ];
8027 })
8003 })
8028 sources."fined-1.1.1"
8004 sources."fined-1.2.0"
8029 sources."flagged-respawn-1.0.1"
8005 sources."flagged-respawn-1.0.1"
8030 sources."flatten-1.0.2"
8006 sources."flatten-1.0.2"
8031 (sources."flush-write-stream-1.0.3" // {
8007 (sources."flush-write-stream-1.1.1" // {
8032 dependencies = [
8008 dependencies = [
8033 sources."readable-stream-2.3.6"
8009 sources."readable-stream-2.3.6"
8034 sources."string_decoder-1.1.1"
8010 sources."string_decoder-1.1.1"
@@ -8051,7 +8027,7 b' let'
8051 ];
8027 ];
8052 })
8028 })
8053 sources."fs.realpath-1.0.0"
8029 sources."fs.realpath-1.0.0"
8054 sources."fsevents-1.2.4"
8030 sources."fsevents-1.2.9"
8055 sources."function-bind-1.1.1"
8031 sources."function-bind-1.1.1"
8056 sources."gaze-0.5.2"
8032 sources."gaze-0.5.2"
8057 sources."get-caller-file-1.0.3"
8033 sources."get-caller-file-1.0.3"
@@ -8083,7 +8059,7 b' let'
8083 sources."globals-9.18.0"
8059 sources."globals-9.18.0"
8084 (sources."globby-7.1.1" // {
8060 (sources."globby-7.1.1" // {
8085 dependencies = [
8061 dependencies = [
8086 sources."glob-7.1.3"
8062 sources."glob-7.1.4"
8087 sources."minimatch-3.0.4"
8063 sources."minimatch-3.0.4"
8088 ];
8064 ];
8089 })
8065 })
@@ -8115,12 +8091,18 b' let'
8115 sources."supports-color-2.0.0"
8091 sources."supports-color-2.0.0"
8116 ];
8092 ];
8117 })
8093 })
8118 sources."grunt-contrib-jshint-0.12.0"
8094 (sources."grunt-contrib-jshint-0.12.0" // {
8095 dependencies = [
8096 sources."jshint-2.9.7"
8097 sources."lodash-4.17.11"
8098 sources."minimatch-3.0.4"
8099 ];
8100 })
8119 (sources."grunt-contrib-less-1.4.1" // {
8101 (sources."grunt-contrib-less-1.4.1" // {
8120 dependencies = [
8102 dependencies = [
8121 sources."ansi-regex-2.1.1"
8103 sources."ansi-regex-2.1.1"
8122 sources."ansi-styles-2.2.1"
8104 sources."ansi-styles-2.2.1"
8123 sources."async-2.6.1"
8105 sources."async-2.6.2"
8124 sources."chalk-1.1.3"
8106 sources."chalk-1.1.3"
8125 sources."has-ansi-2.0.0"
8107 sources."has-ansi-2.0.0"
8126 sources."lodash-4.17.11"
8108 sources."lodash-4.17.11"
@@ -8172,7 +8154,7 b' let'
8172 sources."hmac-drbg-1.0.1"
8154 sources."hmac-drbg-1.0.1"
8173 sources."hoek-2.16.3"
8155 sources."hoek-2.16.3"
8174 sources."home-or-tmp-2.0.0"
8156 sources."home-or-tmp-2.0.0"
8175 sources."homedir-polyfill-1.0.1"
8157 sources."homedir-polyfill-1.0.3"
8176 sources."hooker-0.2.3"
8158 sources."hooker-0.2.3"
8177 sources."html-comment-regex-1.1.2"
8159 sources."html-comment-regex-1.1.2"
8178 sources."html-loader-0.4.5"
8160 sources."html-loader-0.4.5"
@@ -8203,7 +8185,7 b' let'
8203 sources."supports-color-5.5.0"
8185 sources."supports-color-5.5.0"
8204 ];
8186 ];
8205 })
8187 })
8206 sources."ieee754-1.1.12"
8188 sources."ieee754-1.1.13"
8207 sources."iferr-0.1.5"
8189 sources."iferr-0.1.5"
8208 sources."ignore-3.3.10"
8190 sources."ignore-3.3.10"
8209 sources."image-size-0.5.5"
8191 sources."image-size-0.5.5"
@@ -8211,9 +8193,9 b' let'
8211 dependencies = [
8193 dependencies = [
8212 sources."find-up-3.0.0"
8194 sources."find-up-3.0.0"
8213 sources."locate-path-3.0.0"
8195 sources."locate-path-3.0.0"
8214 sources."p-limit-2.1.0"
8196 sources."p-limit-2.2.0"
8215 sources."p-locate-3.0.0"
8197 sources."p-locate-3.0.0"
8216 sources."p-try-2.0.0"
8198 sources."p-try-2.2.0"
8217 sources."pkg-dir-3.0.0"
8199 sources."pkg-dir-3.0.0"
8218 ];
8200 ];
8219 })
8201 })
@@ -8261,12 +8243,12 b' let'
8261 sources."isobject-3.0.1"
8243 sources."isobject-3.0.1"
8262 sources."isstream-0.1.2"
8244 sources."isstream-0.1.2"
8263 sources."jquery-1.11.3"
8245 sources."jquery-1.11.3"
8264 sources."js-base64-2.5.0"
8246 sources."js-base64-2.5.1"
8265 sources."js-tokens-3.0.2"
8247 sources."js-tokens-3.0.2"
8266 sources."js-yaml-2.0.5"
8248 sources."js-yaml-2.0.5"
8267 sources."jsbn-0.1.1"
8249 sources."jsbn-0.1.1"
8268 sources."jsesc-1.3.0"
8250 sources."jsesc-1.3.0"
8269 (sources."jshint-2.9.7" // {
8251 (sources."jshint-2.10.2" // {
8270 dependencies = [
8252 dependencies = [
8271 sources."lodash-4.17.11"
8253 sources."lodash-4.17.11"
8272 sources."minimatch-3.0.4"
8254 sources."minimatch-3.0.4"
@@ -8297,12 +8279,11 b' let'
8297 sources."findup-sync-2.0.0"
8279 sources."findup-sync-2.0.0"
8298 ];
8280 ];
8299 })
8281 })
8300 sources."loader-runner-2.3.1"
8282 sources."loader-runner-2.4.0"
8301 sources."loader-utils-1.2.3"
8283 sources."loader-utils-1.2.3"
8302 sources."locate-path-2.0.0"
8284 sources."locate-path-2.0.0"
8303 sources."lodash-0.9.2"
8285 sources."lodash-0.9.2"
8304 sources."lodash.camelcase-4.3.0"
8286 sources."lodash.camelcase-4.3.0"
8305 sources."lodash.debounce-4.0.8"
8306 sources."lodash.isplainobject-4.0.6"
8287 sources."lodash.isplainobject-4.0.6"
8307 sources."lodash.memoize-4.1.2"
8288 sources."lodash.memoize-4.1.2"
8308 sources."lodash.uniq-4.5.0"
8289 sources."lodash.uniq-4.5.0"
@@ -8318,7 +8299,7 b' let'
8318 sources."mark.js-8.11.1"
8299 sources."mark.js-8.11.1"
8319 sources."math-expression-evaluator-1.2.17"
8300 sources."math-expression-evaluator-1.2.17"
8320 sources."md5.js-1.3.5"
8301 sources."md5.js-1.3.5"
8321 sources."mem-4.0.0"
8302 sources."mem-4.3.0"
8322 (sources."memory-fs-0.4.1" // {
8303 (sources."memory-fs-0.4.1" // {
8323 dependencies = [
8304 dependencies = [
8324 sources."readable-stream-2.3.6"
8305 sources."readable-stream-2.3.6"
@@ -8328,9 +8309,9 b' let'
8328 sources."micromatch-3.1.10"
8309 sources."micromatch-3.1.10"
8329 sources."miller-rabin-4.0.1"
8310 sources."miller-rabin-4.0.1"
8330 sources."mime-1.6.0"
8311 sources."mime-1.6.0"
8331 sources."mime-db-1.37.0"
8312 sources."mime-db-1.40.0"
8332 sources."mime-types-2.1.21"
8313 sources."mime-types-2.1.24"
8333 sources."mimic-fn-1.2.0"
8314 sources."mimic-fn-2.1.0"
8334 sources."minimalistic-assert-1.0.1"
8315 sources."minimalistic-assert-1.0.1"
8335 sources."minimalistic-crypto-utils-1.0.1"
8316 sources."minimalistic-crypto-utils-1.0.1"
8336 sources."minimatch-0.2.14"
8317 sources."minimatch-0.2.14"
@@ -8346,22 +8327,22 b' let'
8346 sources."minimist-0.0.8"
8327 sources."minimist-0.0.8"
8347 ];
8328 ];
8348 })
8329 })
8349 sources."moment-2.23.0"
8330 sources."moment-2.24.0"
8350 sources."mousetrap-1.6.2"
8331 sources."mousetrap-1.6.3"
8351 (sources."move-concurrently-1.0.1" // {
8332 (sources."move-concurrently-1.0.1" // {
8352 dependencies = [
8333 dependencies = [
8353 sources."glob-7.1.3"
8334 sources."glob-7.1.4"
8354 sources."minimatch-3.0.4"
8335 sources."minimatch-3.0.4"
8355 sources."rimraf-2.6.3"
8336 sources."rimraf-2.6.3"
8356 ];
8337 ];
8357 })
8338 })
8358 sources."ms-2.0.0"
8339 sources."ms-2.0.0"
8359 sources."nan-2.12.1"
8340 sources."nan-2.13.2"
8360 sources."nanomatch-1.2.13"
8341 sources."nanomatch-1.2.13"
8361 sources."neo-async-2.6.0"
8342 sources."neo-async-2.6.1"
8362 sources."nice-try-1.0.5"
8343 sources."nice-try-1.0.5"
8363 sources."no-case-2.3.2"
8344 sources."no-case-2.3.2"
8364 (sources."node-libs-browser-2.1.0" // {
8345 (sources."node-libs-browser-2.2.0" // {
8365 dependencies = [
8346 dependencies = [
8366 (sources."readable-stream-2.3.6" // {
8347 (sources."readable-stream-2.3.6" // {
8367 dependencies = [
8348 dependencies = [
@@ -8377,7 +8358,7 b' let'
8377 sources."nopt-2.0.0"
8358 sources."nopt-2.0.0"
8378 ];
8359 ];
8379 })
8360 })
8380 sources."normalize-path-2.1.1"
8361 sources."normalize-path-3.0.0"
8381 sources."normalize-range-0.1.2"
8362 sources."normalize-range-0.1.2"
8382 sources."normalize-url-1.9.1"
8363 sources."normalize-url-1.9.1"
8383 sources."npm-run-path-2.0.2"
8364 sources."npm-run-path-2.0.2"
@@ -8399,7 +8380,7 b' let'
8399 sources."kind-of-3.2.2"
8380 sources."kind-of-3.2.2"
8400 ];
8381 ];
8401 })
8382 })
8402 sources."object-keys-1.0.12"
8383 sources."object-keys-1.1.1"
8403 sources."object-visit-1.0.1"
8384 sources."object-visit-1.0.1"
8404 sources."object.defaults-1.1.0"
8385 sources."object.defaults-1.1.0"
8405 sources."object.getownpropertydescriptors-2.0.3"
8386 sources."object.getownpropertydescriptors-2.0.3"
@@ -8413,11 +8394,11 b' let'
8413 sources."osenv-0.1.5"
8394 sources."osenv-0.1.5"
8414 sources."p-defer-1.0.0"
8395 sources."p-defer-1.0.0"
8415 sources."p-finally-1.0.0"
8396 sources."p-finally-1.0.0"
8416 sources."p-is-promise-1.1.0"
8397 sources."p-is-promise-2.1.0"
8417 sources."p-limit-1.3.0"
8398 sources."p-limit-1.3.0"
8418 sources."p-locate-2.0.0"
8399 sources."p-locate-2.0.0"
8419 sources."p-try-1.0.0"
8400 sources."p-try-1.0.0"
8420 sources."pako-1.0.7"
8401 sources."pako-1.0.10"
8421 (sources."parallel-transform-1.1.0" // {
8402 (sources."parallel-transform-1.1.0" // {
8422 dependencies = [
8403 dependencies = [
8423 sources."readable-stream-2.3.6"
8404 sources."readable-stream-2.3.6"
@@ -8425,7 +8406,7 b' let'
8425 ];
8406 ];
8426 })
8407 })
8427 sources."param-case-2.1.1"
8408 sources."param-case-2.1.1"
8428 sources."parse-asn1-5.1.1"
8409 sources."parse-asn1-5.1.4"
8429 sources."parse-filepath-1.0.2"
8410 sources."parse-filepath-1.0.2"
8430 sources."parse-passwd-1.0.0"
8411 sources."parse-passwd-1.0.0"
8431 sources."parse5-3.0.3"
8412 sources."parse5-3.0.3"
@@ -8564,7 +8545,7 b' let'
8564 sources."query-string-4.3.4"
8545 sources."query-string-4.3.4"
8565 sources."querystring-0.2.0"
8546 sources."querystring-0.2.0"
8566 sources."querystring-es3-0.2.1"
8547 sources."querystring-es3-0.2.1"
8567 sources."randombytes-2.0.6"
8548 sources."randombytes-2.1.0"
8568 sources."randomfill-1.0.4"
8549 sources."randomfill-1.0.4"
8569 sources."raw-loader-1.0.0-beta.0"
8550 sources."raw-loader-1.0.0-beta.0"
8570 (sources."readable-stream-1.1.14" // {
8551 (sources."readable-stream-1.1.14" // {
@@ -8608,14 +8589,9 b' let'
8608 })
8589 })
8609 sources."relateurl-0.2.7"
8590 sources."relateurl-0.2.7"
8610 sources."remove-trailing-separator-1.1.0"
8591 sources."remove-trailing-separator-1.1.0"
8611 (sources."renderkid-2.0.2" // {
8592 (sources."renderkid-2.0.3" // {
8612 dependencies = [
8593 dependencies = [
8613 sources."ansi-regex-2.1.1"
8594 sources."ansi-regex-2.1.1"
8614 sources."domhandler-2.1.0"
8615 sources."domutils-1.1.6"
8616 sources."htmlparser2-3.3.0"
8617 sources."isarray-0.0.1"
8618 sources."readable-stream-1.0.34"
8619 sources."strip-ansi-3.0.1"
8595 sources."strip-ansi-3.0.1"
8620 ];
8596 ];
8621 })
8597 })
@@ -8625,7 +8601,7 b' let'
8625 sources."request-2.81.0"
8601 sources."request-2.81.0"
8626 sources."require-directory-2.1.1"
8602 sources."require-directory-2.1.1"
8627 sources."require-main-filename-1.0.1"
8603 sources."require-main-filename-1.0.1"
8628 sources."resolve-1.9.0"
8604 sources."resolve-1.10.1"
8629 sources."resolve-cwd-2.0.0"
8605 sources."resolve-cwd-2.0.0"
8630 sources."resolve-dir-1.0.1"
8606 sources."resolve-dir-1.0.1"
8631 sources."resolve-from-3.0.0"
8607 sources."resolve-from-3.0.0"
@@ -8641,12 +8617,12 b' let'
8641 sources."sax-1.2.4"
8617 sources."sax-1.2.4"
8642 (sources."schema-utils-0.4.7" // {
8618 (sources."schema-utils-0.4.7" // {
8643 dependencies = [
8619 dependencies = [
8644 sources."ajv-6.6.2"
8620 sources."ajv-6.10.0"
8645 ];
8621 ];
8646 })
8622 })
8647 sources."select-1.1.2"
8623 sources."select-1.1.2"
8648 sources."semver-5.6.0"
8624 sources."semver-5.7.0"
8649 sources."serialize-javascript-1.6.1"
8625 sources."serialize-javascript-1.7.0"
8650 sources."set-blocking-2.0.0"
8626 sources."set-blocking-2.0.0"
8651 (sources."set-value-2.0.0" // {
8627 (sources."set-value-2.0.0" // {
8652 dependencies = [
8628 dependencies = [
@@ -8698,7 +8674,7 b' let'
8698 sources."source-map-url-0.4.0"
8674 sources."source-map-url-0.4.0"
8699 sources."split-string-3.1.0"
8675 sources."split-string-3.1.0"
8700 sources."sprintf-js-1.0.3"
8676 sources."sprintf-js-1.0.3"
8701 (sources."sshpk-1.16.0" // {
8677 (sources."sshpk-1.16.1" // {
8702 dependencies = [
8678 dependencies = [
8703 sources."assert-plus-1.0.0"
8679 sources."assert-plus-1.0.0"
8704 ];
8680 ];
@@ -8722,7 +8698,7 b' let'
8722 ];
8698 ];
8723 })
8699 })
8724 sources."sticky-sidebar-3.3.1"
8700 sources."sticky-sidebar-3.3.1"
8725 (sources."stream-browserify-2.0.1" // {
8701 (sources."stream-browserify-2.0.2" // {
8726 dependencies = [
8702 dependencies = [
8727 sources."readable-stream-2.3.6"
8703 sources."readable-stream-2.3.6"
8728 sources."string_decoder-1.1.1"
8704 sources."string_decoder-1.1.1"
@@ -8759,7 +8735,7 b' let'
8759 sources."js-yaml-3.7.0"
8735 sources."js-yaml-3.7.0"
8760 ];
8736 ];
8761 })
8737 })
8762 sources."tapable-1.1.1"
8738 sources."tapable-1.1.3"
8763 sources."through-2.3.8"
8739 sources."through-2.3.8"
8764 (sources."through2-2.0.5" // {
8740 (sources."through2-2.0.5" // {
8765 dependencies = [
8741 dependencies = [
@@ -8768,7 +8744,7 b' let'
8768 ];
8744 ];
8769 })
8745 })
8770 sources."timers-browserify-2.0.10"
8746 sources."timers-browserify-2.0.10"
8771 sources."tiny-emitter-2.0.2"
8747 sources."tiny-emitter-2.1.0"
8772 (sources."tiny-lr-fork-0.0.5" // {
8748 (sources."tiny-lr-fork-0.0.5" // {
8773 dependencies = [
8749 dependencies = [
8774 sources."debug-0.7.4"
8750 sources."debug-0.7.4"
@@ -8808,9 +8784,9 b' let'
8808 sources."source-map-0.6.1"
8784 sources."source-map-0.6.1"
8809 ];
8785 ];
8810 })
8786 })
8811 (sources."uglify-js-3.4.9" // {
8787 (sources."uglify-js-3.4.10" // {
8812 dependencies = [
8788 dependencies = [
8813 sources."commander-2.17.1"
8789 sources."commander-2.19.0"
8814 sources."source-map-0.6.1"
8790 sources."source-map-0.6.1"
8815 ];
8791 ];
8816 })
8792 })
@@ -8843,7 +8819,7 b' let'
8843 sources."has-values-0.1.4"
8819 sources."has-values-0.1.4"
8844 ];
8820 ];
8845 })
8821 })
8846 sources."upath-1.1.0"
8822 sources."upath-1.1.2"
8847 sources."upper-case-1.1.3"
8823 sources."upper-case-1.1.3"
8848 (sources."uri-js-4.2.2" // {
8824 (sources."uri-js-4.2.2" // {
8849 dependencies = [
8825 dependencies = [
@@ -8857,14 +8833,14 b' let'
8857 ];
8833 ];
8858 })
8834 })
8859 sources."use-3.1.1"
8835 sources."use-3.1.1"
8860 sources."util-0.10.4"
8836 sources."util-0.11.1"
8861 sources."util-deprecate-1.0.2"
8837 sources."util-deprecate-1.0.2"
8862 sources."util.promisify-1.0.0"
8838 sources."util.promisify-1.0.0"
8863 sources."utila-0.4.0"
8839 sources."utila-0.4.0"
8864 sources."uuid-3.3.2"
8840 sources."uuid-3.3.2"
8865 sources."v8-compile-cache-2.0.2"
8841 sources."v8-compile-cache-2.0.3"
8866 sources."v8flags-3.1.2"
8842 sources."v8flags-3.1.3"
8867 sources."vendors-1.0.2"
8843 sources."vendors-1.0.3"
8868 (sources."verror-1.10.0" // {
8844 (sources."verror-1.10.0" // {
8869 dependencies = [
8845 dependencies = [
8870 sources."assert-plus-1.0.0"
8846 sources."assert-plus-1.0.0"
@@ -8879,7 +8855,7 b' let'
8879 sources."waypoints-4.0.1"
8855 sources."waypoints-4.0.1"
8880 (sources."webpack-4.23.1" // {
8856 (sources."webpack-4.23.1" // {
8881 dependencies = [
8857 dependencies = [
8882 sources."ajv-6.6.2"
8858 sources."ajv-6.10.0"
8883 ];
8859 ];
8884 })
8860 })
8885 (sources."webpack-cli-3.1.2" // {
8861 (sources."webpack-cli-3.1.2" // {
@@ -8919,7 +8895,7 b' let'
8919 sources."which-module-2.0.0"
8895 sources."which-module-2.0.0"
8920 sources."window-size-0.1.0"
8896 sources."window-size-0.1.0"
8921 sources."wordwrap-0.0.2"
8897 sources."wordwrap-0.0.2"
8922 sources."worker-farm-1.6.0"
8898 sources."worker-farm-1.7.0"
8923 (sources."wrap-ansi-2.1.0" // {
8899 (sources."wrap-ansi-2.1.0" // {
8924 dependencies = [
8900 dependencies = [
8925 sources."ansi-regex-2.1.1"
8901 sources."ansi-regex-2.1.1"
@@ -8935,9 +8911,9 b' let'
8935 dependencies = [
8911 dependencies = [
8936 sources."find-up-3.0.0"
8912 sources."find-up-3.0.0"
8937 sources."locate-path-3.0.0"
8913 sources."locate-path-3.0.0"
8938 sources."p-limit-2.1.0"
8914 sources."p-limit-2.2.0"
8939 sources."p-locate-3.0.0"
8915 sources."p-locate-3.0.0"
8940 sources."p-try-2.0.0"
8916 sources."p-try-2.2.0"
8941 ];
8917 ];
8942 })
8918 })
8943 sources."yargs-parser-11.1.1"
8919 sources."yargs-parser-11.1.1"
@@ -35,6 +35,18 b' self: super: {'
35 ];
35 ];
36 });
36 });
37
37
38 "cffi" = super."cffi".override (attrs: {
39 buildInputs = [
40 pkgs.libffi
41 ];
42 });
43
44 "cryptography" = super."cryptography".override (attrs: {
45 buildInputs = [
46 pkgs.openssl
47 ];
48 });
49
38 "gevent" = super."gevent".override (attrs: {
50 "gevent" = super."gevent".override (attrs: {
39 propagatedBuildInputs = attrs.propagatedBuildInputs ++ [
51 propagatedBuildInputs = attrs.propagatedBuildInputs ++ [
40 # NOTE: (marcink) odd requirements from gevent aren't set properly,
52 # NOTE: (marcink) odd requirements from gevent aren't set properly,
@@ -152,12 +164,6 b' self: super: {'
152 };
164 };
153 });
165 });
154
166
155 "pytest-runner" = super."pytest-runner".override (attrs: {
156 propagatedBuildInputs = [
157 self."setuptools-scm"
158 ];
159 });
160
161 "python-ldap" = super."python-ldap".override (attrs: {
167 "python-ldap" = super."python-ldap".override (attrs: {
162 propagatedBuildInputs = attrs.propagatedBuildInputs ++ [
168 propagatedBuildInputs = attrs.propagatedBuildInputs ++ [
163 pkgs.openldap
169 pkgs.openldap
@@ -5,7 +5,7 b''
5
5
6 self: super: {
6 self: super: {
7 "alembic" = super.buildPythonPackage {
7 "alembic" = super.buildPythonPackage {
8 name = "alembic-1.0.5";
8 name = "alembic-1.0.10";
9 doCheck = false;
9 doCheck = false;
10 propagatedBuildInputs = [
10 propagatedBuildInputs = [
11 self."sqlalchemy"
11 self."sqlalchemy"
@@ -14,8 +14,8 b' self: super: {'
14 self."python-dateutil"
14 self."python-dateutil"
15 ];
15 ];
16 src = fetchurl {
16 src = fetchurl {
17 url = "https://files.pythonhosted.org/packages/1c/65/b8e4f5b2f345bb13b5e0a3fddd892b0b3f0e8ad4880e954fdc6a50d00d84/alembic-1.0.5.tar.gz";
17 url = "https://files.pythonhosted.org/packages/6e/8b/fa3bd058cccd5e9177fea4efa26bfb769228fdd3178436ad5e05830ef6ef/alembic-1.0.10.tar.gz";
18 sha256 = "0rpjqp2iq6p49x1nli18ivak1izz547nnjxi110mzrgc1v7dxzz9";
18 sha256 = "1dwl0264r6ri2jyrjr68am04x538ab26xwy4crqjnnhm4alwm3c2";
19 };
19 };
20 meta = {
20 meta = {
21 license = [ pkgs.lib.licenses.mit ];
21 license = [ pkgs.lib.licenses.mit ];
@@ -51,6 +51,17 b' self: super: {'
51 license = [ pkgs.lib.licenses.bsdOriginal ];
51 license = [ pkgs.lib.licenses.bsdOriginal ];
52 };
52 };
53 };
53 };
54 "asn1crypto" = super.buildPythonPackage {
55 name = "asn1crypto-0.24.0";
56 doCheck = false;
57 src = fetchurl {
58 url = "https://files.pythonhosted.org/packages/fc/f1/8db7daa71f414ddabfa056c4ef792e1461ff655c2ae2928a2b675bfed6b4/asn1crypto-0.24.0.tar.gz";
59 sha256 = "0jaf8rf9dx1lf23xfv2cdd5h52f1qr3w8k63985bc35g3d220p4x";
60 };
61 meta = {
62 license = [ pkgs.lib.licenses.mit ];
63 };
64 };
54 "atomicwrites" = super.buildPythonPackage {
65 "atomicwrites" = super.buildPythonPackage {
55 name = "atomicwrites-1.2.1";
66 name = "atomicwrites-1.2.1";
56 doCheck = false;
67 doCheck = false;
@@ -77,8 +88,8 b' self: super: {'
77 name = "authomatic-0.1.0.post1";
88 name = "authomatic-0.1.0.post1";
78 doCheck = false;
89 doCheck = false;
79 src = fetchurl {
90 src = fetchurl {
80 url = "https://code.rhodecode.com/upstream/authomatic/archive/90a9ce60cc405ae8a2bf5c3713acd5d78579a04e.tar.gz?md5=3c68720a1322b25254009518d1ff6801";
91 url = "https://code.rhodecode.com/upstream/authomatic/artifacts/download/0-4fe9c041-a567-4f84-be4c-7efa2a606d3c.tar.gz?md5=f6bdc3c769688212db68233e8d2b0383";
81 sha256 = "1cgk0a86sbsjbri06gf5z5l4npwkjdxw6fdnwl4vvfmxs2sx9yxw";
92 sha256 = "0pc716mva0ym6xd8jwzjbjp8dqxy9069wwwv2aqwb8lyhl4757ab";
82 };
93 };
83 meta = {
94 meta = {
84 license = [ pkgs.lib.licenses.mit ];
95 license = [ pkgs.lib.licenses.mit ];
@@ -146,15 +157,15 b' self: super: {'
146 };
157 };
147 };
158 };
148 "bleach" = super.buildPythonPackage {
159 "bleach" = super.buildPythonPackage {
149 name = "bleach-3.0.2";
160 name = "bleach-3.1.0";
150 doCheck = false;
161 doCheck = false;
151 propagatedBuildInputs = [
162 propagatedBuildInputs = [
152 self."six"
163 self."six"
153 self."webencodings"
164 self."webencodings"
154 ];
165 ];
155 src = fetchurl {
166 src = fetchurl {
156 url = "https://files.pythonhosted.org/packages/ae/31/680afc7d44040004296a2d8f0584983c2f2386448cd9d0964197e6c1160e/bleach-3.0.2.tar.gz";
167 url = "https://files.pythonhosted.org/packages/78/5a/0df03e8735cd9c75167528299c738702437589b9c71a849489d00ffa82e8/bleach-3.1.0.tar.gz";
157 sha256 = "06474zg7f73hv8h1xw2wcsmvn2ygj73zxgxxqg8zcx8ap1srdls8";
168 sha256 = "1yhrgrhkln8bd6gn3imj69g1h4xqah9gaz9q26crqr6gmmvpzprz";
158 };
169 };
159 meta = {
170 meta = {
160 license = [ pkgs.lib.licenses.asl20 ];
171 license = [ pkgs.lib.licenses.asl20 ];
@@ -187,6 +198,20 b' self: super: {'
187 license = [ pkgs.lib.licenses.bsdOriginal ];
198 license = [ pkgs.lib.licenses.bsdOriginal ];
188 };
199 };
189 };
200 };
201 "cffi" = super.buildPythonPackage {
202 name = "cffi-1.12.2";
203 doCheck = false;
204 propagatedBuildInputs = [
205 self."pycparser"
206 ];
207 src = fetchurl {
208 url = "https://files.pythonhosted.org/packages/64/7c/27367b38e6cc3e1f49f193deb761fe75cda9f95da37b67b422e62281fcac/cffi-1.12.2.tar.gz";
209 sha256 = "19qfks2djya8vix95bmg3xzipjb8w9b8mbj4j5k2hqkc8j58f4z1";
210 };
211 meta = {
212 license = [ pkgs.lib.licenses.mit ];
213 };
214 };
190 "chameleon" = super.buildPythonPackage {
215 "chameleon" = super.buildPythonPackage {
191 name = "chameleon-2.24";
216 name = "chameleon-2.24";
192 doCheck = false;
217 doCheck = false;
@@ -230,7 +255,7 b' self: super: {'
230 };
255 };
231 };
256 };
232 "colander" = super.buildPythonPackage {
257 "colander" = super.buildPythonPackage {
233 name = "colander-1.5.1";
258 name = "colander-1.7.0";
234 doCheck = false;
259 doCheck = false;
235 propagatedBuildInputs = [
260 propagatedBuildInputs = [
236 self."translationstring"
261 self."translationstring"
@@ -238,8 +263,8 b' self: super: {'
238 self."enum34"
263 self."enum34"
239 ];
264 ];
240 src = fetchurl {
265 src = fetchurl {
241 url = "https://files.pythonhosted.org/packages/ec/d1/fcca811a0a692c69d27e36b4d11a73acb98b4bab48323442642b6fd4386d/colander-1.5.1.tar.gz";
266 url = "https://files.pythonhosted.org/packages/db/e4/74ab06f54211917b41865cafc987ce511e35503de48da9bfe9358a1bdc3e/colander-1.7.0.tar.gz";
242 sha256 = "18ah4cwwxnpm6qxi6x9ipy51dal4spd343h44s5wd01cnhgrwsyq";
267 sha256 = "1wl1bqab307lbbcjx81i28s3yl6dlm4rf15fxawkjb6j48x1cn6p";
243 };
268 };
244 meta = {
269 meta = {
245 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
270 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
@@ -252,19 +277,19 b' self: super: {'
252 self."six"
277 self."six"
253 ];
278 ];
254 src = fetchurl {
279 src = fetchurl {
255 url = "https://code.rhodecode.com/upstream/configobj/archive/a11ff0a0bd4fbda9e3a91267e720f88329efb4a6.tar.gz?md5=9916c524ea11a6c418217af6b28d4b3c";
280 url = "https://code.rhodecode.com/upstream/configobj/artifacts/download/0-012de99a-b1e1-4f64-a5c0-07a98a41b324.tar.gz?md5=6a513f51fe04b2c18cf84c1395a7c626";
256 sha256 = "1hhcxirwvg58grlfr177b3awhbq8hlx1l3lh69ifl1ki7lfd1s1x";
281 sha256 = "0kqfrdfr14mw8yd8qwq14dv2xghpkjmd3yjsy8dfcbvpcc17xnxp";
257 };
282 };
258 meta = {
283 meta = {
259 license = [ pkgs.lib.licenses.bsdOriginal ];
284 license = [ pkgs.lib.licenses.bsdOriginal ];
260 };
285 };
261 };
286 };
262 "configparser" = super.buildPythonPackage {
287 "configparser" = super.buildPythonPackage {
263 name = "configparser-3.7.1";
288 name = "configparser-3.7.4";
264 doCheck = false;
289 doCheck = false;
265 src = fetchurl {
290 src = fetchurl {
266 url = "https://files.pythonhosted.org/packages/b6/a6/eceea7c5a5dbcf56815bed411c38cabd8a879386be10717b160e7362b5a2/configparser-3.7.1.tar.gz";
291 url = "https://files.pythonhosted.org/packages/e2/1c/83fd53748d8245cb9a3399f705c251d3fc0ce7df04450aac1cfc49dd6a0f/configparser-3.7.4.tar.gz";
267 sha256 = "0cnz213il9lhgda6x70fw7mfqr8da43s3wm343lwzhqx94mgmmav";
292 sha256 = "0xac32886ihs2xg7w1gppcq2sgin5qsm8lqwijs5xifq9w0x0q6s";
268 };
293 };
269 meta = {
294 meta = {
270 license = [ pkgs.lib.licenses.mit ];
295 license = [ pkgs.lib.licenses.mit ];
@@ -285,16 +310,34 b' self: super: {'
285 };
310 };
286 };
311 };
287 "coverage" = super.buildPythonPackage {
312 "coverage" = super.buildPythonPackage {
288 name = "coverage-4.5.1";
313 name = "coverage-4.5.3";
289 doCheck = false;
314 doCheck = false;
290 src = fetchurl {
315 src = fetchurl {
291 url = "https://files.pythonhosted.org/packages/35/fe/e7df7289d717426093c68d156e0fd9117c8f4872b6588e8a8928a0f68424/coverage-4.5.1.tar.gz";
316 url = "https://files.pythonhosted.org/packages/82/70/2280b5b29a0352519bb95ab0ef1ea942d40466ca71c53a2085bdeff7b0eb/coverage-4.5.3.tar.gz";
292 sha256 = "1wbrzpxka3xd4nmmkc6q0ir343d91kymwsm8pbmwa0d2a7q4ir2n";
317 sha256 = "02f6m073qdispn96rc616hg0rnmw1pgqzw3bgxwiwza4zf9hirlx";
293 };
318 };
294 meta = {
319 meta = {
295 license = [ pkgs.lib.licenses.asl20 ];
320 license = [ pkgs.lib.licenses.asl20 ];
296 };
321 };
297 };
322 };
323 "cryptography" = super.buildPythonPackage {
324 name = "cryptography-2.6.1";
325 doCheck = false;
326 propagatedBuildInputs = [
327 self."asn1crypto"
328 self."six"
329 self."cffi"
330 self."enum34"
331 self."ipaddress"
332 ];
333 src = fetchurl {
334 url = "https://files.pythonhosted.org/packages/07/ca/bc827c5e55918ad223d59d299fff92f3563476c3b00d0a9157d9c0217449/cryptography-2.6.1.tar.gz";
335 sha256 = "19iwz5avym5zl6jrrrkym1rdaa9h61j20ph4cswsqgv8xg5j3j16";
336 };
337 meta = {
338 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "BSD or Apache License, Version 2.0"; } pkgs.lib.licenses.asl20 ];
339 };
340 };
298 "cssselect" = super.buildPythonPackage {
341 "cssselect" = super.buildPythonPackage {
299 name = "cssselect-1.0.3";
342 name = "cssselect-1.0.3";
300 doCheck = false;
343 doCheck = false;
@@ -337,11 +380,11 b' self: super: {'
337 };
380 };
338 };
381 };
339 "defusedxml" = super.buildPythonPackage {
382 "defusedxml" = super.buildPythonPackage {
340 name = "defusedxml-0.5.0";
383 name = "defusedxml-0.6.0";
341 doCheck = false;
384 doCheck = false;
342 src = fetchurl {
385 src = fetchurl {
343 url = "https://files.pythonhosted.org/packages/74/ba/4ba4e89e21b5a2e267d80736ea674609a0a33cc4435a6d748ef04f1f9374/defusedxml-0.5.0.tar.gz";
386 url = "https://files.pythonhosted.org/packages/a4/5f/f8aa58ca0cf01cbcee728abc9d88bfeb74e95e6cb4334cfd5bed5673ea77/defusedxml-0.6.0.tar.gz";
344 sha256 = "1x54n0h8hl92vvwyymx883fbqpqjwn2mc8fb383bcg3z9zwz5mr4";
387 sha256 = "1xbp8fivl3wlbyg2jrvs4lalaqv1xp9a9f29p75wdx2s2d6h717n";
345 };
388 };
346 meta = {
389 meta = {
347 license = [ pkgs.lib.licenses.psfl ];
390 license = [ pkgs.lib.licenses.psfl ];
@@ -399,11 +442,11 b' self: super: {'
399 };
442 };
400 };
443 };
401 "ecdsa" = super.buildPythonPackage {
444 "ecdsa" = super.buildPythonPackage {
402 name = "ecdsa-0.13";
445 name = "ecdsa-0.13.2";
403 doCheck = false;
446 doCheck = false;
404 src = fetchurl {
447 src = fetchurl {
405 url = "https://files.pythonhosted.org/packages/f9/e5/99ebb176e47f150ac115ffeda5fedb6a3dbb3c00c74a59fd84ddf12f5857/ecdsa-0.13.tar.gz";
448 url = "https://files.pythonhosted.org/packages/51/76/139bf6e9b7b6684d5891212cdbd9e0739f2bfc03f380a1a6ffa700f392ac/ecdsa-0.13.2.tar.gz";
406 sha256 = "1yj31j0asmrx4an9xvsaj2icdmzy6pw0glfpqrrkrphwdpi1xkv4";
449 sha256 = "116qaq7bh4lcynzi613960jhsnn19v0kmsqwahiwjfj14gx4y0sw";
407 };
450 };
408 meta = {
451 meta = {
409 license = [ pkgs.lib.licenses.mit ];
452 license = [ pkgs.lib.licenses.mit ];
@@ -491,8 +534,8 b' self: super: {'
491 self."configparser"
534 self."configparser"
492 ];
535 ];
493 src = fetchurl {
536 src = fetchurl {
494 url = "https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313";
537 url = "https://code.rhodecode.com/upstream/entrypoints/artifacts/download/0-8e9ee9e4-c4db-409c-b07e-81568fd1832d.tar.gz?md5=3a027b8ff1d257b91fe257de6c43357d";
495 sha256 = "0bihrdp8ahsys437kxdhk52gz6kib8rxjv71i93wkw7594fcaxll";
538 sha256 = "0qih72n2myclanplqipqxpgpj9d2yhff1pz5d02zq1cfqyd173w5";
496 };
539 };
497 meta = {
540 meta = {
498 license = [ pkgs.lib.licenses.mit ];
541 license = [ pkgs.lib.licenses.mit ];
@@ -623,11 +666,11 b' self: super: {'
623 };
666 };
624 };
667 };
625 "hupper" = super.buildPythonPackage {
668 "hupper" = super.buildPythonPackage {
626 name = "hupper-1.4.2";
669 name = "hupper-1.6.1";
627 doCheck = false;
670 doCheck = false;
628 src = fetchurl {
671 src = fetchurl {
629 url = "https://files.pythonhosted.org/packages/f1/75/1915dc7650b4867fa3049256e24ca8eddb5989998fcec788cf52b9812dfc/hupper-1.4.2.tar.gz";
672 url = "https://files.pythonhosted.org/packages/85/d9/e005d357b11249c5d70ddf5b7adab2e4c0da4e8b0531ff146917a04fe6c0/hupper-1.6.1.tar.gz";
630 sha256 = "16vb9fkiaakdpcp6pn56h3w0dwvm67bxq2k2dv4i382qhqwphdzb";
673 sha256 = "0d3cvkc8ssgwk54wvhbifj56ry97qi10pfzwfk8vwzzcikbfp3zy";
631 };
674 };
632 meta = {
675 meta = {
633 license = [ pkgs.lib.licenses.mit ];
676 license = [ pkgs.lib.licenses.mit ];
@@ -671,15 +714,15 b' self: super: {'
671 };
714 };
672 };
715 };
673 "ipdb" = super.buildPythonPackage {
716 "ipdb" = super.buildPythonPackage {
674 name = "ipdb-0.11";
717 name = "ipdb-0.12";
675 doCheck = false;
718 doCheck = false;
676 propagatedBuildInputs = [
719 propagatedBuildInputs = [
677 self."setuptools"
720 self."setuptools"
678 self."ipython"
721 self."ipython"
679 ];
722 ];
680 src = fetchurl {
723 src = fetchurl {
681 url = "https://files.pythonhosted.org/packages/80/fe/4564de08f174f3846364b3add8426d14cebee228f741c27e702b2877e85b/ipdb-0.11.tar.gz";
724 url = "https://files.pythonhosted.org/packages/6d/43/c3c2e866a8803e196d6209595020a4a6db1a3c5d07c01455669497ae23d0/ipdb-0.12.tar.gz";
682 sha256 = "02m0l8wrhhd3z7dg3czn5ys1g5pxib516hpshdzp7rxzsxgcd0bh";
725 sha256 = "1khr2n7xfy8hg65kj1bsrjq9g7656pp0ybfa8abpbzpdawji3qnw";
683 };
726 };
684 meta = {
727 meta = {
685 license = [ pkgs.lib.licenses.bsdOriginal ];
728 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -802,14 +845,14 b' self: super: {'
802 };
845 };
803 };
846 };
804 "jupyter-core" = super.buildPythonPackage {
847 "jupyter-core" = super.buildPythonPackage {
805 name = "jupyter-core-4.4.0";
848 name = "jupyter-core-4.5.0";
806 doCheck = false;
849 doCheck = false;
807 propagatedBuildInputs = [
850 propagatedBuildInputs = [
808 self."traitlets"
851 self."traitlets"
809 ];
852 ];
810 src = fetchurl {
853 src = fetchurl {
811 url = "https://files.pythonhosted.org/packages/b6/2d/2804f4de3a95583f65e5dcb4d7c8c7183124882323758996e867f47e72af/jupyter_core-4.4.0.tar.gz";
854 url = "https://files.pythonhosted.org/packages/4a/de/ff4ca734656d17ebe0450807b59d728f45277e2e7f4b82bc9aae6cb82961/jupyter_core-4.5.0.tar.gz";
812 sha256 = "1dy083rarba8prn9f9srxq3c7n7vyql02ycrqq306c40lr57aw5s";
855 sha256 = "1xr4pbghwk5hayn5wwnhb7z95380r45p79gf5if5pi1akwg7qvic";
813 };
856 };
814 meta = {
857 meta = {
815 license = [ pkgs.lib.licenses.bsdOriginal ];
858 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -1008,14 +1051,14 b' self: super: {'
1008 };
1051 };
1009 };
1052 };
1010 "paste" = super.buildPythonPackage {
1053 "paste" = super.buildPythonPackage {
1011 name = "paste-3.0.5";
1054 name = "paste-3.0.8";
1012 doCheck = false;
1055 doCheck = false;
1013 propagatedBuildInputs = [
1056 propagatedBuildInputs = [
1014 self."six"
1057 self."six"
1015 ];
1058 ];
1016 src = fetchurl {
1059 src = fetchurl {
1017 url = "https://files.pythonhosted.org/packages/d4/41/91bde422400786b1b06357c1e6e3a5379f54dc3002aeb337cb767233304e/Paste-3.0.5.tar.gz";
1060 url = "https://files.pythonhosted.org/packages/66/65/e3acf1663438483c1f6ced0b6c6f3b90da9f0faacb0a6e2aa0f3f9f4b235/Paste-3.0.8.tar.gz";
1018 sha256 = "1a6i8fh1fg8r4x800fvy9r82m15clwjim6yf2g9r4dff0y40dchv";
1061 sha256 = "05w1sh6ky4d7pmdb8nv82n13w22jcn3qsagg5ih3hjmbws9kkwf4";
1019 };
1062 };
1020 meta = {
1063 meta = {
1021 license = [ pkgs.lib.licenses.mit ];
1064 license = [ pkgs.lib.licenses.mit ];
@@ -1033,7 +1076,7 b' self: super: {'
1033 };
1076 };
1034 };
1077 };
1035 "pastescript" = super.buildPythonPackage {
1078 "pastescript" = super.buildPythonPackage {
1036 name = "pastescript-3.0.0";
1079 name = "pastescript-3.1.0";
1037 doCheck = false;
1080 doCheck = false;
1038 propagatedBuildInputs = [
1081 propagatedBuildInputs = [
1039 self."paste"
1082 self."paste"
@@ -1041,23 +1084,23 b' self: super: {'
1041 self."six"
1084 self."six"
1042 ];
1085 ];
1043 src = fetchurl {
1086 src = fetchurl {
1044 url = "https://files.pythonhosted.org/packages/08/2a/3797377a884ab9a064ad4d564ed612e54d26d7997caa8229c9c9df4eac31/PasteScript-3.0.0.tar.gz";
1087 url = "https://files.pythonhosted.org/packages/9e/1d/14db1c283eb21a5d36b6ba1114c13b709629711e64acab653d9994fe346f/PasteScript-3.1.0.tar.gz";
1045 sha256 = "1hvmyz1sbn7ws1syw567ph7km9fi0wi75r3vlyzx6sk0z26xkm6r";
1088 sha256 = "02qcxjjr32ks7a6d4f533wl34ysc7yhwlrfcyqwqbzr52250v4fs";
1046 };
1089 };
1047 meta = {
1090 meta = {
1048 license = [ pkgs.lib.licenses.mit ];
1091 license = [ pkgs.lib.licenses.mit ];
1049 };
1092 };
1050 };
1093 };
1051 "pathlib2" = super.buildPythonPackage {
1094 "pathlib2" = super.buildPythonPackage {
1052 name = "pathlib2-2.3.3";
1095 name = "pathlib2-2.3.4";
1053 doCheck = false;
1096 doCheck = false;
1054 propagatedBuildInputs = [
1097 propagatedBuildInputs = [
1055 self."six"
1098 self."six"
1056 self."scandir"
1099 self."scandir"
1057 ];
1100 ];
1058 src = fetchurl {
1101 src = fetchurl {
1059 url = "https://files.pythonhosted.org/packages/bf/d7/a2568f4596b75d2c6e2b4094a7e64f620decc7887f69a1f2811931ea15b9/pathlib2-2.3.3.tar.gz";
1102 url = "https://files.pythonhosted.org/packages/b5/f4/9c7cc726ece2498b6c8b62d3262aa43f59039b953fe23c9964ac5e18d40b/pathlib2-2.3.4.tar.gz";
1060 sha256 = "0hpp92vqqgcd8h92msm9slv161b1q160igjwnkf2ag6cx0c96695";
1103 sha256 = "1y0f9rkm1924zrc5dn4bwxlhgdkbml82lkcc28l5rgmr7d918q24";
1061 };
1104 };
1062 meta = {
1105 meta = {
1063 license = [ pkgs.lib.licenses.mit ];
1106 license = [ pkgs.lib.licenses.mit ];
@@ -1075,14 +1118,14 b' self: super: {'
1075 };
1118 };
1076 };
1119 };
1077 "pexpect" = super.buildPythonPackage {
1120 "pexpect" = super.buildPythonPackage {
1078 name = "pexpect-4.6.0";
1121 name = "pexpect-4.7.0";
1079 doCheck = false;
1122 doCheck = false;
1080 propagatedBuildInputs = [
1123 propagatedBuildInputs = [
1081 self."ptyprocess"
1124 self."ptyprocess"
1082 ];
1125 ];
1083 src = fetchurl {
1126 src = fetchurl {
1084 url = "https://files.pythonhosted.org/packages/89/43/07d07654ee3e25235d8cea4164cdee0ec39d1fda8e9203156ebe403ffda4/pexpect-4.6.0.tar.gz";
1127 url = "https://files.pythonhosted.org/packages/1c/b1/362a0d4235496cb42c33d1d8732b5e2c607b0129ad5fdd76f5a583b9fcb3/pexpect-4.7.0.tar.gz";
1085 sha256 = "1fla85g47iaxxpjhp9vkxdnv4pgc7rplfy6ja491smrrk0jqi3ia";
1128 sha256 = "1sv2rri15zwhds85a4kamwh9pj49qcxv7m4miyr4jfpfwv81yb4y";
1086 };
1129 };
1087 meta = {
1130 meta = {
1088 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
1131 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
@@ -1117,63 +1160,63 b' self: super: {'
1117 };
1160 };
1118 };
1161 };
1119 "plaster-pastedeploy" = super.buildPythonPackage {
1162 "plaster-pastedeploy" = super.buildPythonPackage {
1120 name = "plaster-pastedeploy-0.6";
1163 name = "plaster-pastedeploy-0.7";
1121 doCheck = false;
1164 doCheck = false;
1122 propagatedBuildInputs = [
1165 propagatedBuildInputs = [
1123 self."pastedeploy"
1166 self."pastedeploy"
1124 self."plaster"
1167 self."plaster"
1125 ];
1168 ];
1126 src = fetchurl {
1169 src = fetchurl {
1127 url = "https://files.pythonhosted.org/packages/3f/e7/6a6833158d2038ec40085433308a1e164fd1dac595513f6dd556d5669bb8/plaster_pastedeploy-0.6.tar.gz";
1170 url = "https://files.pythonhosted.org/packages/99/69/2d3bc33091249266a1bd3cf24499e40ab31d54dffb4a7d76fe647950b98c/plaster_pastedeploy-0.7.tar.gz";
1128 sha256 = "1bkggk18f4z2bmsmxyxabvf62znvjwbivzh880419r3ap0616cf2";
1171 sha256 = "1zg7gcsvc1kzay1ry5p699rg2qavfsxqwl17mqxzr0gzw6j9679r";
1129 };
1172 };
1130 meta = {
1173 meta = {
1131 license = [ pkgs.lib.licenses.mit ];
1174 license = [ pkgs.lib.licenses.mit ];
1132 };
1175 };
1133 };
1176 };
1134 "pluggy" = super.buildPythonPackage {
1177 "pluggy" = super.buildPythonPackage {
1135 name = "pluggy-0.8.1";
1178 name = "pluggy-0.11.0";
1136 doCheck = false;
1179 doCheck = false;
1137 src = fetchurl {
1180 src = fetchurl {
1138 url = "https://files.pythonhosted.org/packages/38/e1/83b10c17688af7b2998fa5342fec58ecbd2a5a7499f31e606ae6640b71ac/pluggy-0.8.1.tar.gz";
1181 url = "https://files.pythonhosted.org/packages/0d/a1/862ab336e8128fde20981d2c1aa8506693412daf5083b1911d539412676b/pluggy-0.11.0.tar.gz";
1139 sha256 = "05l6g42p9ilmabw0hlbiyxy6gyzjri41m5l11a8dzgvi77q35p4d";
1182 sha256 = "10511a54dvafw1jrk75mrhml53c7b7w4yaw7241696lc2hfvr895";
1140 };
1183 };
1141 meta = {
1184 meta = {
1142 license = [ pkgs.lib.licenses.mit ];
1185 license = [ pkgs.lib.licenses.mit ];
1143 };
1186 };
1144 };
1187 };
1145 "prompt-toolkit" = super.buildPythonPackage {
1188 "prompt-toolkit" = super.buildPythonPackage {
1146 name = "prompt-toolkit-1.0.15";
1189 name = "prompt-toolkit-1.0.16";
1147 doCheck = false;
1190 doCheck = false;
1148 propagatedBuildInputs = [
1191 propagatedBuildInputs = [
1149 self."six"
1192 self."six"
1150 self."wcwidth"
1193 self."wcwidth"
1151 ];
1194 ];
1152 src = fetchurl {
1195 src = fetchurl {
1153 url = "https://files.pythonhosted.org/packages/8a/ad/cf6b128866e78ad6d7f1dc5b7f99885fb813393d9860778b2984582e81b5/prompt_toolkit-1.0.15.tar.gz";
1196 url = "https://files.pythonhosted.org/packages/f1/03/bb36771dc9fa7553ac4bdc639a9ecdf6fda0ff4176faf940d97e3c16e41d/prompt_toolkit-1.0.16.tar.gz";
1154 sha256 = "05v9h5nydljwpj5nm8n804ms0glajwfy1zagrzqrg91wk3qqi1c5";
1197 sha256 = "1d65hm6nf0cbq0q0121m60zzy4s1fpg9fn761s1yxf08dridvkn1";
1155 };
1198 };
1156 meta = {
1199 meta = {
1157 license = [ pkgs.lib.licenses.bsdOriginal ];
1200 license = [ pkgs.lib.licenses.bsdOriginal ];
1158 };
1201 };
1159 };
1202 };
1160 "psutil" = super.buildPythonPackage {
1203 "psutil" = super.buildPythonPackage {
1161 name = "psutil-5.4.8";
1204 name = "psutil-5.5.1";
1162 doCheck = false;
1205 doCheck = false;
1163 src = fetchurl {
1206 src = fetchurl {
1164 url = "https://files.pythonhosted.org/packages/e3/58/0eae6e4466e5abf779d7e2b71fac7fba5f59e00ea36ddb3ed690419ccb0f/psutil-5.4.8.tar.gz";
1207 url = "https://files.pythonhosted.org/packages/c7/01/7c30b247cdc5ba29623faa5c8cf1f1bbf7e041783c340414b0ed7e067c64/psutil-5.5.1.tar.gz";
1165 sha256 = "1hyna338sml2cl1mfb2gs89np18z27mvyhmq4ifh22x07n7mq9kf";
1208 sha256 = "045qaqvn6k90bj5bcy259yrwcd2afgznaav3sfhphy9b8ambzkkj";
1166 };
1209 };
1167 meta = {
1210 meta = {
1168 license = [ pkgs.lib.licenses.bsdOriginal ];
1211 license = [ pkgs.lib.licenses.bsdOriginal ];
1169 };
1212 };
1170 };
1213 };
1171 "psycopg2" = super.buildPythonPackage {
1214 "psycopg2" = super.buildPythonPackage {
1172 name = "psycopg2-2.7.5";
1215 name = "psycopg2-2.8.3";
1173 doCheck = false;
1216 doCheck = false;
1174 src = fetchurl {
1217 src = fetchurl {
1175 url = "https://files.pythonhosted.org/packages/b2/c1/7bf6c464e903ffc4f3f5907c389e5a4199666bf57f6cd6bf46c17912a1f9/psycopg2-2.7.5.tar.gz";
1218 url = "https://files.pythonhosted.org/packages/5c/1c/6997288da181277a0c29bc39a5f9143ff20b8c99f2a7d059cfb55163e165/psycopg2-2.8.3.tar.gz";
1176 sha256 = "17klx964gw8z0znl0raz3by8vdc7cq5gxj4pdcrfcina84nrdkzc";
1219 sha256 = "0ms4kx0p5n281l89awccix4d05ybmdngnjjpi9jbzd0rhf1nwyl9";
1177 };
1220 };
1178 meta = {
1221 meta = {
1179 license = [ pkgs.lib.licenses.zpl21 { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "LGPL with exceptions or ZPL"; } ];
1222 license = [ pkgs.lib.licenses.zpl21 { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "LGPL with exceptions or ZPL"; } ];
@@ -1239,14 +1282,25 b' self: super: {'
1239 };
1282 };
1240 };
1283 };
1241 "pyasn1-modules" = super.buildPythonPackage {
1284 "pyasn1-modules" = super.buildPythonPackage {
1242 name = "pyasn1-modules-0.2.4";
1285 name = "pyasn1-modules-0.2.5";
1243 doCheck = false;
1286 doCheck = false;
1244 propagatedBuildInputs = [
1287 propagatedBuildInputs = [
1245 self."pyasn1"
1288 self."pyasn1"
1246 ];
1289 ];
1247 src = fetchurl {
1290 src = fetchurl {
1248 url = "https://files.pythonhosted.org/packages/bd/a5/ef7bf693e8a8f015386c9167483199f54f8a8ec01d1c737e05524f16e792/pyasn1-modules-0.2.4.tar.gz";
1291 url = "https://files.pythonhosted.org/packages/ec/0b/69620cb04a016e4a1e8e352e8a42717862129b574b3479adb2358a1f12f7/pyasn1-modules-0.2.5.tar.gz";
1249 sha256 = "0z3w5dqrrvdplg9ma45j8n23xvyrj9ki8mg4ibqbn7l4qpl90855";
1292 sha256 = "15nvfx0vnl8akdlv3k6s0n80vqvryj82bm040jdsn7wmyxl1ywpg";
1293 };
1294 meta = {
1295 license = [ pkgs.lib.licenses.bsdOriginal ];
1296 };
1297 };
1298 "pycparser" = super.buildPythonPackage {
1299 name = "pycparser-2.19";
1300 doCheck = false;
1301 src = fetchurl {
1302 url = "https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz";
1303 sha256 = "1cr5dcj9628lkz1qlwq3fv97c25363qppkmcayqvd05dpy573259";
1250 };
1304 };
1251 meta = {
1305 meta = {
1252 license = [ pkgs.lib.licenses.bsdOriginal ];
1306 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -1274,23 +1328,12 b' self: super: {'
1274 license = [ pkgs.lib.licenses.mit { fullName = "LGPL/MIT"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ];
1328 license = [ pkgs.lib.licenses.mit { fullName = "LGPL/MIT"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ];
1275 };
1329 };
1276 };
1330 };
1277 "pyflakes" = super.buildPythonPackage {
1331 "pygments" = super.buildPythonPackage {
1278 name = "pyflakes-0.8.1";
1332 name = "pygments-2.4.2";
1279 doCheck = false;
1333 doCheck = false;
1280 src = fetchurl {
1334 src = fetchurl {
1281 url = "https://files.pythonhosted.org/packages/75/22/a90ec0252f4f87f3ffb6336504de71fe16a49d69c4538dae2f12b9360a38/pyflakes-0.8.1.tar.gz";
1335 url = "https://files.pythonhosted.org/packages/7e/ae/26808275fc76bf2832deb10d3a3ed3107bc4de01b85dcccbe525f2cd6d1e/Pygments-2.4.2.tar.gz";
1282 sha256 = "0sbpq6pqm1i9wqi41mlfrsc5rk92jv4mskvlyxmnhlbdnc80ma1z";
1336 sha256 = "15v2sqm5g12bqa0c7wikfh9ck2nl97ayizy1hpqhmws5gqalq748";
1283 };
1284 meta = {
1285 license = [ pkgs.lib.licenses.mit ];
1286 };
1287 };
1288 "pygments" = super.buildPythonPackage {
1289 name = "pygments-2.3.1";
1290 doCheck = false;
1291 src = fetchurl {
1292 url = "https://files.pythonhosted.org/packages/64/69/413708eaf3a64a6abb8972644e0f20891a55e621c6759e2c3f3891e05d63/Pygments-2.3.1.tar.gz";
1293 sha256 = "0ji87g09jph8jqcvclgb02qvxasdnr9pzvk90rl66d90yqcxmyjz";
1294 };
1337 };
1295 meta = {
1338 meta = {
1296 license = [ pkgs.lib.licenses.bsdOriginal ];
1339 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -1330,7 +1373,7 b' self: super: {'
1330 };
1373 };
1331 };
1374 };
1332 "pyramid" = super.buildPythonPackage {
1375 "pyramid" = super.buildPythonPackage {
1333 name = "pyramid-1.10.1";
1376 name = "pyramid-1.10.4";
1334 doCheck = false;
1377 doCheck = false;
1335 propagatedBuildInputs = [
1378 propagatedBuildInputs = [
1336 self."hupper"
1379 self."hupper"
@@ -1345,28 +1388,13 b' self: super: {'
1345 self."repoze.lru"
1388 self."repoze.lru"
1346 ];
1389 ];
1347 src = fetchurl {
1390 src = fetchurl {
1348 url = "https://files.pythonhosted.org/packages/0a/3e/22e3ac9be1b70a01139adba8906ee4b8f628bb469fea3c52f6c97b73063c/pyramid-1.10.1.tar.gz";
1391 url = "https://files.pythonhosted.org/packages/c2/43/1ae701c9c6bb3a434358e678a5e72c96e8aa55cf4cb1d2fa2041b5dd38b7/pyramid-1.10.4.tar.gz";
1349 sha256 = "1h5105nfh6rsrfjiyw20aavyibj36la3hajy6vh1fa77xb4y3hrp";
1392 sha256 = "0rkxs1ajycg2zh1c94xlmls56mx5m161sn8112skj0amza6cn36q";
1350 };
1393 };
1351 meta = {
1394 meta = {
1352 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1395 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1353 };
1396 };
1354 };
1397 };
1355 "pyramid-beaker" = super.buildPythonPackage {
1356 name = "pyramid-beaker-0.8";
1357 doCheck = false;
1358 propagatedBuildInputs = [
1359 self."pyramid"
1360 self."beaker"
1361 ];
1362 src = fetchurl {
1363 url = "https://files.pythonhosted.org/packages/d9/6e/b85426e00fd3d57f4545f74e1c3828552d8700f13ededeef9233f7bca8be/pyramid_beaker-0.8.tar.gz";
1364 sha256 = "0hflx3qkcdml1mwpq53sz46s7jickpfn0zy0ns2c7j445j66bp3p";
1365 };
1366 meta = {
1367 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1368 };
1369 };
1370 "pyramid-debugtoolbar" = super.buildPythonPackage {
1398 "pyramid-debugtoolbar" = super.buildPythonPackage {
1371 name = "pyramid-debugtoolbar-4.5";
1399 name = "pyramid-debugtoolbar-4.5";
1372 doCheck = false;
1400 doCheck = false;
@@ -1538,14 +1566,14 b' self: super: {'
1538 };
1566 };
1539 };
1567 };
1540 "python-dateutil" = super.buildPythonPackage {
1568 "python-dateutil" = super.buildPythonPackage {
1541 name = "python-dateutil-2.7.5";
1569 name = "python-dateutil-2.8.0";
1542 doCheck = false;
1570 doCheck = false;
1543 propagatedBuildInputs = [
1571 propagatedBuildInputs = [
1544 self."six"
1572 self."six"
1545 ];
1573 ];
1546 src = fetchurl {
1574 src = fetchurl {
1547 url = "https://files.pythonhosted.org/packages/0e/01/68747933e8d12263d41ce08119620d9a7e5eb72c876a3442257f74490da0/python-dateutil-2.7.5.tar.gz";
1575 url = "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz";
1548 sha256 = "00ngwcdw36w5b37b51mdwn3qxid9zdf3kpffv2q6n9kl05y2iyc8";
1576 sha256 = "17nsfhy4xdz1khrfxa61vd7pmvd5z0wa3zb6v4gb4kfnykv0b668";
1549 };
1577 };
1550 meta = {
1578 meta = {
1551 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.asl20 { fullName = "Dual License"; } ];
1579 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.asl20 { fullName = "Dual License"; } ];
@@ -1690,7 +1718,7 b' self: super: {'
1690 };
1718 };
1691 };
1719 };
1692 "rhodecode-enterprise-ce" = super.buildPythonPackage {
1720 "rhodecode-enterprise-ce" = super.buildPythonPackage {
1693 name = "rhodecode-enterprise-ce-4.16.2";
1721 name = "rhodecode-enterprise-ce-4.17.0";
1694 buildInputs = [
1722 buildInputs = [
1695 self."pytest"
1723 self."pytest"
1696 self."py"
1724 self."py"
@@ -1709,36 +1737,29 b' self: super: {'
1709 ];
1737 ];
1710 doCheck = true;
1738 doCheck = true;
1711 propagatedBuildInputs = [
1739 propagatedBuildInputs = [
1712 self."setuptools-scm"
1713 self."amqp"
1740 self."amqp"
1714 self."authomatic"
1741 self."authomatic"
1715 self."atomicwrites"
1716 self."attrs"
1717 self."babel"
1742 self."babel"
1718 self."beaker"
1743 self."beaker"
1719 self."bleach"
1744 self."bleach"
1720 self."celery"
1745 self."celery"
1721 self."chameleon"
1722 self."channelstream"
1746 self."channelstream"
1723 self."click"
1747 self."click"
1724 self."colander"
1748 self."colander"
1725 self."configobj"
1749 self."configobj"
1726 self."cssselect"
1750 self."cssselect"
1751 self."cryptography"
1727 self."decorator"
1752 self."decorator"
1728 self."deform"
1753 self."deform"
1729 self."docutils"
1754 self."docutils"
1730 self."dogpile.cache"
1755 self."dogpile.cache"
1731 self."dogpile.core"
1756 self."dogpile.core"
1732 self."ecdsa"
1733 self."formencode"
1757 self."formencode"
1734 self."future"
1758 self."future"
1735 self."futures"
1759 self."futures"
1736 self."gnureadline"
1737 self."infrae.cache"
1760 self."infrae.cache"
1738 self."iso8601"
1761 self."iso8601"
1739 self."itsdangerous"
1762 self."itsdangerous"
1740 self."jinja2"
1741 self."billiard"
1742 self."kombu"
1763 self."kombu"
1743 self."lxml"
1764 self."lxml"
1744 self."mako"
1765 self."mako"
@@ -1747,21 +1768,18 b' self: super: {'
1747 self."msgpack-python"
1768 self."msgpack-python"
1748 self."pyotp"
1769 self."pyotp"
1749 self."packaging"
1770 self."packaging"
1771 self."pathlib2"
1750 self."paste"
1772 self."paste"
1751 self."pastedeploy"
1773 self."pastedeploy"
1752 self."pastescript"
1774 self."pastescript"
1753 self."pathlib2"
1754 self."peppercorn"
1775 self."peppercorn"
1755 self."psutil"
1776 self."psutil"
1756 self."py-bcrypt"
1777 self."py-bcrypt"
1778 self."pycurl"
1757 self."pycrypto"
1779 self."pycrypto"
1758 self."pycurl"
1759 self."pyflakes"
1760 self."pygments"
1780 self."pygments"
1761 self."pyparsing"
1781 self."pyparsing"
1762 self."pyramid-beaker"
1763 self."pyramid-debugtoolbar"
1782 self."pyramid-debugtoolbar"
1764 self."pyramid-jinja2"
1765 self."pyramid-mako"
1783 self."pyramid-mako"
1766 self."pyramid"
1784 self."pyramid"
1767 self."pyramid-mailer"
1785 self."pyramid-mailer"
@@ -1784,7 +1802,6 b' self: super: {'
1784 self."sshpubkeys"
1802 self."sshpubkeys"
1785 self."subprocess32"
1803 self."subprocess32"
1786 self."supervisor"
1804 self."supervisor"
1787 self."tempita"
1788 self."translationstring"
1805 self."translationstring"
1789 self."urllib3"
1806 self."urllib3"
1790 self."urlobject"
1807 self."urlobject"
@@ -1813,7 +1830,6 b' self: super: {'
1813 self."greenlet"
1830 self."greenlet"
1814 self."gunicorn"
1831 self."gunicorn"
1815 self."waitress"
1832 self."waitress"
1816 self."setproctitle"
1817 self."ipdb"
1833 self."ipdb"
1818 self."ipython"
1834 self."ipython"
1819 self."rhodecode-tools"
1835 self."rhodecode-tools"
@@ -1855,8 +1871,8 b' self: super: {'
1855 self."elasticsearch1-dsl"
1871 self."elasticsearch1-dsl"
1856 ];
1872 ];
1857 src = fetchurl {
1873 src = fetchurl {
1858 url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v1.2.1.tar.gz?md5=25bc2f7de1da318e547236d3fb463d28";
1874 url = "https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-10ac93f4-bb7d-4b97-baea-68110743dd5a.tar.gz?md5=962dc77c06aceee62282b98d33149661";
1859 sha256 = "1k8l3s4mvshza1zay6dfxprq54fyb5dc85dqdva9wa3f466y0adk";
1875 sha256 = "1vfhgf46inbx7jvlfx4fdzh3vz7lh37r291gzb5hx447pfm3qllg";
1860 };
1876 };
1861 meta = {
1877 meta = {
1862 license = [ { fullName = "Apache 2.0 and Proprietary"; } ];
1878 license = [ { fullName = "Apache 2.0 and Proprietary"; } ];
@@ -1878,11 +1894,11 b' self: super: {'
1878 };
1894 };
1879 };
1895 };
1880 "scandir" = super.buildPythonPackage {
1896 "scandir" = super.buildPythonPackage {
1881 name = "scandir-1.9.0";
1897 name = "scandir-1.10.0";
1882 doCheck = false;
1898 doCheck = false;
1883 src = fetchurl {
1899 src = fetchurl {
1884 url = "https://files.pythonhosted.org/packages/16/2a/557af1181e6b4e30254d5a6163b18f5053791ca66e251e77ab08887e8fe3/scandir-1.9.0.tar.gz";
1900 url = "https://files.pythonhosted.org/packages/df/f5/9c052db7bd54d0cbf1bc0bb6554362bba1012d03e5888950a4f5c5dadc4e/scandir-1.10.0.tar.gz";
1885 sha256 = "0r3hvf1a9jm1rkqgx40gxkmccknkaiqjavs8lccgq9s8khh5x5s4";
1901 sha256 = "1bkqwmf056pkchf05ywbnf659wqlp6lljcdb0y88wr9f0vv32ijd";
1886 };
1902 };
1887 meta = {
1903 meta = {
1888 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ];
1904 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ];
@@ -1900,22 +1916,11 b' self: super: {'
1900 };
1916 };
1901 };
1917 };
1902 "setuptools" = super.buildPythonPackage {
1918 "setuptools" = super.buildPythonPackage {
1903 name = "setuptools-40.8.0";
1919 name = "setuptools-41.0.1";
1904 doCheck = false;
1920 doCheck = false;
1905 src = fetchurl {
1921 src = fetchurl {
1906 url = "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip";
1922 url = "https://files.pythonhosted.org/packages/1d/64/a18a487b4391a05b9c7f938b94a16d80305bf0369c6b0b9509e86165e1d3/setuptools-41.0.1.zip";
1907 sha256 = "0k9hifpgahnw2a26w3cr346iy733k6d3nwh3f7g9m13y6f8fqkkf";
1923 sha256 = "04sns22y2hhsrwfy1mha2lgslvpjsjsz8xws7h2rh5a7ylkd28m2";
1908 };
1909 meta = {
1910 license = [ pkgs.lib.licenses.mit ];
1911 };
1912 };
1913 "setuptools-scm" = super.buildPythonPackage {
1914 name = "setuptools-scm-2.1.0";
1915 doCheck = false;
1916 src = fetchurl {
1917 url = "https://files.pythonhosted.org/packages/e5/62/f9e1ac314464eb5945c97542acb6bf6f3381dfa5d7a658de7730c36f31a1/setuptools_scm-2.1.0.tar.gz";
1918 sha256 = "0yb364cgk15sfw3x8ln4ssh98z1dj6n8iiz4r2rw1cfsxhgi8rx7";
1919 };
1924 };
1920 meta = {
1925 meta = {
1921 license = [ pkgs.lib.licenses.mit ];
1926 license = [ pkgs.lib.licenses.mit ];
@@ -1966,40 +1971,40 b' self: super: {'
1966 };
1971 };
1967 };
1972 };
1968 "sshpubkeys" = super.buildPythonPackage {
1973 "sshpubkeys" = super.buildPythonPackage {
1969 name = "sshpubkeys-2.2.0";
1974 name = "sshpubkeys-3.1.0";
1970 doCheck = false;
1975 doCheck = false;
1971 propagatedBuildInputs = [
1976 propagatedBuildInputs = [
1972 self."pycrypto"
1977 self."cryptography"
1973 self."ecdsa"
1978 self."ecdsa"
1974 ];
1979 ];
1975 src = fetchurl {
1980 src = fetchurl {
1976 url = "https://files.pythonhosted.org/packages/27/da/337fabeb3dca6b62039a93ceaa636f25065e0ae92b575b1235342076cf0a/sshpubkeys-2.2.0.tar.gz";
1981 url = "https://files.pythonhosted.org/packages/00/23/f7508a12007c96861c3da811992f14283d79c819d71a217b3e12d5196649/sshpubkeys-3.1.0.tar.gz";
1977 sha256 = "0r4kpwzmg96a2x56pllik7dmc3fnqk189v3sfgsi07q2ryrhr6xm";
1982 sha256 = "105g2li04nm1hb15a2y6hm9m9k7fbrkd5l3gy12w3kgcmsf3k25k";
1978 };
1983 };
1979 meta = {
1984 meta = {
1980 license = [ pkgs.lib.licenses.bsdOriginal ];
1985 license = [ pkgs.lib.licenses.bsdOriginal ];
1981 };
1986 };
1982 };
1987 };
1983 "subprocess32" = super.buildPythonPackage {
1988 "subprocess32" = super.buildPythonPackage {
1984 name = "subprocess32-3.5.3";
1989 name = "subprocess32-3.5.4";
1985 doCheck = false;
1990 doCheck = false;
1986 src = fetchurl {
1991 src = fetchurl {
1987 url = "https://files.pythonhosted.org/packages/be/2b/beeba583e9877e64db10b52a96915afc0feabf7144dcbf2a0d0ea68bf73d/subprocess32-3.5.3.tar.gz";
1992 url = "https://files.pythonhosted.org/packages/32/c8/564be4d12629b912ea431f1a50eb8b3b9d00f1a0b1ceff17f266be190007/subprocess32-3.5.4.tar.gz";
1988 sha256 = "1hr5fan8i719hmlmz73hf8rhq74014w07d8ryg7krvvf6692kj3b";
1993 sha256 = "17f7mvwx2271s1wrl0qac3wjqqnrqag866zs3qc8v5wp0k43fagb";
1989 };
1994 };
1990 meta = {
1995 meta = {
1991 license = [ pkgs.lib.licenses.psfl ];
1996 license = [ pkgs.lib.licenses.psfl ];
1992 };
1997 };
1993 };
1998 };
1994 "supervisor" = super.buildPythonPackage {
1999 "supervisor" = super.buildPythonPackage {
1995 name = "supervisor-3.3.5";
2000 name = "supervisor-4.0.3";
1996 doCheck = false;
2001 doCheck = false;
1997 propagatedBuildInputs = [
2002 propagatedBuildInputs = [
1998 self."meld3"
2003 self."meld3"
1999 ];
2004 ];
2000 src = fetchurl {
2005 src = fetchurl {
2001 url = "https://files.pythonhosted.org/packages/ba/65/92575a8757ed576beaee59251f64a3287bde82bdc03964b89df9e1d29e1b/supervisor-3.3.5.tar.gz";
2006 url = "https://files.pythonhosted.org/packages/97/48/f38bf70bd9282d1a18d591616557cc1a77a1c627d57dff66ead65c891dc8/supervisor-4.0.3.tar.gz";
2002 sha256 = "1w3ahridzbc6rxfpbyx8lij6pjlcgf2ymzyg53llkjqxalp6sk8v";
2007 sha256 = "17hla7mx6w5m5jzkkjxgqa8wpswqmfhbhf49f692hw78fg0ans7p";
2003 };
2008 };
2004 meta = {
2009 meta = {
2005 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
2010 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
@@ -2128,22 +2133,22 b' self: super: {'
2128 };
2133 };
2129 };
2134 };
2130 "vine" = super.buildPythonPackage {
2135 "vine" = super.buildPythonPackage {
2131 name = "vine-1.2.0";
2136 name = "vine-1.3.0";
2132 doCheck = false;
2137 doCheck = false;
2133 src = fetchurl {
2138 src = fetchurl {
2134 url = "https://files.pythonhosted.org/packages/46/1a/c94317efa98040c5d50fe3cf9080cafb0372ff5afb0283dc018c751c6746/vine-1.2.0.tar.gz";
2139 url = "https://files.pythonhosted.org/packages/1c/e1/79fb8046e607dd6c2ad05c9b8ebac9d0bd31d086a08f02699e96fc5b3046/vine-1.3.0.tar.gz";
2135 sha256 = "0xjz2sjbr5jrpjk411b7alkghdskhphgsqqrbi7abqfh2pli6j7f";
2140 sha256 = "11ydsbhl1vabndc2r979dv61s6j2b0giq6dgvryifvq1m7bycghk";
2136 };
2141 };
2137 meta = {
2142 meta = {
2138 license = [ pkgs.lib.licenses.bsdOriginal ];
2143 license = [ pkgs.lib.licenses.bsdOriginal ];
2139 };
2144 };
2140 };
2145 };
2141 "waitress" = super.buildPythonPackage {
2146 "waitress" = super.buildPythonPackage {
2142 name = "waitress-1.1.0";
2147 name = "waitress-1.3.0";
2143 doCheck = false;
2148 doCheck = false;
2144 src = fetchurl {
2149 src = fetchurl {
2145 url = "https://files.pythonhosted.org/packages/3c/68/1c10dd5c556872ceebe88483b0436140048d39de83a84a06a8baa8136f4f/waitress-1.1.0.tar.gz";
2150 url = "https://files.pythonhosted.org/packages/43/50/9890471320d5ad22761ae46661cf745f487b1c8c4ec49352b99e1078b970/waitress-1.3.0.tar.gz";
2146 sha256 = "1a85gyji0kajc3p0s1pwwfm06w4wfxjkvvl4rnrz3h164kbd6g6k";
2151 sha256 = "09j5dzbbcxib7vdskhx39s1qsydlr4n2p2png71d7mjnr9pnwajf";
2147 };
2152 };
2148 meta = {
2153 meta = {
2149 license = [ pkgs.lib.licenses.zpl21 ];
2154 license = [ pkgs.lib.licenses.zpl21 ];
@@ -2218,18 +2223,18 b' self: super: {'
2218 };
2223 };
2219 };
2224 };
2220 "webob" = super.buildPythonPackage {
2225 "webob" = super.buildPythonPackage {
2221 name = "webob-1.8.4";
2226 name = "webob-1.8.5";
2222 doCheck = false;
2227 doCheck = false;
2223 src = fetchurl {
2228 src = fetchurl {
2224 url = "https://files.pythonhosted.org/packages/e4/6c/99e322c3d4cc11d9060a67a9bf2f7c9c581f40988c11fffe89bb8c36bc5e/WebOb-1.8.4.tar.gz";
2229 url = "https://files.pythonhosted.org/packages/9d/1a/0c89c070ee2829c934cb6c7082287c822e28236a4fcf90063e6be7c35532/WebOb-1.8.5.tar.gz";
2225 sha256 = "16cfg5y4n6sihz59vsmns2yqbfm0gfsn3l5xgz2g0pdhilaib0x4";
2230 sha256 = "11khpzaxc88q31v25ic330gsf56fwmbdc9b30br8mvp0fmwspah5";
2226 };
2231 };
2227 meta = {
2232 meta = {
2228 license = [ pkgs.lib.licenses.mit ];
2233 license = [ pkgs.lib.licenses.mit ];
2229 };
2234 };
2230 };
2235 };
2231 "webtest" = super.buildPythonPackage {
2236 "webtest" = super.buildPythonPackage {
2232 name = "webtest-2.0.32";
2237 name = "webtest-2.0.33";
2233 doCheck = false;
2238 doCheck = false;
2234 propagatedBuildInputs = [
2239 propagatedBuildInputs = [
2235 self."six"
2240 self."six"
@@ -2238,8 +2243,8 b' self: super: {'
2238 self."beautifulsoup4"
2243 self."beautifulsoup4"
2239 ];
2244 ];
2240 src = fetchurl {
2245 src = fetchurl {
2241 url = "https://files.pythonhosted.org/packages/27/9f/9e74449d272ffbef4fb3012e6dbc53c0b24822d545e7a33a342f80131e59/WebTest-2.0.32.tar.gz";
2246 url = "https://files.pythonhosted.org/packages/a8/b0/ffc9413b637dbe26e291429bb0f6ed731e518d0cd03da28524a8fe2e8a8f/WebTest-2.0.33.tar.gz";
2242 sha256 = "0qp0nnbazzm4ibjiyqfcn6f230svk09i4g58zg2i9x1ga06h48a2";
2247 sha256 = "1l3z0cwqslsf4rcrhi2gr8kdfh74wn2dw76376i4g9i38gz8wd21";
2243 };
2248 };
2244 meta = {
2249 meta = {
2245 license = [ pkgs.lib.licenses.mit ];
2250 license = [ pkgs.lib.licenses.mit ];
@@ -2293,42 +2298,42 b' self: super: {'
2293 };
2298 };
2294 };
2299 };
2295 "zope.deprecation" = super.buildPythonPackage {
2300 "zope.deprecation" = super.buildPythonPackage {
2296 name = "zope.deprecation-4.3.0";
2301 name = "zope.deprecation-4.4.0";
2297 doCheck = false;
2302 doCheck = false;
2298 propagatedBuildInputs = [
2303 propagatedBuildInputs = [
2299 self."setuptools"
2304 self."setuptools"
2300 ];
2305 ];
2301 src = fetchurl {
2306 src = fetchurl {
2302 url = "https://files.pythonhosted.org/packages/a1/18/2dc5e6bfe64fdc3b79411b67464c55bb0b43b127051a20f7f492ab767758/zope.deprecation-4.3.0.tar.gz";
2307 url = "https://files.pythonhosted.org/packages/34/da/46e92d32d545dd067b9436279d84c339e8b16de2ca393d7b892bc1e1e9fd/zope.deprecation-4.4.0.tar.gz";
2303 sha256 = "095jas41wbxgmw95kwdxqhbc3bgihw2hzj9b3qpdg85apcsf2lkx";
2308 sha256 = "1pz2cv7gv9y1r3m0bdv7ks1alagmrn5msm5spwdzkb2by0w36i8d";
2304 };
2309 };
2305 meta = {
2310 meta = {
2306 license = [ pkgs.lib.licenses.zpl21 ];
2311 license = [ pkgs.lib.licenses.zpl21 ];
2307 };
2312 };
2308 };
2313 };
2309 "zope.event" = super.buildPythonPackage {
2314 "zope.event" = super.buildPythonPackage {
2310 name = "zope.event-4.3.0";
2315 name = "zope.event-4.4";
2311 doCheck = false;
2316 doCheck = false;
2312 propagatedBuildInputs = [
2317 propagatedBuildInputs = [
2313 self."setuptools"
2318 self."setuptools"
2314 ];
2319 ];
2315 src = fetchurl {
2320 src = fetchurl {
2316 url = "https://files.pythonhosted.org/packages/9e/d0/54ba59f19a0635f6591b74be259cf6fbf67e73f4edda27b5cd0cf4d26efa/zope.event-4.3.0.tar.gz";
2321 url = "https://files.pythonhosted.org/packages/4c/b2/51c0369adcf5be2334280eed230192ab3b03f81f8efda9ddea6f65cc7b32/zope.event-4.4.tar.gz";
2317 sha256 = "1rrkyx42bcq8dkpj23c2v99kczlrg8d39c06q5qpr0vs4hjfmv70";
2322 sha256 = "1ksbc726av9xacml6jhcfyn828hlhb9xlddpx6fcvnlvmpmpvhk9";
2318 };
2323 };
2319 meta = {
2324 meta = {
2320 license = [ pkgs.lib.licenses.zpl21 ];
2325 license = [ pkgs.lib.licenses.zpl21 ];
2321 };
2326 };
2322 };
2327 };
2323 "zope.interface" = super.buildPythonPackage {
2328 "zope.interface" = super.buildPythonPackage {
2324 name = "zope.interface-4.5.0";
2329 name = "zope.interface-4.6.0";
2325 doCheck = false;
2330 doCheck = false;
2326 propagatedBuildInputs = [
2331 propagatedBuildInputs = [
2327 self."setuptools"
2332 self."setuptools"
2328 ];
2333 ];
2329 src = fetchurl {
2334 src = fetchurl {
2330 url = "https://files.pythonhosted.org/packages/ac/8a/657532df378c2cd2a1fe6b12be3b4097521570769d4852ec02c24bd3594e/zope.interface-4.5.0.tar.gz";
2335 url = "https://files.pythonhosted.org/packages/4e/d0/c9d16bd5b38de44a20c6dc5d5ed80a49626fafcb3db9f9efdc2a19026db6/zope.interface-4.6.0.tar.gz";
2331 sha256 = "0k67m60ij06wkg82n15qgyn96waf4pmrkhv0njpkfzpmv5q89hsp";
2336 sha256 = "1rgh2x3rcl9r0v0499kf78xy86rnmanajf4ywmqb943wpk50sg8v";
2332 };
2337 };
2333 meta = {
2338 meta = {
2334 license = [ pkgs.lib.licenses.zpl21 ];
2339 license = [ pkgs.lib.licenses.zpl21 ];
@@ -1,37 +1,31 b''
1 ## dependencies
1 ## dependencies
2
2
3 setuptools-scm==2.1.0
4 amqp==2.3.1
3 amqp==2.3.1
5 # not released authomatic that has updated some oauth providers
4 # not released authomatic that has updated some oauth providers
6 https://code.rhodecode.com/upstream/authomatic/archive/90a9ce60cc405ae8a2bf5c3713acd5d78579a04e.tar.gz?md5=3c68720a1322b25254009518d1ff6801#egg=authomatic==0.1.0.post1
5 https://code.rhodecode.com/upstream/authomatic/artifacts/download/0-4fe9c041-a567-4f84-be4c-7efa2a606d3c.tar.gz?md5=f6bdc3c769688212db68233e8d2b0383#egg=authomatic==0.1.0.post1
7 atomicwrites==1.2.1
6
8 attrs==18.2.0
9 babel==1.3
7 babel==1.3
10 beaker==1.9.1
8 beaker==1.9.1
11 bleach==3.0.2
9 bleach==3.1.0
12 celery==4.1.1
10 celery==4.1.1
13 chameleon==2.24
14 channelstream==0.5.2
11 channelstream==0.5.2
15 click==7.0
12 click==7.0
16 colander==1.5.1
13 colander==1.7.0
17 # our custom configobj
14 # our custom configobj
18 https://code.rhodecode.com/upstream/configobj/archive/a11ff0a0bd4fbda9e3a91267e720f88329efb4a6.tar.gz?md5=9916c524ea11a6c418217af6b28d4b3c#egg=configobj==5.0.6
15 https://code.rhodecode.com/upstream/configobj/artifacts/download/0-012de99a-b1e1-4f64-a5c0-07a98a41b324.tar.gz?md5=6a513f51fe04b2c18cf84c1395a7c626#egg=configobj==5.0.6
19 cssselect==1.0.3
16 cssselect==1.0.3
17 cryptography==2.6.1
20 decorator==4.1.2
18 decorator==4.1.2
21 deform==2.0.7
19 deform==2.0.7
22 docutils==0.14.0
20 docutils==0.14.0
23 dogpile.cache==0.7.1
21 dogpile.cache==0.7.1
24 dogpile.core==0.4.1
22 dogpile.core==0.4.1
25 ecdsa==0.13
26 formencode==1.2.4
23 formencode==1.2.4
27 future==0.14.3
24 future==0.14.3
28 futures==3.0.2
25 futures==3.0.2
29 gnureadline==6.3.8
30 infrae.cache==1.0.1
26 infrae.cache==1.0.1
31 iso8601==0.1.12
27 iso8601==0.1.12
32 itsdangerous==0.24
28 itsdangerous==0.24
33 jinja2==2.9.6
34 billiard==3.5.0.3
35 kombu==4.2.1
29 kombu==4.2.1
36 lxml==4.2.5
30 lxml==4.2.5
37 mako==1.0.7
31 mako==1.0.7
@@ -40,23 +34,20 b' markupsafe==1.1.0'
40 msgpack-python==0.5.6
34 msgpack-python==0.5.6
41 pyotp==2.2.7
35 pyotp==2.2.7
42 packaging==15.2
36 packaging==15.2
43 paste==3.0.5
37 pathlib2==2.3.4
38 paste==3.0.8
44 pastedeploy==2.0.1
39 pastedeploy==2.0.1
45 pastescript==3.0.0
40 pastescript==3.1.0
46 pathlib2==2.3.3
47 peppercorn==0.6
41 peppercorn==0.6
48 psutil==5.4.8
42 psutil==5.5.1
49 py-bcrypt==0.4
43 py-bcrypt==0.4
50 pycrypto==2.6.1
51 pycurl==7.43.0.2
44 pycurl==7.43.0.2
52 pyflakes==0.8.1
45 pycrypto==2.6.1
53 pygments==2.3.1
46 pygments==2.4.2
54 pyparsing==2.3.0
47 pyparsing==2.3.0
55 pyramid-beaker==0.8
56 pyramid-debugtoolbar==4.5.0
48 pyramid-debugtoolbar==4.5.0
57 pyramid-jinja2==2.7
58 pyramid-mako==1.0.2
49 pyramid-mako==1.0.2
59 pyramid==1.10.1
50 pyramid==1.10.4
60 pyramid_mailer==0.15.1
51 pyramid_mailer==0.15.1
61 python-dateutil
52 python-dateutil
62 python-ldap==3.1.0
53 python-ldap==3.1.0
@@ -74,10 +65,9 b' routes==2.4.1'
74 simplejson==3.16.0
65 simplejson==3.16.0
75 six==1.11.0
66 six==1.11.0
76 sqlalchemy==1.1.18
67 sqlalchemy==1.1.18
77 sshpubkeys==2.2.0
68 sshpubkeys==3.1.0
78 subprocess32==3.5.3
69 subprocess32==3.5.4
79 supervisor==3.3.5
70 supervisor==4.0.3
80 tempita==0.5.2
81 translationstring==1.3
71 translationstring==1.3
82 urllib3==1.24.1
72 urllib3==1.24.1
83 urlobject==2.4.3
73 urlobject==2.4.3
@@ -85,29 +75,29 b' venusian==1.2.0'
85 weberror==0.10.3
75 weberror==0.10.3
86 webhelpers2==2.0
76 webhelpers2==2.0
87 webhelpers==1.3
77 webhelpers==1.3
88 webob==1.8.4
78 webob==1.8.5
89 whoosh==2.7.4
79 whoosh==2.7.4
90 wsgiref==0.1.2
80 wsgiref==0.1.2
91 zope.cachedescriptors==4.3.1
81 zope.cachedescriptors==4.3.1
92 zope.deprecation==4.3.0
82 zope.deprecation==4.4.0
93 zope.event==4.3.0
83 zope.event==4.4.0
94 zope.interface==4.5.0
84 zope.interface==4.6.0
95
85
96 # DB drivers
86 # DB drivers
97 mysql-python==1.2.5
87 mysql-python==1.2.5
98 pymysql==0.8.1
88 pymysql==0.8.1
99 pysqlite==2.8.3
89 pysqlite==2.8.3
100 psycopg2==2.7.5
90 psycopg2==2.8.3
101
91
102 # IPYTHON RENDERING
92 # IPYTHON RENDERING
103 # entrypoints backport, pypi version doesn't support egg installs
93 # entrypoints backport, pypi version doesn't support egg installs
104 https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1
94 https://code.rhodecode.com/upstream/entrypoints/artifacts/download/0-8e9ee9e4-c4db-409c-b07e-81568fd1832d.tar.gz?md5=3a027b8ff1d257b91fe257de6c43357d#egg=entrypoints==0.2.2.rhodecode-upstream1
105 nbconvert==5.3.1
95 nbconvert==5.3.1
106 nbformat==4.4.0
96 nbformat==4.4.0
107 jupyter_client==5.0.0
97 jupyter_client==5.0.0
108
98
109 ## cli tools
99 ## cli tools
110 alembic==1.0.5
100 alembic==1.0.10
111 invoke==0.13.0
101 invoke==0.13.0
112 bumpversion==0.5.3
102 bumpversion==0.5.3
113
103
@@ -115,15 +105,14 b' bumpversion==0.5.3'
115 gevent==1.4.0
105 gevent==1.4.0
116 greenlet==0.4.15
106 greenlet==0.4.15
117 gunicorn==19.9.0
107 gunicorn==19.9.0
118 waitress==1.1.0
108 waitress==1.3.0
119 setproctitle==1.1.10
120
109
121 ## debug
110 ## debug
122 ipdb==0.11.0
111 ipdb==0.12.0
123 ipython==5.1.0
112 ipython==5.1.0
124
113
125 ## rhodecode-tools, special case
114 ## rhodecode-tools, special case
126 https://code.rhodecode.com/rhodecode-tools-ce/archive/v1.2.1.tar.gz?md5=25bc2f7de1da318e547236d3fb463d28#egg=rhodecode-tools==1.2.1
115 https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-10ac93f4-bb7d-4b97-baea-68110743dd5a.tar.gz?md5=962dc77c06aceee62282b98d33149661#egg=rhodecode-tools==1.2.1
127
116
128 ## appenlight
117 ## appenlight
129 appenlight-client==0.6.26
118 appenlight-client==0.6.26
@@ -10,7 +10,7 b' gprof2dot==2017.9.19'
10
10
11 mock==1.0.1
11 mock==1.0.1
12 cov-core==1.15.0
12 cov-core==1.15.0
13 coverage==4.5.1
13 coverage==4.5.3
14
14
15 webtest==2.0.32
15 webtest==2.0.33
16 beautifulsoup4==4.6.3
16 beautifulsoup4==4.6.3
@@ -1,1 +1,1 b''
1 4.16.2 No newline at end of file
1 4.17.0 No newline at end of file
@@ -45,7 +45,7 b' PYRAMID_SETTINGS = {}'
45 EXTENSIONS = {}
45 EXTENSIONS = {}
46
46
47 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
47 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
48 __dbversion__ = 95 # defines current db version for migrations
48 __dbversion__ = 98 # defines current db version for migrations
49 __platform__ = platform.system()
49 __platform__ = platform.system()
50 __license__ = 'AGPLv3, and Commercial License'
50 __license__ = 'AGPLv3, and Commercial License'
51 __author__ = 'RhodeCode GmbH'
51 __author__ = 'RhodeCode GmbH'
@@ -37,11 +37,11 b' class TestCommentCommit(object):'
37 assert_error(id_, expected, given=response.body)
37 assert_error(id_, expected, given=response.body)
38
38
39 @pytest.mark.parametrize("commit_id, expected_err", [
39 @pytest.mark.parametrize("commit_id, expected_err", [
40 ('abcabca', {'hg': 'Commit {commit} does not exist for {repo}',
40 ('abcabca', {'hg': 'Commit {commit} does not exist for `{repo}`',
41 'git': 'Commit {commit} does not exist for {repo}',
41 'git': 'Commit {commit} does not exist for `{repo}`',
42 'svn': 'Commit id {commit} not understood.'}),
42 'svn': 'Commit id {commit} not understood.'}),
43 ('idontexist', {'hg': 'Commit {commit} does not exist for {repo}',
43 ('idontexist', {'hg': 'Commit {commit} does not exist for `{repo}`',
44 'git': 'Commit {commit} does not exist for {repo}',
44 'git': 'Commit {commit} does not exist for `{repo}`',
45 'svn': 'Commit id {commit} not understood.'}),
45 'svn': 'Commit id {commit} not understood.'}),
46 ])
46 ])
47 def test_api_comment_commit_wrong_hash(self, backend, commit_id, expected_err):
47 def test_api_comment_commit_wrong_hash(self, backend, commit_id, expected_err):
@@ -53,7 +53,7 b' class TestCommentCommit(object):'
53
53
54 expected_err = expected_err[backend.alias]
54 expected_err = expected_err[backend.alias]
55 expected_err = expected_err.format(
55 expected_err = expected_err.format(
56 repo=backend.repo.scm_instance(), commit=commit_id)
56 repo=backend.repo.scm_instance().name, commit=commit_id)
57 assert_error(id_, expected_err, given=response.body)
57 assert_error(id_, expected_err, given=response.body)
58
58
59 @pytest.mark.parametrize("status_change, message, commit_id", [
59 @pytest.mark.parametrize("status_change, message, commit_id", [
@@ -44,6 +44,7 b' class TestGetRepo(object):'
44 self, apikey_attr, expect_secrets, cache_param, backend,
44 self, apikey_attr, expect_secrets, cache_param, backend,
45 user_util):
45 user_util):
46 repo = backend.create_repo()
46 repo = backend.create_repo()
47 repo_id = repo.repo_id
47 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
48 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
48 group = user_util.create_user_group(members=[usr])
49 group = user_util.create_user_group(members=[usr])
49 user_util.grant_user_group_permission_to_repo(
50 user_util.grant_user_group_permission_to_repo(
@@ -64,6 +65,8 b' class TestGetRepo(object):'
64 permissions = expected_permissions(repo)
65 permissions = expected_permissions(repo)
65
66
66 followers = []
67 followers = []
68
69 repo = RepoModel().get(repo_id)
67 for user in repo.followers:
70 for user in repo.followers:
68 followers.append(user.user.get_api_data(
71 followers.append(user.user.get_api_data(
69 include_secrets=expect_secrets))
72 include_secrets=expect_secrets))
@@ -84,6 +87,7 b' class TestGetRepo(object):'
84 # TODO: Depending on which tests are running before this one, we
87 # TODO: Depending on which tests are running before this one, we
85 # start with a different number of permissions in the database.
88 # start with a different number of permissions in the database.
86 repo = RepoModel().get_by_repo_name(backend.repo_name)
89 repo = RepoModel().get_by_repo_name(backend.repo_name)
90 repo_id = repo.repo_id
87 permission_count = len(repo.repo_to_perm)
91 permission_count = len(repo.repo_to_perm)
88
92
89 RepoModel().grant_user_permission(repo=backend.repo_name,
93 RepoModel().grant_user_permission(repo=backend.repo_name,
@@ -102,6 +106,8 b' class TestGetRepo(object):'
102 permissions = expected_permissions(repo)
106 permissions = expected_permissions(repo)
103
107
104 followers = []
108 followers = []
109
110 repo = RepoModel().get(repo_id)
105 for user in repo.followers:
111 for user in repo.followers:
106 followers.append(user.user.get_api_data())
112 followers.append(user.user.get_api_data())
107
113
@@ -444,7 +444,7 b' def get_repo_nodes(request, apiuser, rep'
444 result: [
444 result: [
445 {
445 {
446 "binary": false,
446 "binary": false,
447 "content": "File line\nLine2\n",
447 "content": "File line",
448 "extension": "md",
448 "extension": "md",
449 "lines": 2,
449 "lines": 2,
450 "md5": "059fa5d29b19c0657e384749480f6422",
450 "md5": "059fa5d29b19c0657e384749480f6422",
@@ -529,6 +529,7 b' def get_repo_file(request, apiuser, repo'
529 :param cache: Use internal caches for fetching files. If disabled fetching
529 :param cache: Use internal caches for fetching files. If disabled fetching
530 files is slower but more memory efficient
530 files is slower but more memory efficient
531 :type cache: Optional(bool)
531 :type cache: Optional(bool)
532
532 Example output:
533 Example output:
533
534
534 .. code-block:: bash
535 .. code-block:: bash
@@ -168,6 +168,28 b' class BaseAppView(object):'
168 from rhodecode.lib.base import attach_context_attributes
168 from rhodecode.lib.base import attach_context_attributes
169 attach_context_attributes(c, self.request, self.request.user.user_id)
169 attach_context_attributes(c, self.request, self.request.user.user_id)
170
170
171 c.is_super_admin = c.auth_user.is_admin
172
173 c.can_create_repo = c.is_super_admin
174 c.can_create_repo_group = c.is_super_admin
175 c.can_create_user_group = c.is_super_admin
176
177 c.is_delegated_admin = False
178
179 if not c.auth_user.is_default and not c.is_super_admin:
180 c.can_create_repo = h.HasPermissionAny('hg.create.repository')(
181 user=self.request.user)
182 repositories = c.auth_user.repositories_admin or c.can_create_repo
183
184 c.can_create_repo_group = h.HasPermissionAny('hg.repogroup.create.true')(
185 user=self.request.user)
186 repository_groups = c.auth_user.repository_groups_admin or c.can_create_repo_group
187
188 c.can_create_user_group = h.HasPermissionAny('hg.usergroup.create.true')(
189 user=self.request.user)
190 user_groups = c.auth_user.user_groups_admin or c.can_create_user_group
191 # delegated admin can create, or manage some objects
192 c.is_delegated_admin = repositories or repository_groups or user_groups
171 return c
193 return c
172
194
173 def _get_template_context(self, tmpl_args, **kwargs):
195 def _get_template_context(self, tmpl_args, **kwargs):
@@ -215,12 +237,17 b' class RepoAppView(BaseAppView):'
215 c.rhodecode_db_repo = self.db_repo
237 c.rhodecode_db_repo = self.db_repo
216 c.repo_name = self.db_repo_name
238 c.repo_name = self.db_repo_name
217 c.repository_pull_requests = self.db_repo_pull_requests
239 c.repository_pull_requests = self.db_repo_pull_requests
240 c.repository_is_user_following = ScmModel().is_following_repo(
241 self.db_repo_name, self._rhodecode_user.user_id)
218 self.path_filter = PathFilter(None)
242 self.path_filter = PathFilter(None)
219
243
220 c.repository_requirements_missing = {}
244 c.repository_requirements_missing = {}
221 try:
245 try:
222 self.rhodecode_vcs_repo = self.db_repo.scm_instance()
246 self.rhodecode_vcs_repo = self.db_repo.scm_instance()
223 if self.rhodecode_vcs_repo:
247 # NOTE(marcink):
248 # comparison to None since if it's an object __bool__ is expensive to
249 # calculate
250 if self.rhodecode_vcs_repo is not None:
224 path_perms = self.rhodecode_vcs_repo.get_path_permissions(
251 path_perms = self.rhodecode_vcs_repo.get_path_permissions(
225 c.auth_user.username)
252 c.auth_user.username)
226 self.path_filter = PathFilter(path_perms)
253 self.path_filter = PathFilter(path_perms)
@@ -85,8 +85,6 b' class NavigationRegistry(object):'
85 'admin_settings_hooks'),
85 'admin_settings_hooks'),
86 NavEntry('search', _('Full Text Search'),
86 NavEntry('search', _('Full Text Search'),
87 'admin_settings_search'),
87 'admin_settings_search'),
88 NavEntry('integrations', _('Integrations'),
89 'global_integrations_home'),
90 NavEntry('system', _('System Info'),
88 NavEntry('system', _('System Info'),
91 'admin_settings_system'),
89 'admin_settings_system'),
92 NavEntry('exceptions', _('Exceptions Tracker'),
90 NavEntry('exceptions', _('Exceptions Tracker'),
@@ -424,6 +424,10 b' def admin_routes(config):'
424 pattern='/repo_groups')
424 pattern='/repo_groups')
425
425
426 config.add_route(
426 config.add_route(
427 name='repo_groups_data',
428 pattern='/repo_groups_data')
429
430 config.add_route(
427 name='repo_group_new',
431 name='repo_group_new',
428 pattern='/repo_group/new')
432 pattern='/repo_group/new')
429
433
@@ -46,10 +46,10 b' def route_path(name, params=None, **kwar'
46
46
47 class TestAdminMainView(TestController):
47 class TestAdminMainView(TestController):
48
48
49 def test_redirect_admin_home(self):
49 def test_access_admin_home(self):
50 self.log_user()
50 self.log_user()
51 response = self.app.get(route_path('admin_home'), status=302)
51 response = self.app.get(route_path('admin_home'), status=200)
52 assert response.location.endswith('/audit_logs')
52 response.mustcontain("Administration area")
53
53
54 def test_redirect_pull_request_view(self, view):
54 def test_redirect_pull_request_view(self, view):
55 self.log_user()
55 self.log_user()
@@ -23,11 +23,11 b' import pytest'
23
23
24 from rhodecode.apps._base import ADMIN_PREFIX
24 from rhodecode.apps._base import ADMIN_PREFIX
25 from rhodecode.lib import helpers as h
25 from rhodecode.lib import helpers as h
26 from rhodecode.model.db import Repository, UserRepoToPerm, User
26 from rhodecode.model.db import Repository, UserRepoToPerm, User, RepoGroup
27 from rhodecode.model.meta import Session
27 from rhodecode.model.meta import Session
28 from rhodecode.model.repo_group import RepoGroupModel
28 from rhodecode.model.repo_group import RepoGroupModel
29 from rhodecode.tests import (
29 from rhodecode.tests import (
30 assert_session_flash, TEST_USER_REGULAR_LOGIN, TESTS_TMP_PATH, TestController)
30 assert_session_flash, TEST_USER_REGULAR_LOGIN, TESTS_TMP_PATH)
31 from rhodecode.tests.fixture import Fixture
31 from rhodecode.tests.fixture import Fixture
32
32
33 fixture = Fixture()
33 fixture = Fixture()
@@ -38,6 +38,7 b' def route_path(name, params=None, **kwar'
38
38
39 base_url = {
39 base_url = {
40 'repo_groups': ADMIN_PREFIX + '/repo_groups',
40 'repo_groups': ADMIN_PREFIX + '/repo_groups',
41 'repo_groups_data': ADMIN_PREFIX + '/repo_groups_data',
41 'repo_group_new': ADMIN_PREFIX + '/repo_group/new',
42 'repo_group_new': ADMIN_PREFIX + '/repo_group/new',
42 'repo_group_create': ADMIN_PREFIX + '/repo_group/create',
43 'repo_group_create': ADMIN_PREFIX + '/repo_group/create',
43
44
@@ -59,13 +60,30 b' def _get_permission_for_user(user, repo)'
59
60
60 @pytest.mark.usefixtures("app")
61 @pytest.mark.usefixtures("app")
61 class TestAdminRepositoryGroups(object):
62 class TestAdminRepositoryGroups(object):
63
62 def test_show_repo_groups(self, autologin_user):
64 def test_show_repo_groups(self, autologin_user):
63 response = self.app.get(route_path('repo_groups'))
65 self.app.get(route_path('repo_groups'))
64 response.mustcontain('data: []')
66
67 def test_show_repo_groups_data(self, autologin_user, xhr_header):
68 response = self.app.get(route_path(
69 'repo_groups_data'), extra_environ=xhr_header)
70
71 all_repo_groups = RepoGroup.query().count()
72 assert response.json['recordsTotal'] == all_repo_groups
65
73
66 def test_show_repo_groups_after_creating_group(self, autologin_user):
74 def test_show_repo_groups_data_filtered(self, autologin_user, xhr_header):
75 response = self.app.get(route_path(
76 'repo_groups_data', params={'search[value]': 'empty_search'}),
77 extra_environ=xhr_header)
78
79 all_repo_groups = RepoGroup.query().count()
80 assert response.json['recordsTotal'] == all_repo_groups
81 assert response.json['recordsFiltered'] == 0
82
83 def test_show_repo_groups_after_creating_group(self, autologin_user, xhr_header):
67 fixture.create_repo_group('test_repo_group')
84 fixture.create_repo_group('test_repo_group')
68 response = self.app.get(route_path('repo_groups'))
85 response = self.app.get(route_path(
86 'repo_groups_data'), extra_environ=xhr_header)
69 response.mustcontain('"name_raw": "test_repo_group"')
87 response.mustcontain('"name_raw": "test_repo_group"')
70 fixture.destroy_repo_group('test_repo_group')
88 fixture.destroy_repo_group('test_repo_group')
71
89
@@ -214,8 +214,7 b' class TestAdminSettingsGlobal(object):'
214 })
214 })
215
215
216 response = response.follow()
216 response = response.follow()
217 response.mustcontain(
217 response.mustcontain(new_title)
218 """<div class="branding">- %s</div>""" % new_title)
219
218
220 def post_and_verify_settings(self, settings):
219 def post_and_verify_settings(self, settings):
221 old_title = 'RhodeCode'
220 old_title = 'RhodeCode'
@@ -173,4 +173,4 b' class TestAdminUsersSshKeysView(TestCont'
173
173
174 response.mustcontain('Private key')
174 response.mustcontain('Private key')
175 response.mustcontain('Public key')
175 response.mustcontain('Public key')
176 response.mustcontain('-----BEGIN RSA PRIVATE KEY-----')
176 response.mustcontain('-----BEGIN PRIVATE KEY-----')
@@ -50,7 +50,7 b' class ExceptionsTrackerView(BaseAppView)'
50 count +=1
50 count +=1
51 return count
51 return count
52
52
53 def get_all_exceptions(self, read_metadata=False, limit=None):
53 def get_all_exceptions(self, read_metadata=False, limit=None, type_filter=None):
54 exc_store_path = exc_tracking.get_exc_store()
54 exc_store_path = exc_tracking.get_exc_store()
55 exception_list = []
55 exception_list = []
56
56
@@ -59,7 +59,7 b' class ExceptionsTrackerView(BaseAppView)'
59 return val.split('_')[-1]
59 return val.split('_')[-1]
60 except Exception:
60 except Exception:
61 return 0
61 return 0
62 count = 0
62
63 for fname in reversed(sorted(os.listdir(exc_store_path), key=key_sorter)):
63 for fname in reversed(sorted(os.listdir(exc_store_path), key=key_sorter)):
64
64
65 parts = fname.split('_', 2)
65 parts = fname.split('_', 2)
@@ -83,13 +83,17 b' class ExceptionsTrackerView(BaseAppView)'
83 except Exception:
83 except Exception:
84 log.exception('Failed to read exc data from:{}'.format(full_path))
84 log.exception('Failed to read exc data from:{}'.format(full_path))
85 pass
85 pass
86
87 # convert our timestamp to a date obj, for nicer representation
86 # convert our timestamp to a date obj, for nicer representation
88 exc['exc_utc_date'] = time_to_utcdatetime(exc['exc_timestamp'])
87 exc['exc_utc_date'] = time_to_utcdatetime(exc['exc_timestamp'])
88
89 type_present = exc.get('exc_type')
90 if type_filter:
91 if type_present and type_present == type_filter:
92 exception_list.append(exc)
93 else:
89 exception_list.append(exc)
94 exception_list.append(exc)
90
95
91 count += 1
96 if limit and len(exception_list) >= limit:
92 if limit and count >= limit:
93 break
97 break
94 return exception_list
98 return exception_list
95
99
@@ -103,8 +107,10 b' class ExceptionsTrackerView(BaseAppView)'
103 c = self.load_default_context()
107 c = self.load_default_context()
104 c.active = 'exceptions_browse'
108 c.active = 'exceptions_browse'
105 c.limit = safe_int(self.request.GET.get('limit')) or 50
109 c.limit = safe_int(self.request.GET.get('limit')) or 50
110 c.type_filter = self.request.GET.get('type_filter')
106 c.next_limit = c.limit + 50
111 c.next_limit = c.limit + 50
107 c.exception_list = self.get_all_exceptions(read_metadata=True, limit=c.limit)
112 c.exception_list = self.get_all_exceptions(
113 read_metadata=True, limit=c.limit, type_filter=c.type_filter)
108 c.exception_list_count = self.count_all_exceptions()
114 c.exception_list_count = self.count_all_exceptions()
109 c.exception_store_dir = exc_tracking.get_exc_store()
115 c.exception_store_dir = exc_tracking.get_exc_store()
110 return self._get_template_context(c)
116 return self._get_template_context(c)
@@ -132,12 +138,20 b' class ExceptionsTrackerView(BaseAppView)'
132 def exception_delete_all(self):
138 def exception_delete_all(self):
133 _ = self.request.translate
139 _ = self.request.translate
134 c = self.load_default_context()
140 c = self.load_default_context()
141 type_filter = self.request.POST.get('type_filter')
135
142
136 c.active = 'exceptions'
143 c.active = 'exceptions'
137 all_exc = self.get_all_exceptions()
144 all_exc = self.get_all_exceptions(read_metadata=bool(type_filter), type_filter=type_filter)
138 exc_count = len(all_exc)
145 exc_count = 0
146
139 for exc in all_exc:
147 for exc in all_exc:
148 if type_filter:
149 if exc.get('exc_type') == type_filter:
140 exc_tracking.delete_exception(exc['exc_id'], prefix=None)
150 exc_tracking.delete_exception(exc['exc_id'], prefix=None)
151 exc_count += 1
152 else:
153 exc_tracking.delete_exception(exc['exc_id'], prefix=None)
154 exc_count += 1
141
155
142 h.flash(_('Removed {} Exceptions').format(exc_count), category='success')
156 h.flash(_('Removed {} Exceptions').format(exc_count), category='success')
143 raise HTTPFound(h.route_path('admin_settings_exception_tracker'))
157 raise HTTPFound(h.route_path('admin_settings_exception_tracker'))
@@ -20,12 +20,12 b''
20
20
21 import logging
21 import logging
22
22
23 from pyramid.httpexceptions import HTTPFound
23 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
24 from pyramid.view import view_config
24 from pyramid.view import view_config
25
25
26 from rhodecode.apps._base import BaseAppView
26 from rhodecode.apps._base import BaseAppView
27 from rhodecode.lib import helpers as h
27 from rhodecode.lib import helpers as h
28 from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
28 from rhodecode.lib.auth import (LoginRequired, NotAnonymous)
29 from rhodecode.model.db import PullRequest
29 from rhodecode.model.db import PullRequest
30
30
31
31
@@ -33,14 +33,23 b' log = logging.getLogger(__name__)'
33
33
34
34
35 class AdminMainView(BaseAppView):
35 class AdminMainView(BaseAppView):
36 def load_default_context(self):
37 c = self._get_local_tmpl_context()
38 return c
36
39
37 @LoginRequired()
40 @LoginRequired()
38 @HasPermissionAllDecorator('hg.admin')
41 @NotAnonymous()
39 @view_config(
42 @view_config(
40 route_name='admin_home', request_method='GET')
43 route_name='admin_home', request_method='GET',
44 renderer='rhodecode:templates/admin/main.mako')
41 def admin_main(self):
45 def admin_main(self):
42 # redirect _admin to audit logs...
46 c = self.load_default_context()
43 raise HTTPFound(h.route_path('admin_audit_logs'))
47 c.active = 'admin'
48
49 if not (c.is_super_admin or c.is_delegated_admin):
50 raise HTTPNotFound()
51
52 return self._get_template_context(c)
44
53
45 @LoginRequired()
54 @LoginRequired()
46 @view_config(route_name='pull_requests_global_0', request_method='GET')
55 @view_config(route_name='pull_requests_global_0', request_method='GET')
@@ -49,8 +58,7 b' class AdminMainView(BaseAppView):'
49 def pull_requests(self):
58 def pull_requests(self):
50 """
59 """
51 Global redirect for Pull Requests
60 Global redirect for Pull Requests
52
61 pull_request_id: id of pull requests in the system
53 :param pull_request_id: id of pull requests in the system
54 """
62 """
55
63
56 pull_request = PullRequest.get_or_404(
64 pull_request = PullRequest.get_or_404(
@@ -17,7 +17,7 b''
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20 import datetime
21 import logging
21 import logging
22 import formencode
22 import formencode
23 import formencode.htmlfill
23 import formencode.htmlfill
@@ -30,16 +30,16 b' from pyramid.response import Response'
30 from rhodecode import events
30 from rhodecode import events
31 from rhodecode.apps._base import BaseAppView, DataGridAppView
31 from rhodecode.apps._base import BaseAppView, DataGridAppView
32
32
33 from rhodecode.lib.ext_json import json
34 from rhodecode.lib.auth import (
33 from rhodecode.lib.auth import (
35 LoginRequired, CSRFRequired, NotAnonymous,
34 LoginRequired, CSRFRequired, NotAnonymous,
36 HasPermissionAny, HasRepoGroupPermissionAny)
35 HasPermissionAny, HasRepoGroupPermissionAny)
37 from rhodecode.lib import helpers as h, audit_logger
36 from rhodecode.lib import helpers as h, audit_logger
38 from rhodecode.lib.utils2 import safe_int, safe_unicode
37 from rhodecode.lib.utils2 import safe_int, safe_unicode, datetime_to_time
39 from rhodecode.model.forms import RepoGroupForm
38 from rhodecode.model.forms import RepoGroupForm
40 from rhodecode.model.repo_group import RepoGroupModel
39 from rhodecode.model.repo_group import RepoGroupModel
41 from rhodecode.model.scm import RepoGroupList
40 from rhodecode.model.scm import RepoGroupList
42 from rhodecode.model.db import Session, RepoGroup
41 from rhodecode.model.db import (
42 or_, count, func, in_filter_generator, Session, RepoGroup, User, Repository)
43
43
44 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
45
45
@@ -88,22 +88,168 b' class AdminRepoGroupsView(BaseAppView, D'
88 return False
88 return False
89 return False
89 return False
90
90
91 # permission check in data loading of
92 # `repo_group_list_data` via RepoGroupList
91 @LoginRequired()
93 @LoginRequired()
92 @NotAnonymous()
94 @NotAnonymous()
93 # perms check inside
94 @view_config(
95 @view_config(
95 route_name='repo_groups', request_method='GET',
96 route_name='repo_groups', request_method='GET',
96 renderer='rhodecode:templates/admin/repo_groups/repo_groups.mako')
97 renderer='rhodecode:templates/admin/repo_groups/repo_groups.mako')
97 def repo_group_list(self):
98 def repo_group_list(self):
98 c = self.load_default_context()
99 c = self.load_default_context()
100 return self._get_template_context(c)
99
101
100 repo_group_list = RepoGroup.get_all_repo_groups()
102 # permission check inside
101 repo_group_list_acl = RepoGroupList(
103 @LoginRequired()
102 repo_group_list, perm_set=['group.admin'])
104 @NotAnonymous()
103 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
105 @view_config(
104 repo_group_list=repo_group_list_acl, admin=True)
106 route_name='repo_groups_data', request_method='GET',
105 c.data = json.dumps(repo_group_data)
107 renderer='json_ext', xhr=True)
106 return self._get_template_context(c)
108 def repo_group_list_data(self):
109 self.load_default_context()
110 column_map = {
111 'name_raw': 'group_name_hash',
112 'desc': 'group_description',
113 'last_change_raw': 'updated_on',
114 'top_level_repos': 'repos_total',
115 'owner': 'user_username',
116 }
117 draw, start, limit = self._extract_chunk(self.request)
118 search_q, order_by, order_dir = self._extract_ordering(
119 self.request, column_map=column_map)
120
121 _render = self.request.get_partial_renderer(
122 'rhodecode:templates/data_table/_dt_elements.mako')
123 c = _render.get_call_context()
124
125 def quick_menu(repo_group_name):
126 return _render('quick_repo_group_menu', repo_group_name)
127
128 def repo_group_lnk(repo_group_name):
129 return _render('repo_group_name', repo_group_name)
130
131 def last_change(last_change):
132 if isinstance(last_change, datetime.datetime) and not last_change.tzinfo:
133 delta = datetime.timedelta(
134 seconds=(datetime.datetime.now() - datetime.datetime.utcnow()).seconds)
135 last_change = last_change + delta
136 return _render("last_change", last_change)
137
138 def desc(desc, personal):
139 return _render(
140 'repo_group_desc', desc, personal, c.visual.stylify_metatags)
141
142 def repo_group_actions(repo_group_id, repo_group_name, gr_count):
143 return _render(
144 'repo_group_actions', repo_group_id, repo_group_name, gr_count)
145
146 def user_profile(username):
147 return _render('user_profile', username)
148
149 auth_repo_group_list = RepoGroupList(
150 RepoGroup.query().all(), perm_set=['group.admin'])
151
152 allowed_ids = [-1]
153 for repo_group in auth_repo_group_list:
154 allowed_ids.append(repo_group.group_id)
155
156 repo_groups_data_total_count = RepoGroup.query()\
157 .filter(or_(
158 # generate multiple IN to fix limitation problems
159 *in_filter_generator(RepoGroup.group_id, allowed_ids)
160 )) \
161 .count()
162
163 repo_groups_data_total_inactive_count = RepoGroup.query()\
164 .filter(RepoGroup.group_id.in_(allowed_ids))\
165 .count()
166
167 repo_count = count(Repository.repo_id)
168 base_q = Session.query(
169 RepoGroup.group_name,
170 RepoGroup.group_name_hash,
171 RepoGroup.group_description,
172 RepoGroup.group_id,
173 RepoGroup.personal,
174 RepoGroup.updated_on,
175 User,
176 repo_count.label('repos_count')
177 ) \
178 .filter(or_(
179 # generate multiple IN to fix limitation problems
180 *in_filter_generator(RepoGroup.group_id, allowed_ids)
181 )) \
182 .outerjoin(Repository) \
183 .join(User, User.user_id == RepoGroup.user_id) \
184 .group_by(RepoGroup, User)
185
186 if search_q:
187 like_expression = u'%{}%'.format(safe_unicode(search_q))
188 base_q = base_q.filter(or_(
189 RepoGroup.group_name.ilike(like_expression),
190 ))
191
192 repo_groups_data_total_filtered_count = base_q.count()
193 # the inactive isn't really used, but we still make it same as other data grids
194 # which use inactive (users,user groups)
195 repo_groups_data_total_filtered_inactive_count = repo_groups_data_total_filtered_count
196
197 sort_defined = False
198 if order_by == 'group_name':
199 sort_col = func.lower(RepoGroup.group_name)
200 sort_defined = True
201 elif order_by == 'repos_total':
202 sort_col = repo_count
203 sort_defined = True
204 elif order_by == 'user_username':
205 sort_col = User.username
206 else:
207 sort_col = getattr(RepoGroup, order_by, None)
208
209 if sort_defined or sort_col:
210 if order_dir == 'asc':
211 sort_col = sort_col.asc()
212 else:
213 sort_col = sort_col.desc()
214
215 base_q = base_q.order_by(sort_col)
216 base_q = base_q.offset(start).limit(limit)
217
218 # authenticated access to user groups
219 auth_repo_group_list = base_q.all()
220
221 repo_groups_data = []
222 for repo_gr in auth_repo_group_list:
223 row = {
224 "menu": quick_menu(repo_gr.group_name),
225 "name": repo_group_lnk(repo_gr.group_name),
226 "name_raw": repo_gr.group_name,
227 "last_change": last_change(repo_gr.updated_on),
228 "last_change_raw": datetime_to_time(repo_gr.updated_on),
229
230 "last_changeset": "",
231 "last_changeset_raw": "",
232
233 "desc": desc(repo_gr.group_description, repo_gr.personal),
234 "owner": user_profile(repo_gr.User.username),
235 "top_level_repos": repo_gr.repos_count,
236 "action": repo_group_actions(
237 repo_gr.group_id, repo_gr.group_name, repo_gr.repos_count),
238
239 }
240
241 repo_groups_data.append(row)
242
243 data = ({
244 'draw': draw,
245 'data': repo_groups_data,
246 'recordsTotal': repo_groups_data_total_count,
247 'recordsTotalInactive': repo_groups_data_total_inactive_count,
248 'recordsFiltered': repo_groups_data_total_filtered_count,
249 'recordsFilteredInactive': repo_groups_data_total_filtered_inactive_count,
250 })
251
252 return data
107
253
108 @LoginRequired()
254 @LoginRequired()
109 @NotAnonymous()
255 @NotAnonymous()
@@ -39,7 +39,7 b' from rhodecode.model.forms import UserGr'
39 from rhodecode.model.permission import PermissionModel
39 from rhodecode.model.permission import PermissionModel
40 from rhodecode.model.scm import UserGroupList
40 from rhodecode.model.scm import UserGroupList
41 from rhodecode.model.db import (
41 from rhodecode.model.db import (
42 or_, count, User, UserGroup, UserGroupMember)
42 or_, count, User, UserGroup, UserGroupMember, in_filter_generator)
43 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
44 from rhodecode.model.user_group import UserGroupModel
44 from rhodecode.model.user_group import UserGroupModel
45 from rhodecode.model.db import true
45 from rhodecode.model.db import true
@@ -107,11 +107,17 b' class AdminUserGroupsView(BaseAppView, D'
107 allowed_ids.append(user_group.users_group_id)
107 allowed_ids.append(user_group.users_group_id)
108
108
109 user_groups_data_total_count = UserGroup.query()\
109 user_groups_data_total_count = UserGroup.query()\
110 .filter(UserGroup.users_group_id.in_(allowed_ids))\
110 .filter(or_(
111 # generate multiple IN to fix limitation problems
112 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
113 ))\
111 .count()
114 .count()
112
115
113 user_groups_data_total_inactive_count = UserGroup.query()\
116 user_groups_data_total_inactive_count = UserGroup.query()\
114 .filter(UserGroup.users_group_id.in_(allowed_ids))\
117 .filter(or_(
118 # generate multiple IN to fix limitation problems
119 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
120 ))\
115 .filter(UserGroup.users_group_active != true()).count()
121 .filter(UserGroup.users_group_active != true()).count()
116
122
117 member_count = count(UserGroupMember.user_id)
123 member_count = count(UserGroupMember.user_id)
@@ -124,7 +130,10 b' class AdminUserGroupsView(BaseAppView, D'
124 User,
130 User,
125 member_count.label('member_count')
131 member_count.label('member_count')
126 ) \
132 ) \
127 .filter(UserGroup.users_group_id.in_(allowed_ids)) \
133 .filter(or_(
134 # generate multiple IN to fix limitation problems
135 *in_filter_generator(UserGroup.users_group_id, allowed_ids)
136 )) \
128 .outerjoin(UserGroupMember) \
137 .outerjoin(UserGroupMember) \
129 .join(User, User.user_id == UserGroup.user_id) \
138 .join(User, User.user_id == UserGroup.user_id) \
130 .group_by(UserGroup, User)
139 .group_by(UserGroup, User)
@@ -141,14 +150,16 b' class AdminUserGroupsView(BaseAppView, D'
141 user_groups_data_total_filtered_count = base_q.count()
150 user_groups_data_total_filtered_count = base_q.count()
142 user_groups_data_total_filtered_inactive_count = base_q_inactive.count()
151 user_groups_data_total_filtered_inactive_count = base_q_inactive.count()
143
152
153 sort_defined = False
144 if order_by == 'members_total':
154 if order_by == 'members_total':
145 sort_col = member_count
155 sort_col = member_count
156 sort_defined = True
146 elif order_by == 'user_username':
157 elif order_by == 'user_username':
147 sort_col = User.username
158 sort_col = User.username
148 else:
159 else:
149 sort_col = getattr(UserGroup, order_by, None)
160 sort_col = getattr(UserGroup, order_by, None)
150
161
151 if isinstance(sort_col, count) or sort_col:
162 if sort_defined or sort_col:
152 if order_dir == 'asc':
163 if order_dir == 'asc':
153 sort_col = sort_col.asc()
164 sort_col = sort_col.asc()
154 else:
165 else:
@@ -162,7 +173,7 b' class AdminUserGroupsView(BaseAppView, D'
162
173
163 user_groups_data = []
174 user_groups_data = []
164 for user_gr in auth_user_group_list:
175 for user_gr in auth_user_group_list:
165 user_groups_data.append({
176 row = {
166 "users_group_name": user_group_name(user_gr.users_group_name),
177 "users_group_name": user_group_name(user_gr.users_group_name),
167 "name_raw": h.escape(user_gr.users_group_name),
178 "name_raw": h.escape(user_gr.users_group_name),
168 "description": h.escape(user_gr.user_group_description),
179 "description": h.escape(user_gr.user_group_description),
@@ -175,7 +186,8 b' class AdminUserGroupsView(BaseAppView, D'
175 "owner": user_profile(user_gr.User.username),
186 "owner": user_profile(user_gr.User.username),
176 "action": user_group_actions(
187 "action": user_group_actions(
177 user_gr.users_group_id, user_gr.users_group_name)
188 user_gr.users_group_id, user_gr.users_group_name)
178 })
189 }
190 user_groups_data.append(row)
179
191
180 data = ({
192 data = ({
181 'draw': draw,
193 'draw': draw,
@@ -682,8 +682,7 b' class UsersView(UserAppView):'
682 if personal_repo_group:
682 if personal_repo_group:
683 raise HTTPFound(h.route_path('user_edit_advanced', user_id=user_id))
683 raise HTTPFound(h.route_path('user_edit_advanced', user_id=user_id))
684
684
685 personal_repo_group_name = RepoGroupModel().get_personal_group_name(
685 personal_repo_group_name = RepoGroupModel().get_personal_group_name(c.user)
686 c.user)
687 named_personal_group = RepoGroup.get_by_group_name(
686 named_personal_group = RepoGroup.get_by_group_name(
688 personal_repo_group_name)
687 personal_repo_group_name)
689 try:
688 try:
@@ -38,19 +38,18 b' class LocalFileStorage(object):'
38 """
38 """
39 Resolves a unique name and the correct path. If a filename
39 Resolves a unique name and the correct path. If a filename
40 for that path already exists then a numeric prefix with values > 0 will be
40 for that path already exists then a numeric prefix with values > 0 will be
41 added, for example test.jpg -> test-1.jpg etc. initially file would have 0 prefix.
41 added, for example test.jpg -> 1-test.jpg etc. initially file would have 0 prefix.
42
42
43 :param name: base name of file
43 :param name: base name of file
44 :param directory: absolute directory path
44 :param directory: absolute directory path
45 """
45 """
46
46
47 basename, ext = os.path.splitext(name)
48 counter = 0
47 counter = 0
49 while True:
48 while True:
50 name = '%s-%d%s' % (basename, counter, ext)
49 name = '%d-%s' % (counter, name)
51
50
52 # sub_store prefix to optimize disk usage, e.g some_path/ab/final_file
51 # sub_store prefix to optimize disk usage, e.g some_path/ab/final_file
53 sub_store = cls._sub_store_from_filename(basename)
52 sub_store = cls._sub_store_from_filename(name)
54 sub_store_path = os.path.join(directory, sub_store)
53 sub_store_path = os.path.join(directory, sub_store)
55 if not os.path.exists(sub_store_path):
54 if not os.path.exists(sub_store_path):
56 os.makedirs(sub_store_path)
55 os.makedirs(sub_store_path)
@@ -209,3 +208,16 b' class LocalFileStorage(object):'
209 filename = os.path.join(directory, filename)
208 filename = os.path.join(directory, filename)
210
209
211 return filename, metadata
210 return filename, metadata
211
212 def get_metadata(self, filename):
213 """
214 Reads JSON stored metadata for a file
215
216 :param filename:
217 :return:
218 """
219 filename = self.store_path(filename)
220 filename_meta = filename + '.meta'
221
222 with open(filename_meta, "rb") as source_meta:
223 return json.loads(source_meta.read())
@@ -21,6 +21,7 b' import os'
21 import pytest
21 import pytest
22
22
23 from rhodecode.lib.ext_json import json
23 from rhodecode.lib.ext_json import json
24 from rhodecode.model.db import Session, FileStore
24 from rhodecode.tests import TestController
25 from rhodecode.tests import TestController
25 from rhodecode.apps.file_store import utils, config_keys
26 from rhodecode.apps.file_store import utils, config_keys
26
27
@@ -46,9 +47,12 b' class TestFileStoreViews(TestController)'
46 ('abcde-0.exe', "1234567", True),
47 ('abcde-0.exe', "1234567", True),
47 ('abcde-0.jpg', "xxxxx", False),
48 ('abcde-0.jpg', "xxxxx", False),
48 ])
49 ])
49 def test_get_files_from_store(self, fid, content, exists, tmpdir):
50 def test_get_files_from_store(self, fid, content, exists, tmpdir, user_util):
50 self.log_user()
51 user = self.log_user()
52 user_id = user['user_id']
53 repo_id = user_util.create_repo().repo_id
51 store_path = self.app._pyramid_settings[config_keys.store_path]
54 store_path = self.app._pyramid_settings[config_keys.store_path]
55 store_uid = fid
52
56
53 if exists:
57 if exists:
54 status = 200
58 status = 200
@@ -58,17 +62,28 b' class TestFileStoreViews(TestController)'
58 f.write(content)
62 f.write(content)
59
63
60 with open(filesystem_file, 'rb') as f:
64 with open(filesystem_file, 'rb') as f:
61 fid, metadata = store.save_file(f, fid, extra_metadata={'filename': fid})
65 store_uid, metadata = store.save_file(f, fid, extra_metadata={'filename': fid})
66
67 entry = FileStore.create(
68 file_uid=store_uid, filename=metadata["filename"],
69 file_hash=metadata["sha256"], file_size=metadata["size"],
70 file_display_name='file_display_name',
71 file_description='repo artifact `{}`'.format(metadata["filename"]),
72 check_acl=True, user_id=user_id,
73 scope_repo_id=repo_id
74 )
75 Session().add(entry)
76 Session().commit()
62
77
63 else:
78 else:
64 status = 404
79 status = 404
65
80
66 response = self.app.get(route_path('download_file', fid=fid), status=status)
81 response = self.app.get(route_path('download_file', fid=store_uid), status=status)
67
82
68 if exists:
83 if exists:
69 assert response.text == content
84 assert response.text == content
70 file_store_path = os.path.dirname(store.resolve_name(fid, store_path)[1])
85 file_store_path = os.path.dirname(store.resolve_name(store_uid, store_path)[1])
71 metadata_file = os.path.join(file_store_path, fid + '.meta')
86 metadata_file = os.path.join(file_store_path, store_uid + '.meta')
72 assert os.path.exists(metadata_file)
87 assert os.path.exists(metadata_file)
73 with open(metadata_file, 'rb') as f:
88 with open(metadata_file, 'rb') as f:
74 json_data = json.loads(f.read())
89 json_data = json.loads(f.read())
@@ -19,9 +19,10 b''
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import os
23 import uuid
22 import uuid
24
23
24 import pathlib2
25
25
26
26 def get_file_storage(settings):
27 def get_file_storage(settings):
27 from rhodecode.apps.file_store.local_store import LocalFileStorage
28 from rhodecode.apps.file_store.local_store import LocalFileStorage
@@ -30,6 +31,11 b' def get_file_storage(settings):'
30 return LocalFileStorage(base_path=store_path)
31 return LocalFileStorage(base_path=store_path)
31
32
32
33
34 def splitext(filename):
35 ext = ''.join(pathlib2.Path(filename).suffixes)
36 return filename, ext
37
38
33 def uid_filename(filename, randomized=True):
39 def uid_filename(filename, randomized=True):
34 """
40 """
35 Generates a randomized or stable (uuid) filename,
41 Generates a randomized or stable (uuid) filename,
@@ -38,7 +44,8 b' def uid_filename(filename, randomized=Tr'
38 :param filename: the original filename
44 :param filename: the original filename
39 :param randomized: define if filename should be stable (sha1 based) or randomized
45 :param randomized: define if filename should be stable (sha1 based) or randomized
40 """
46 """
41 _, ext = os.path.splitext(filename)
47
48 _, ext = splitext(filename)
42 if randomized:
49 if randomized:
43 uid = uuid.uuid4()
50 uid = uuid.uuid4()
44 else:
51 else:
@@ -30,7 +30,7 b' from rhodecode.apps.file_store.exception'
30
30
31 from rhodecode.lib import helpers as h
31 from rhodecode.lib import helpers as h
32 from rhodecode.lib import audit_logger
32 from rhodecode.lib import audit_logger
33 from rhodecode.lib.auth import (CSRFRequired, NotAnonymous)
33 from rhodecode.lib.auth import (CSRFRequired, NotAnonymous, HasRepoPermissionAny, HasRepoGroupPermissionAny)
34 from rhodecode.model.db import Session, FileStore
34 from rhodecode.model.db import Session, FileStore
35
35
36 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
@@ -68,7 +68,7 b' class FileStoreView(BaseAppView):'
68 'user_id': self._rhodecode_user.user_id,
68 'user_id': self._rhodecode_user.user_id,
69 'ip': self._rhodecode_user.ip_addr}}
69 'ip': self._rhodecode_user.ip_addr}}
70 try:
70 try:
71 store_fid, metadata = self.storage.save_file(
71 store_uid, metadata = self.storage.save_file(
72 file_obj.file, filename, extra_metadata=metadata)
72 file_obj.file, filename, extra_metadata=metadata)
73 except FileNotAllowedException:
73 except FileNotAllowedException:
74 return {'store_fid': None,
74 return {'store_fid': None,
@@ -82,7 +82,7 b' class FileStoreView(BaseAppView):'
82
82
83 try:
83 try:
84 entry = FileStore.create(
84 entry = FileStore.create(
85 file_uid=store_fid, filename=metadata["filename"],
85 file_uid=store_uid, filename=metadata["filename"],
86 file_hash=metadata["sha256"], file_size=metadata["size"],
86 file_hash=metadata["sha256"], file_size=metadata["size"],
87 file_description='upload attachment',
87 file_description='upload attachment',
88 check_acl=False, user_id=self._rhodecode_user.user_id
88 check_acl=False, user_id=self._rhodecode_user.user_id
@@ -96,8 +96,8 b' class FileStoreView(BaseAppView):'
96 'access_path': None,
96 'access_path': None,
97 'error': 'File {} failed to store in DB.'.format(filename)}
97 'error': 'File {} failed to store in DB.'.format(filename)}
98
98
99 return {'store_fid': store_fid,
99 return {'store_fid': store_uid,
100 'access_path': h.route_path('download_file', fid=store_fid)}
100 'access_path': h.route_path('download_file', fid=store_uid)}
101
101
102 @view_config(route_name='download_file')
102 @view_config(route_name='download_file')
103 def download_file(self):
103 def download_file(self):
@@ -109,6 +109,35 b' class FileStoreView(BaseAppView):'
109 log.debug('File with FID:%s not found in the store', file_uid)
109 log.debug('File with FID:%s not found in the store', file_uid)
110 raise HTTPNotFound()
110 raise HTTPNotFound()
111
111
112 db_obj = FileStore().query().filter(FileStore.file_uid == file_uid).scalar()
113 if not db_obj:
114 raise HTTPNotFound()
115
116 # private upload for user
117 if db_obj.check_acl and db_obj.scope_user_id:
118 user = db_obj.user
119 if self._rhodecode_db_user.user_id != user.user_id:
120 log.warning('Access to file store object forbidden')
121 raise HTTPNotFound()
122
123 # scoped to repository permissions
124 if db_obj.check_acl and db_obj.scope_repo_id:
125 repo = db_obj.repo
126 perm_set = ['repository.read', 'repository.write', 'repository.admin']
127 has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'FileStore check')
128 if not has_perm:
129 log.warning('Access to file store object forbidden')
130 raise HTTPNotFound()
131
132 # scoped to repository group permissions
133 if db_obj.check_acl and db_obj.scope_repo_group_id:
134 repo_group = db_obj.repo_group
135 perm_set = ['group.read', 'group.write', 'group.admin']
136 has_perm = HasRepoGroupPermissionAny(*perm_set)(repo_group.group_name, 'FileStore check')
137 if not has_perm:
138 log.warning('Access to file store object forbidden')
139 raise HTTPNotFound()
140
112 FileStore.bump_access_counter(file_uid)
141 FileStore.bump_access_counter(file_uid)
113
142
114 file_path = self.storage.store_path(file_uid)
143 file_path = self.storage.store_path(file_uid)
@@ -25,7 +25,7 b' import formencode'
25 import formencode.htmlfill
25 import formencode.htmlfill
26 import peppercorn
26 import peppercorn
27
27
28 from pyramid.httpexceptions import HTTPNotFound, HTTPFound
28 from pyramid.httpexceptions import HTTPNotFound, HTTPFound, HTTPBadRequest
29 from pyramid.view import view_config
29 from pyramid.view import view_config
30 from pyramid.renderers import render
30 from pyramid.renderers import render
31 from pyramid.response import Response
31 from pyramid.response import Response
@@ -67,7 +67,6 b' class GistView(BaseAppView):'
67 (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users"))
67 (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users"))
68 ]
68 ]
69
69
70
71 return c
70 return c
72
71
73 @LoginRequired()
72 @LoginRequired()
@@ -296,6 +295,8 b' class GistView(BaseAppView):'
296 response = Response(content)
295 response = Response(content)
297 response.content_type = 'text/plain'
296 response.content_type = 'text/plain'
298 return response
297 return response
298 elif return_format:
299 raise HTTPBadRequest()
299
300
300 return self._get_template_context(c)
301 return self._get_template_context(c)
301
302
@@ -68,6 +68,10 b' def includeme(config):'
68 pattern='/_markup_preview')
68 pattern='/_markup_preview')
69
69
70 config.add_route(
70 config.add_route(
71 name='file_preview',
72 pattern='/_file_preview')
73
74 config.add_route(
71 name='store_user_session_value',
75 name='store_user_session_value',
72 pattern='/_store_session_attr')
76 pattern='/_store_session_attr')
73
77
@@ -27,13 +27,14 b' from pyramid.view import view_config'
27 from rhodecode.apps._base import BaseAppView
27 from rhodecode.apps._base import BaseAppView
28 from rhodecode.lib import helpers as h
28 from rhodecode.lib import helpers as h
29 from rhodecode.lib.auth import (
29 from rhodecode.lib.auth import (
30 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator,
30 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator, CSRFRequired)
31 CSRFRequired)
31 from rhodecode.lib.codeblocks import filenode_as_lines_tokens
32 from rhodecode.lib.index import searcher_from_config
32 from rhodecode.lib.index import searcher_from_config
33 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
33 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
34 from rhodecode.lib.ext_json import json
34 from rhodecode.lib.ext_json import json
35 from rhodecode.lib.vcs.nodes import FileNode
35 from rhodecode.model.db import (
36 from rhodecode.model.db import (
36 func, true, or_, in_filter_generator, Repository, RepoGroup, User, UserGroup)
37 func, true, or_, case, in_filter_generator, Repository, RepoGroup, User, UserGroup)
37 from rhodecode.model.repo import RepoModel
38 from rhodecode.model.repo import RepoModel
38 from rhodecode.model.repo_group import RepoGroupModel
39 from rhodecode.model.repo_group import RepoGroupModel
39 from rhodecode.model.scm import RepoGroupList, RepoList
40 from rhodecode.model.scm import RepoGroupList, RepoList
@@ -105,21 +106,27 b' class HomeView(BaseAppView):'
105
106
106 return {'suggestions': _user_groups}
107 return {'suggestions': _user_groups}
107
108
108 def _get_repo_list(self, name_contains=None, repo_type=None, limit=20):
109 def _get_repo_list(self, name_contains=None, repo_type=None, repo_group_name='', limit=20):
109 org_query = name_contains
110 org_query = name_contains
110 allowed_ids = self._rhodecode_user.repo_acl_ids(
111 allowed_ids = self._rhodecode_user.repo_acl_ids(
111 ['repository.read', 'repository.write', 'repository.admin'],
112 ['repository.read', 'repository.write', 'repository.admin'],
112 cache=False, name_filter=name_contains) or [-1]
113 cache=False, name_filter=name_contains) or [-1]
113
114
114 query = Repository.query()\
115 query = Repository.query()\
115 .order_by(func.length(Repository.repo_name))\
116 .order_by(Repository.repo_name)\
117 .filter(Repository.archived.isnot(true()))\
116 .filter(Repository.archived.isnot(true()))\
118 .filter(or_(
117 .filter(or_(
119 # generate multiple IN to fix limitation problems
118 # generate multiple IN to fix limitation problems
120 *in_filter_generator(Repository.repo_id, allowed_ids)
119 *in_filter_generator(Repository.repo_id, allowed_ids)
121 ))
120 ))
122
121
122 query = query.order_by(case(
123 [
124 (Repository.repo_name.startswith(repo_group_name), repo_group_name+'/'),
125 ],
126 ))
127 query = query.order_by(func.length(Repository.repo_name))
128 query = query.order_by(Repository.repo_name)
129
123 if repo_type:
130 if repo_type:
124 query = query.filter(Repository.repo_type == repo_type)
131 query = query.filter(Repository.repo_type == repo_type)
125
132
@@ -145,20 +152,26 b' class HomeView(BaseAppView):'
145 }
152 }
146 for obj in acl_iter]
153 for obj in acl_iter]
147
154
148 def _get_repo_group_list(self, name_contains=None, limit=20):
155 def _get_repo_group_list(self, name_contains=None, repo_group_name='', limit=20):
149 org_query = name_contains
156 org_query = name_contains
150 allowed_ids = self._rhodecode_user.repo_group_acl_ids(
157 allowed_ids = self._rhodecode_user.repo_group_acl_ids(
151 ['group.read', 'group.write', 'group.admin'],
158 ['group.read', 'group.write', 'group.admin'],
152 cache=False, name_filter=name_contains) or [-1]
159 cache=False, name_filter=name_contains) or [-1]
153
160
154 query = RepoGroup.query()\
161 query = RepoGroup.query()\
155 .order_by(func.length(RepoGroup.group_name))\
156 .order_by(RepoGroup.group_name) \
157 .filter(or_(
162 .filter(or_(
158 # generate multiple IN to fix limitation problems
163 # generate multiple IN to fix limitation problems
159 *in_filter_generator(RepoGroup.group_id, allowed_ids)
164 *in_filter_generator(RepoGroup.group_id, allowed_ids)
160 ))
165 ))
161
166
167 query = query.order_by(case(
168 [
169 (RepoGroup.group_name.startswith(repo_group_name), repo_group_name+'/'),
170 ],
171 ))
172 query = query.order_by(func.length(RepoGroup.group_name))
173 query = query.order_by(RepoGroup.group_name)
174
162 if name_contains:
175 if name_contains:
163 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
176 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
164 query = query.filter(
177 query = query.filter(
@@ -183,11 +196,17 b' class HomeView(BaseAppView):'
183 def _get_user_list(self, name_contains=None, limit=20):
196 def _get_user_list(self, name_contains=None, limit=20):
184 org_query = name_contains
197 org_query = name_contains
185 if not name_contains:
198 if not name_contains:
186 return []
199 return [], False
187
200
188 name_contains = re.compile('(?:user:)(.+)').findall(name_contains)
201 # TODO(marcink): should all logged in users be allowed to search others?
202 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
203 if not allowed_user_search:
204 return [], False
205
206 name_contains = re.compile('(?:user:[ ]?)(.+)').findall(name_contains)
189 if len(name_contains) != 1:
207 if len(name_contains) != 1:
190 return []
208 return [], False
209
191 name_contains = name_contains[0]
210 name_contains = name_contains[0]
192
211
193 query = User.query()\
212 query = User.query()\
@@ -207,22 +226,28 b' class HomeView(BaseAppView):'
207 {
226 {
208 'id': obj.user_id,
227 'id': obj.user_id,
209 'value': org_query,
228 'value': org_query,
210 'value_display': obj.username,
229 'value_display': 'user: `{}`'.format(obj.username),
211 'type': 'user',
230 'type': 'user',
212 'icon_link': h.gravatar_url(obj.email, 30),
231 'icon_link': h.gravatar_url(obj.email, 30),
213 'url': h.route_path(
232 'url': h.route_path(
214 'user_profile', username=obj.username)
233 'user_profile', username=obj.username)
215 }
234 }
216 for obj in acl_iter]
235 for obj in acl_iter], True
217
236
218 def _get_user_groups_list(self, name_contains=None, limit=20):
237 def _get_user_groups_list(self, name_contains=None, limit=20):
219 org_query = name_contains
238 org_query = name_contains
220 if not name_contains:
239 if not name_contains:
221 return []
240 return [], False
222
241
223 name_contains = re.compile('(?:user_group:)(.+)').findall(name_contains)
242 # TODO(marcink): should all logged in users be allowed to search others?
243 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
244 if not allowed_user_search:
245 return [], False
246
247 name_contains = re.compile('(?:user_group:[ ]?)(.+)').findall(name_contains)
224 if len(name_contains) != 1:
248 if len(name_contains) != 1:
225 return []
249 return [], False
250
226 name_contains = name_contains[0]
251 name_contains = name_contains[0]
227
252
228 query = UserGroup.query()\
253 query = UserGroup.query()\
@@ -241,27 +266,34 b' class HomeView(BaseAppView):'
241 {
266 {
242 'id': obj.users_group_id,
267 'id': obj.users_group_id,
243 'value': org_query,
268 'value': org_query,
244 'value_display': obj.users_group_name,
269 'value_display': 'user_group: `{}`'.format(obj.users_group_name),
245 'type': 'user_group',
270 'type': 'user_group',
246 'url': h.route_path(
271 'url': h.route_path(
247 'user_group_profile', user_group_name=obj.users_group_name)
272 'user_group_profile', user_group_name=obj.users_group_name)
248 }
273 }
249 for obj in acl_iter]
274 for obj in acl_iter], True
250
275
251 def _get_hash_commit_list(self, auth_user, searcher, query):
276 def _get_hash_commit_list(self, auth_user, searcher, query, repo=None, repo_group=None):
277 repo_name = repo_group_name = None
278 if repo:
279 repo_name = repo.repo_name
280 if repo_group:
281 repo_group_name = repo_group.group_name
282
252 org_query = query
283 org_query = query
253 if not query or len(query) < 3 or not searcher:
284 if not query or len(query) < 3 or not searcher:
254 return []
285 return [], False
255
286
256 commit_hashes = re.compile('(?:commit:)([0-9a-f]{2,40})').findall(query)
287 commit_hashes = re.compile('(?:commit:[ ]?)([0-9a-f]{2,40})').findall(query)
257
288
258 if len(commit_hashes) != 1:
289 if len(commit_hashes) != 1:
259 return []
290 return [], False
291
260 commit_hash = commit_hashes[0]
292 commit_hash = commit_hashes[0]
261
293
262 result = searcher.search(
294 result = searcher.search(
263 'commit_id:{}*'.format(commit_hash), 'commit', auth_user,
295 'commit_id:{}*'.format(commit_hash), 'commit', auth_user,
264 raise_on_exc=False)
296 repo_name, repo_group_name, raise_on_exc=False)
265
297
266 commits = []
298 commits = []
267 for entry in result['results']:
299 for entry in result['results']:
@@ -286,7 +318,55 b' class HomeView(BaseAppView):'
286 }
318 }
287
319
288 commits.append(commit_entry)
320 commits.append(commit_entry)
289 return commits
321 return commits, True
322
323 def _get_path_list(self, auth_user, searcher, query, repo=None, repo_group=None):
324 repo_name = repo_group_name = None
325 if repo:
326 repo_name = repo.repo_name
327 if repo_group:
328 repo_group_name = repo_group.group_name
329
330 org_query = query
331 if not query or len(query) < 3 or not searcher:
332 return [], False
333
334 paths_re = re.compile('(?:file:[ ]?)(.+)').findall(query)
335 if len(paths_re) != 1:
336 return [], False
337
338 file_path = paths_re[0]
339
340 search_path = searcher.escape_specials(file_path)
341 result = searcher.search(
342 'file.raw:*{}*'.format(search_path), 'path', auth_user,
343 repo_name, repo_group_name, raise_on_exc=False)
344
345 files = []
346 for entry in result['results']:
347 repo_data = {
348 'repository_id': entry.get('repository_id'),
349 'repository_type': entry.get('repo_type'),
350 'repository_name': entry.get('repository'),
351 }
352
353 file_entry = {
354 'id': entry['commit_id'],
355 'value': org_query,
356 'value_display': '`{}` file: {}'.format(
357 entry['repository'], entry['file']),
358 'type': 'file',
359 'repo': entry['repository'],
360 'repo_data': repo_data,
361
362 'url': h.route_path(
363 'repo_files',
364 repo_name=entry['repository'], commit_id=entry['commit_id'],
365 f_path=entry['file'])
366 }
367
368 files.append(file_entry)
369 return files, True
290
370
291 @LoginRequired()
371 @LoginRequired()
292 @view_config(
372 @view_config(
@@ -363,36 +443,42 b' class HomeView(BaseAppView):'
363 def query_modifier():
443 def query_modifier():
364 qry = query
444 qry = query
365 return {'q': qry, 'type': 'content'}
445 return {'q': qry, 'type': 'content'}
366 label = u'File search for `{}` in this repository.'.format(query)
446
367 queries.append(
447 label = u'File search for `{}`'.format(h.escape(query))
368 {
448 file_qry = {
369 'id': -10,
449 'id': -10,
370 'value': query,
450 'value': query,
371 'value_display': label,
451 'value_display': label,
372 'type': 'search',
452 'type': 'search',
453 'subtype': 'repo',
373 'url': h.route_path('search_repo',
454 'url': h.route_path('search_repo',
374 repo_name=repo_name,
455 repo_name=repo_name,
375 _query=query_modifier())
456 _query=query_modifier())
376 }
457 }
377 )
378
458
379 # commits
459 # commits
380 def query_modifier():
460 def query_modifier():
381 qry = query
461 qry = query
382 return {'q': qry, 'type': 'commit'}
462 return {'q': qry, 'type': 'commit'}
383
463
384 label = u'Commit search for `{}` in this repository.'.format(query)
464 label = u'Commit search for `{}`'.format(h.escape(query))
385 queries.append(
465 commit_qry = {
386 {
387 'id': -20,
466 'id': -20,
388 'value': query,
467 'value': query,
389 'value_display': label,
468 'value_display': label,
390 'type': 'search',
469 'type': 'search',
470 'subtype': 'repo',
391 'url': h.route_path('search_repo',
471 'url': h.route_path('search_repo',
392 repo_name=repo_name,
472 repo_name=repo_name,
393 _query=query_modifier())
473 _query=query_modifier())
394 }
474 }
395 )
475
476 if repo_context in ['commit', 'commits']:
477 queries.extend([commit_qry, file_qry])
478 elif repo_context in ['files', 'summary']:
479 queries.extend([file_qry, commit_qry])
480 else:
481 queries.extend([commit_qry, file_qry])
396
482
397 elif is_es_6 and repo_group_name:
483 elif is_es_6 and repo_group_name:
398 # files
484 # files
@@ -400,37 +486,43 b' class HomeView(BaseAppView):'
400 qry = query
486 qry = query
401 return {'q': qry, 'type': 'content'}
487 return {'q': qry, 'type': 'content'}
402
488
403 label = u'File search for `{}` in this repository group'.format(query)
489 label = u'File search for `{}`'.format(query)
404 queries.append(
490 file_qry = {
405 {
406 'id': -30,
491 'id': -30,
407 'value': query,
492 'value': query,
408 'value_display': label,
493 'value_display': label,
409 'type': 'search',
494 'type': 'search',
495 'subtype': 'repo_group',
410 'url': h.route_path('search_repo_group',
496 'url': h.route_path('search_repo_group',
411 repo_group_name=repo_group_name,
497 repo_group_name=repo_group_name,
412 _query=query_modifier())
498 _query=query_modifier())
413 }
499 }
414 )
415
500
416 # commits
501 # commits
417 def query_modifier():
502 def query_modifier():
418 qry = query
503 qry = query
419 return {'q': qry, 'type': 'commit'}
504 return {'q': qry, 'type': 'commit'}
420
505
421 label = u'Commit search for `{}` in this repository group'.format(query)
506 label = u'Commit search for `{}`'.format(query)
422 queries.append(
507 commit_qry = {
423 {
424 'id': -40,
508 'id': -40,
425 'value': query,
509 'value': query,
426 'value_display': label,
510 'value_display': label,
427 'type': 'search',
511 'type': 'search',
512 'subtype': 'repo_group',
428 'url': h.route_path('search_repo_group',
513 'url': h.route_path('search_repo_group',
429 repo_group_name=repo_group_name,
514 repo_group_name=repo_group_name,
430 _query=query_modifier())
515 _query=query_modifier())
431 }
516 }
432 )
433
517
518 if repo_context in ['commit', 'commits']:
519 queries.extend([commit_qry, file_qry])
520 elif repo_context in ['files', 'summary']:
521 queries.extend([file_qry, commit_qry])
522 else:
523 queries.extend([commit_qry, file_qry])
524
525 # Global, not scoped
434 if not queries:
526 if not queries:
435 queries.append(
527 queries.append(
436 {
528 {
@@ -438,6 +530,7 b' class HomeView(BaseAppView):'
438 'value': query,
530 'value': query,
439 'value_display': u'File search for: `{}`'.format(query),
531 'value_display': u'File search for: `{}`'.format(query),
440 'type': 'search',
532 'type': 'search',
533 'subtype': 'global',
441 'url': h.route_path('search',
534 'url': h.route_path('search',
442 _query={'q': query, 'type': 'content'})
535 _query={'q': query, 'type': 'content'})
443 })
536 })
@@ -447,6 +540,7 b' class HomeView(BaseAppView):'
447 'value': query,
540 'value': query,
448 'value_display': u'Commit search for: `{}`'.format(query),
541 'value_display': u'Commit search for: `{}`'.format(query),
449 'type': 'search',
542 'type': 'search',
543 'subtype': 'global',
450 'url': h.route_path('search',
544 'url': h.route_path('search',
451 _query={'q': query, 'type': 'commit'})
545 _query={'q': query, 'type': 'commit'})
452 })
546 })
@@ -469,54 +563,107 b' class HomeView(BaseAppView):'
469 if not query:
563 if not query:
470 return {'suggestions': res}
564 return {'suggestions': res}
471
565
566 def no_match(name):
567 return {
568 'id': -1,
569 'value': "",
570 'value_display': name,
571 'type': 'text',
572 'url': ""
573 }
472 searcher = searcher_from_config(self.request.registry.settings)
574 searcher = searcher_from_config(self.request.registry.settings)
473 for _q in self._get_default_search_queries(self.request.GET, searcher, query):
575 has_specialized_search = False
474 res.append(_q)
475
576
577 # set repo context
578 repo = None
579 repo_id = safe_int(self.request.GET.get('search_context[repo_id]'))
580 if repo_id:
581 repo = Repository.get(repo_id)
582
583 # set group context
584 repo_group = None
476 repo_group_id = safe_int(self.request.GET.get('search_context[repo_group_id]'))
585 repo_group_id = safe_int(self.request.GET.get('search_context[repo_group_id]'))
477 if repo_group_id:
586 if repo_group_id:
478 repo_group = RepoGroup.get(repo_group_id)
587 repo_group = RepoGroup.get(repo_group_id)
479 composed_hint = '{}/{}'.format(repo_group.group_name, query)
588 prefix_match = False
480 show_hint = not query.startswith(repo_group.group_name)
481 if repo_group and show_hint:
482 hint = u'Repository search inside: `{}`'.format(composed_hint)
483 res.append({
484 'id': -1,
485 'value': composed_hint,
486 'value_display': hint,
487 'type': 'hint',
488 'url': ""
489 })
490
589
491 repo_groups = self._get_repo_group_list(query)
590 # user: type search
492 for serialized_repo_group in repo_groups:
591 if not prefix_match:
493 res.append(serialized_repo_group)
592 users, prefix_match = self._get_user_list(query)
494
593 if users:
495 repos = self._get_repo_list(query)
594 has_specialized_search = True
496 for serialized_repo in repos:
497 res.append(serialized_repo)
498
499 # TODO(marcink): should all logged in users be allowed to search others?
500 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
501 if allowed_user_search:
502 users = self._get_user_list(query)
503 for serialized_user in users:
595 for serialized_user in users:
504 res.append(serialized_user)
596 res.append(serialized_user)
597 elif prefix_match:
598 has_specialized_search = True
599 res.append(no_match('No matching users found'))
505
600
506 user_groups = self._get_user_groups_list(query)
601 # user_group: type search
602 if not prefix_match:
603 user_groups, prefix_match = self._get_user_groups_list(query)
604 if user_groups:
605 has_specialized_search = True
507 for serialized_user_group in user_groups:
606 for serialized_user_group in user_groups:
508 res.append(serialized_user_group)
607 res.append(serialized_user_group)
608 elif prefix_match:
609 has_specialized_search = True
610 res.append(no_match('No matching user groups found'))
509
611
510 commits = self._get_hash_commit_list(c.auth_user, searcher, query)
612 # FTS commit: type search
613 if not prefix_match:
614 commits, prefix_match = self._get_hash_commit_list(
615 c.auth_user, searcher, query, repo, repo_group)
511 if commits:
616 if commits:
617 has_specialized_search = True
512 unique_repos = collections.OrderedDict()
618 unique_repos = collections.OrderedDict()
513 for commit in commits:
619 for commit in commits:
514 repo_name = commit['repo']
620 repo_name = commit['repo']
515 unique_repos.setdefault(repo_name, []).append(commit)
621 unique_repos.setdefault(repo_name, []).append(commit)
516
622
517 for repo, commits in unique_repos.items():
623 for _repo, commits in unique_repos.items():
518 for commit in commits:
624 for commit in commits:
519 res.append(commit)
625 res.append(commit)
626 elif prefix_match:
627 has_specialized_search = True
628 res.append(no_match('No matching commits found'))
629
630 # FTS file: type search
631 if not prefix_match:
632 paths, prefix_match = self._get_path_list(
633 c.auth_user, searcher, query, repo, repo_group)
634 if paths:
635 has_specialized_search = True
636 unique_repos = collections.OrderedDict()
637 for path in paths:
638 repo_name = path['repo']
639 unique_repos.setdefault(repo_name, []).append(path)
640
641 for repo, paths in unique_repos.items():
642 for path in paths:
643 res.append(path)
644 elif prefix_match:
645 has_specialized_search = True
646 res.append(no_match('No matching files found'))
647
648 # main suggestions
649 if not has_specialized_search:
650 repo_group_name = ''
651 if repo_group:
652 repo_group_name = repo_group.group_name
653
654 for _q in self._get_default_search_queries(self.request.GET, searcher, query):
655 res.append(_q)
656
657 repo_groups = self._get_repo_group_list(query, repo_group_name=repo_group_name)
658 for serialized_repo_group in repo_groups:
659 res.append(serialized_repo_group)
660
661 repos = self._get_repo_list(query, repo_group_name=repo_group_name)
662 for serialized_repo in repos:
663 res.append(serialized_repo)
664
665 if not repos and not repo_groups:
666 res.append(no_match('No matches found'))
520
667
521 return {'suggestions': res}
668 return {'suggestions': res}
522
669
@@ -564,8 +711,11 b' class HomeView(BaseAppView):'
564 def repo_group_main_page(self):
711 def repo_group_main_page(self):
565 c = self.load_default_context()
712 c = self.load_default_context()
566 c.repo_group = self.request.db_repo_group
713 c.repo_group = self.request.db_repo_group
567 repo_data, repo_group_data = self._get_groups_and_repos(
714 repo_data, repo_group_data = self._get_groups_and_repos(c.repo_group.group_id)
568 c.repo_group.group_id)
715
716 # update every 5 min
717 if self.request.db_repo_group.last_commit_cache_update_diff > 60 * 5:
718 self.request.db_repo_group.update_commit_cache()
569
719
570 # json used to render the grids
720 # json used to render the grids
571 c.repos_data = json.dumps(repo_data)
721 c.repos_data = json.dumps(repo_data)
@@ -594,6 +744,34 b' class HomeView(BaseAppView):'
594 @LoginRequired()
744 @LoginRequired()
595 @CSRFRequired()
745 @CSRFRequired()
596 @view_config(
746 @view_config(
747 route_name='file_preview', request_method='POST',
748 renderer='string', xhr=True)
749 def file_preview(self):
750 # Technically a CSRF token is not needed as no state changes with this
751 # call. However, as this is a POST is better to have it, so automated
752 # tools don't flag it as potential CSRF.
753 # Post is required because the payload could be bigger than the maximum
754 # allowed by GET.
755
756 text = self.request.POST.get('text')
757 file_path = self.request.POST.get('file_path')
758
759 renderer = h.renderer_from_filename(file_path)
760
761 if renderer:
762 return h.render(text, renderer=renderer, mentions=True)
763 else:
764 self.load_default_context()
765 _render = self.request.get_partial_renderer(
766 'rhodecode:templates/files/file_content.mako')
767
768 lines = filenode_as_lines_tokens(FileNode(file_path, text))
769
770 return _render('render_lines', lines)
771
772 @LoginRequired()
773 @CSRFRequired()
774 @view_config(
597 route_name='store_user_session_value', request_method='POST',
775 route_name='store_user_session_value', request_method='POST',
598 renderer='string', xhr=True)
776 renderer='string', xhr=True)
599 def store_user_session_attr(self):
777 def store_user_session_attr(self):
@@ -604,4 +782,4 b' class HomeView(BaseAppView):'
604 if existing_value != val:
782 if existing_value != val:
605 self.request.session[key] = val
783 self.request.session[key] = val
606
784
607 return 'stored:{}'.format(key)
785 return 'stored:{}:{}'.format(key, val)
@@ -31,12 +31,12 b' from pyramid.renderers import render'
31
31
32 from rhodecode.apps._base import BaseAppView
32 from rhodecode.apps._base import BaseAppView
33 from rhodecode.model.db import (
33 from rhodecode.model.db import (
34 or_, joinedload, UserLog, UserFollowing, User, UserApiKeys)
34 or_, joinedload, Repository, UserLog, UserFollowing, User, UserApiKeys)
35 from rhodecode.model.meta import Session
35 from rhodecode.model.meta import Session
36 import rhodecode.lib.helpers as h
36 import rhodecode.lib.helpers as h
37 from rhodecode.lib.helpers import Page
37 from rhodecode.lib.helpers import Page
38 from rhodecode.lib.user_log_filter import user_log_filter
38 from rhodecode.lib.user_log_filter import user_log_filter
39 from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
39 from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired, HasRepoPermissionAny
40 from rhodecode.lib.utils2 import safe_int, AttributeDict, md5_safe
40 from rhodecode.lib.utils2 import safe_int, AttributeDict, md5_safe
41 from rhodecode.model.scm import ScmModel
41 from rhodecode.model.scm import ScmModel
42
42
@@ -153,7 +153,7 b' class JournalView(BaseAppView):'
153 desc = action_extra()
153 desc = action_extra()
154 _url = h.route_url('home')
154 _url = h.route_url('home')
155 if entry.repository is not None:
155 if entry.repository is not None:
156 _url = h.route_url('repo_changelog',
156 _url = h.route_url('repo_commits',
157 repo_name=entry.repository.repo_name)
157 repo_name=entry.repository.repo_name)
158
158
159 feed.add_item(
159 feed.add_item(
@@ -199,7 +199,7 b' class JournalView(BaseAppView):'
199 desc = action_extra()
199 desc = action_extra()
200 _url = h.route_url('home')
200 _url = h.route_url('home')
201 if entry.repository is not None:
201 if entry.repository is not None:
202 _url = h.route_url('repo_changelog',
202 _url = h.route_url('repo_commits',
203 repo_name=entry.repository.repo_name)
203 repo_name=entry.repository.repo_name)
204
204
205 feed.add_item(
205 feed.add_item(
@@ -297,18 +297,19 b' class JournalView(BaseAppView):'
297 user_id = self.request.POST.get('follows_user_id')
297 user_id = self.request.POST.get('follows_user_id')
298 if user_id:
298 if user_id:
299 try:
299 try:
300 ScmModel().toggle_following_user(
300 ScmModel().toggle_following_user(user_id, self._rhodecode_user.user_id)
301 user_id, self._rhodecode_user.user_id)
302 Session().commit()
301 Session().commit()
303 return 'ok'
302 return 'ok'
304 except Exception:
303 except Exception:
305 raise HTTPBadRequest()
304 raise HTTPBadRequest()
306
305
307 repo_id = self.request.POST.get('follows_repo_id')
306 repo_id = self.request.POST.get('follows_repo_id')
308 if repo_id:
307 repo = Repository.get_or_404(repo_id)
308 perm_set = ['repository.read', 'repository.write', 'repository.admin']
309 has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'RepoWatch check')
310 if repo and has_perm:
309 try:
311 try:
310 ScmModel().toggle_following_repo(
312 ScmModel().toggle_following_repo(repo_id, self._rhodecode_user.user_id)
311 repo_id, self._rhodecode_user.user_id)
312 Session().commit()
313 Session().commit()
313 return 'ok'
314 return 'ok'
314 except Exception:
315 except Exception:
@@ -160,4 +160,4 b' class TestMyAccountSshKeysView(TestContr'
160
160
161 response.mustcontain('Private key')
161 response.mustcontain('Private key')
162 response.mustcontain('Public key')
162 response.mustcontain('Public key')
163 response.mustcontain('-----BEGIN RSA PRIVATE KEY-----')
163 response.mustcontain('-----BEGIN PRIVATE KEY-----')
@@ -360,7 +360,7 b' class MyAccountView(BaseAppView, DataGri'
360 'repository.read', 'repository.write', 'repository.admin'])
360 'repository.read', 'repository.write', 'repository.admin'])
361
361
362 repos_data = RepoModel().get_repos_as_dict(
362 repos_data = RepoModel().get_repos_as_dict(
363 repo_list=repo_list, admin=admin)
363 repo_list=repo_list, admin=admin, short_name=False)
364 # json used to render the grid
364 # json used to render the grid
365 return json.dumps(repos_data)
365 return json.dumps(repos_data)
366
366
@@ -423,7 +423,7 b' class MyAccountView(BaseAppView, DataGri'
423 default_redirect_url = ''
423 default_redirect_url = ''
424
424
425 # save repo
425 # save repo
426 if entry.get('bookmark_repo'):
426 if entry.get('bookmark_repo') and safe_int(entry.get('bookmark_repo')):
427 repo = Repository.get(entry['bookmark_repo'])
427 repo = Repository.get(entry['bookmark_repo'])
428 perm_check = HasRepoPermissionAny(
428 perm_check = HasRepoPermissionAny(
429 'repository.read', 'repository.write', 'repository.admin')
429 'repository.read', 'repository.write', 'repository.admin')
@@ -432,7 +432,7 b' class MyAccountView(BaseAppView, DataGri'
432 should_save = True
432 should_save = True
433 default_redirect_url = '${repo_url}'
433 default_redirect_url = '${repo_url}'
434 # save repo group
434 # save repo group
435 elif entry.get('bookmark_repo_group'):
435 elif entry.get('bookmark_repo_group') and safe_int(entry.get('bookmark_repo_group')):
436 repo_group = RepoGroup.get(entry['bookmark_repo_group'])
436 repo_group = RepoGroup.get(entry['bookmark_repo_group'])
437 perm_check = HasRepoGroupPermissionAny(
437 perm_check = HasRepoGroupPermissionAny(
438 'group.read', 'group.write', 'group.admin')
438 'group.read', 'group.write', 'group.admin')
@@ -496,6 +496,7 b' class MyAccountView(BaseAppView, DataGri'
496 if not user_bookmark:
496 if not user_bookmark:
497 raise HTTPFound(redirect_url)
497 raise HTTPFound(redirect_url)
498
498
499 # repository set
499 if user_bookmark.repository:
500 if user_bookmark.repository:
500 repo_name = user_bookmark.repository.repo_name
501 repo_name = user_bookmark.repository.repo_name
501 base_redirect_url = h.route_path(
502 base_redirect_url = h.route_path(
@@ -506,7 +507,7 b' class MyAccountView(BaseAppView, DataGri'
506 .safe_substitute({'repo_url': base_redirect_url})
507 .safe_substitute({'repo_url': base_redirect_url})
507 else:
508 else:
508 redirect_url = base_redirect_url
509 redirect_url = base_redirect_url
509
510 # repository group set
510 elif user_bookmark.repository_group:
511 elif user_bookmark.repository_group:
511 repo_group_name = user_bookmark.repository_group.group_name
512 repo_group_name = user_bookmark.repository_group.group_name
512 base_redirect_url = h.route_path(
513 base_redirect_url = h.route_path(
@@ -517,9 +518,11 b' class MyAccountView(BaseAppView, DataGri'
517 .safe_substitute({'repo_group_url': base_redirect_url})
518 .safe_substitute({'repo_group_url': base_redirect_url})
518 else:
519 else:
519 redirect_url = base_redirect_url
520 redirect_url = base_redirect_url
520
521 # custom URL set
521 elif user_bookmark.redirect_url:
522 elif user_bookmark.redirect_url:
522 redirect_url = user_bookmark.redirect_url
523 server_url = h.route_url('home').rstrip('/')
524 redirect_url = string.Template(user_bookmark.redirect_url) \
525 .safe_substitute({'server_url': server_url})
523
526
524 log.debug('Redirecting bookmark %s to %s', user_bookmark, redirect_url)
527 log.debug('Redirecting bookmark %s to %s', user_bookmark, redirect_url)
525 raise HTTPFound(redirect_url)
528 raise HTTPFound(redirect_url)
@@ -90,7 +90,7 b' def includeme(config):'
90 # Files
90 # Files
91 config.add_route(
91 config.add_route(
92 name='repo_archivefile',
92 name='repo_archivefile',
93 pattern='/{repo_name:.*?[^/]}/archive/{fname}', repo_route=True)
93 pattern='/{repo_name:.*?[^/]}/archive/{fname:.*}', repo_route=True)
94
94
95 config.add_route(
95 config.add_route(
96 name='repo_files_diff',
96 name='repo_files_diff',
@@ -172,6 +172,10 b' def includeme(config):'
172 pattern='/{repo_name:.*?[^/]}/add_file/{commit_id}/{f_path:.*}',
172 pattern='/{repo_name:.*?[^/]}/add_file/{commit_id}/{f_path:.*}',
173 repo_route=True)
173 repo_route=True)
174 config.add_route(
174 config.add_route(
175 name='repo_files_upload_file',
176 pattern='/{repo_name:.*?[^/]}/upload_file/{commit_id}/{f_path:.*}',
177 repo_route=True)
178 config.add_route(
175 name='repo_files_create_file',
179 name='repo_files_create_file',
176 pattern='/{repo_name:.*?[^/]}/create_file/{commit_id}/{f_path:.*}',
180 pattern='/{repo_name:.*?[^/]}/create_file/{commit_id}/{f_path:.*}',
177 repo_route=True)
181 repo_route=True)
@@ -189,19 +193,27 b' def includeme(config):'
189 name='repo_stats',
193 name='repo_stats',
190 pattern='/{repo_name:.*?[^/]}/repo_stats/{commit_id}', repo_route=True)
194 pattern='/{repo_name:.*?[^/]}/repo_stats/{commit_id}', repo_route=True)
191
195
192 # Changelog
196 # Commits
197 config.add_route(
198 name='repo_commits',
199 pattern='/{repo_name:.*?[^/]}/commits', repo_route=True)
200 config.add_route(
201 name='repo_commits_file',
202 pattern='/{repo_name:.*?[^/]}/commits/{commit_id}/{f_path:.*}', repo_route=True)
203 config.add_route(
204 name='repo_commits_elements',
205 pattern='/{repo_name:.*?[^/]}/commits_elements', repo_route=True)
206 config.add_route(
207 name='repo_commits_elements_file',
208 pattern='/{repo_name:.*?[^/]}/commits_elements/{commit_id}/{f_path:.*}', repo_route=True)
209
210 # Changelog (old deprecated name for commits page)
193 config.add_route(
211 config.add_route(
194 name='repo_changelog',
212 name='repo_changelog',
195 pattern='/{repo_name:.*?[^/]}/changelog', repo_route=True)
213 pattern='/{repo_name:.*?[^/]}/changelog', repo_route=True)
196 config.add_route(
214 config.add_route(
197 name='repo_changelog_file',
215 name='repo_changelog_file',
198 pattern='/{repo_name:.*?[^/]}/changelog/{commit_id}/{f_path:.*}', repo_route=True)
216 pattern='/{repo_name:.*?[^/]}/changelog/{commit_id}/{f_path:.*}', repo_route=True)
199 config.add_route(
200 name='repo_changelog_elements',
201 pattern='/{repo_name:.*?[^/]}/changelog_elements', repo_route=True)
202 config.add_route(
203 name='repo_changelog_elements_file',
204 pattern='/{repo_name:.*?[^/]}/changelog_elements/{commit_id}/{f_path:.*}', repo_route=True)
205
217
206 # Compare
218 # Compare
207 config.add_route(
219 config.add_route(
@@ -312,6 +324,11 b' def includeme(config):'
312 pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/delete',
324 pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/delete',
313 repo_route=True, repo_accepted_types=['hg', 'git'])
325 repo_route=True, repo_accepted_types=['hg', 'git'])
314
326
327 # Artifacts, (EE feature)
328 config.add_route(
329 name='repo_artifacts_list',
330 pattern='/{repo_name:.*?[^/]}/artifacts', repo_route=True)
331
315 # Settings
332 # Settings
316 config.add_route(
333 config.add_route(
317 name='edit_repo',
334 name='edit_repo',
@@ -40,11 +40,11 b' def route_path(name, params=None, **kwar'
40 class TestPullRequestList(object):
40 class TestPullRequestList(object):
41
41
42 @pytest.mark.parametrize('params, expected_title', [
42 @pytest.mark.parametrize('params, expected_title', [
43 ({'source': 0, 'closed': 1}, 'Closed Pull Requests'),
43 ({'source': 0, 'closed': 1}, 'Closed'),
44 ({'source': 0, 'my': 1}, 'opened by me'),
44 ({'source': 0, 'my': 1}, 'Opened by me'),
45 ({'source': 0, 'awaiting_review': 1}, 'awaiting review'),
45 ({'source': 0, 'awaiting_review': 1}, 'Awaiting review'),
46 ({'source': 0, 'awaiting_my_review': 1}, 'awaiting my review'),
46 ({'source': 0, 'awaiting_my_review': 1}, 'Awaiting my review'),
47 ({'source': 1}, 'Pull Requests from'),
47 ({'source': 1}, 'From this repo'),
48 ])
48 ])
49 def test_showing_list_page(self, backend, pr_util, params, expected_title):
49 def test_showing_list_page(self, backend, pr_util, params, expected_title):
50 pull_request = pr_util.create_pull_request()
50 pull_request = pr_util.create_pull_request()
@@ -55,9 +55,10 b' class TestPullRequestList(object):'
55 params=params))
55 params=params))
56
56
57 assert_response = response.assert_response()
57 assert_response = response.assert_response()
58 assert_response.element_equals_to('.panel-title', expected_title)
58
59 element = assert_response.get_element('.panel-title')
59 element = assert_response.get_element('.title .active')
60 element_text = assert_response._element_to_string(element)
60 element_text = element.text_content()
61 assert expected_title == element_text
61
62
62 def test_showing_list_page_data(self, backend, pr_util, xhr_header):
63 def test_showing_list_page_data(self, backend, pr_util, xhr_header):
63 pull_request = pr_util.create_pull_request()
64 pull_request = pr_util.create_pull_request()
@@ -33,8 +33,9 b' def route_path(name, params=None, **kwar'
33
33
34 base_url = {
34 base_url = {
35 'repo_changelog':'/{repo_name}/changelog',
35 'repo_changelog': '/{repo_name}/changelog',
36 'repo_changelog_file':'/{repo_name}/changelog/{commit_id}/{f_path}',
36 'repo_commits': '/{repo_name}/commits',
37 'repo_changelog_elements':'/{repo_name}/changelog_elements',
37 'repo_commits_file': '/{repo_name}/commits/{commit_id}/{f_path}',
38 'repo_commits_elements': '/{repo_name}/commits_elements',
38 }[name].format(**kwargs)
39 }[name].format(**kwargs)
39
40
40 if params:
41 if params:
@@ -42,8 +43,22 b' def route_path(name, params=None, **kwar'
42 return base_url
43 return base_url
43
44
44
45
46 def assert_commits_on_page(response, indexes):
47 found_indexes = [int(idx) for idx in MATCH_HASH.findall(response.body)]
48 assert found_indexes == indexes
49
50
45 class TestChangelogController(TestController):
51 class TestChangelogController(TestController):
46
52
53 def test_commits_page(self, backend):
54 self.log_user()
55 response = self.app.get(
56 route_path('repo_commits', repo_name=backend.repo_name))
57
58 first_idx = -1
59 last_idx = -DEFAULT_CHANGELOG_SIZE
60 self.assert_commit_range_on_page(response, first_idx, last_idx, backend)
61
47 def test_changelog(self, backend):
62 def test_changelog(self, backend):
48 self.log_user()
63 self.log_user()
49 response = self.app.get(
64 response = self.app.get(
@@ -62,6 +77,14 b' class TestChangelogController(TestContro'
62 params=dict(branch=backend.default_branch_name)),
77 params=dict(branch=backend.default_branch_name)),
63 status=200)
78 status=200)
64
79
80 @pytest.mark.backends("hg", "git")
81 def test_commits_filtered_by_branch(self, backend):
82 self.log_user()
83 self.app.get(
84 route_path('repo_commits', repo_name=backend.repo_name,
85 params=dict(branch=backend.default_branch_name)),
86 status=200)
87
65 @pytest.mark.backends("svn")
88 @pytest.mark.backends("svn")
66 def test_changelog_filtered_by_branch_svn(self, autologin_user, backend):
89 def test_changelog_filtered_by_branch_svn(self, autologin_user, backend):
67 repo = backend['svn-simple-layout']
90 repo = backend['svn-simple-layout']
@@ -70,27 +93,22 b' class TestChangelogController(TestContro'
70 params=dict(branch='trunk')),
93 params=dict(branch='trunk')),
71 status=200)
94 status=200)
72
95
73 self.assert_commits_on_page(
96 assert_commits_on_page(response, indexes=[15, 12, 7, 3, 2, 1])
74 response, indexes=[15, 12, 7, 3, 2, 1])
75
97
76 def test_changelog_filtered_by_wrong_branch(self, backend):
98 def test_commits_filtered_by_wrong_branch(self, backend):
77 self.log_user()
99 self.log_user()
78 branch = 'wrong-branch-name'
100 branch = 'wrong-branch-name'
79 response = self.app.get(
101 response = self.app.get(
80 route_path('repo_changelog', repo_name=backend.repo_name,
102 route_path('repo_commits', repo_name=backend.repo_name,
81 params=dict(branch=branch)),
103 params=dict(branch=branch)),
82 status=302)
104 status=302)
83 expected_url = '/{repo}/changelog/{branch}'.format(
105 expected_url = '/{repo}/commits/{branch}'.format(
84 repo=backend.repo_name, branch=branch)
106 repo=backend.repo_name, branch=branch)
85 assert expected_url in response.location
107 assert expected_url in response.location
86 response = response.follow()
108 response = response.follow()
87 expected_warning = 'Branch {} is not found.'.format(branch)
109 expected_warning = 'Branch {} is not found.'.format(branch)
88 assert expected_warning in response.body
110 assert expected_warning in response.body
89
111
90 def assert_commits_on_page(self, response, indexes):
91 found_indexes = [int(idx) for idx in MATCH_HASH.findall(response.body)]
92 assert found_indexes == indexes
93
94 @pytest.mark.xfail_backends("svn", reason="Depends on branch support")
112 @pytest.mark.xfail_backends("svn", reason="Depends on branch support")
95 def test_changelog_filtered_by_branch_with_merges(
113 def test_changelog_filtered_by_branch_with_merges(
96 self, autologin_user, backend):
114 self, autologin_user, backend):
@@ -112,21 +130,20 b' class TestChangelogController(TestContro'
112 status=200)
130 status=200)
113
131
114 @pytest.mark.backends("hg")
132 @pytest.mark.backends("hg")
115 def test_changelog_closed_branches(self, autologin_user, backend):
133 def test_commits_closed_branches(self, autologin_user, backend):
116 repo = backend['closed_branch']
134 repo = backend['closed_branch']
117 response = self.app.get(
135 response = self.app.get(
118 route_path('repo_changelog', repo_name=repo.repo_name,
136 route_path('repo_commits', repo_name=repo.repo_name,
119 params=dict(branch='experimental')),
137 params=dict(branch='experimental')),
120 status=200)
138 status=200)
121
139
122 self.assert_commits_on_page(
140 assert_commits_on_page(response, indexes=[3, 1])
123 response, indexes=[3, 1])
124
141
125 def test_changelog_pagination(self, backend):
142 def test_changelog_pagination(self, backend):
126 self.log_user()
143 self.log_user()
127 # pagination, walk up to page 6
144 # pagination, walk up to page 6
128 changelog_url = route_path(
145 changelog_url = route_path(
129 'repo_changelog', repo_name=backend.repo_name)
146 'repo_commits', repo_name=backend.repo_name)
130
147
131 for page in range(1, 7):
148 for page in range(1, 7):
132 response = self.app.get(changelog_url, {'page': page})
149 response = self.app.get(changelog_url, {'page': page})
@@ -138,22 +155,30 b' class TestChangelogController(TestContro'
138 def assert_commit_range_on_page(
155 def assert_commit_range_on_page(
139 self, response, first_idx, last_idx, backend):
156 self, response, first_idx, last_idx, backend):
140 input_template = (
157 input_template = (
141 """<input class="commit-range" id="%(raw_id)s" """
158 """<input class="commit-range" """
159 """data-commit-id="%(raw_id)s" data-commit-idx="%(idx)s" """
160 """data-short-id="%(short_id)s" id="%(raw_id)s" """
142 """name="%(raw_id)s" type="checkbox" value="1" />"""
161 """name="%(raw_id)s" type="checkbox" value="1" />"""
143 )
162 )
163
144 commit_span_template = """<span class="commit_hash">r%s:%s</span>"""
164 commit_span_template = """<span class="commit_hash">r%s:%s</span>"""
145 repo = backend.repo
165 repo = backend.repo
146
166
147 first_commit_on_page = repo.get_commit(commit_idx=first_idx)
167 first_commit_on_page = repo.get_commit(commit_idx=first_idx)
148 response.mustcontain(
168 response.mustcontain(
149 input_template % {'raw_id': first_commit_on_page.raw_id})
169 input_template % {'raw_id': first_commit_on_page.raw_id,
170 'idx': first_commit_on_page.idx,
171 'short_id': first_commit_on_page.short_id})
172
150 response.mustcontain(commit_span_template % (
173 response.mustcontain(commit_span_template % (
151 first_commit_on_page.idx, first_commit_on_page.short_id)
174 first_commit_on_page.idx, first_commit_on_page.short_id)
152 )
175 )
153
176
154 last_commit_on_page = repo.get_commit(commit_idx=last_idx)
177 last_commit_on_page = repo.get_commit(commit_idx=last_idx)
155 response.mustcontain(
178 response.mustcontain(
156 input_template % {'raw_id': last_commit_on_page.raw_id})
179 input_template % {'raw_id': last_commit_on_page.raw_id,
180 'idx': last_commit_on_page.idx,
181 'short_id': last_commit_on_page.short_id})
157 response.mustcontain(commit_span_template % (
182 response.mustcontain(commit_span_template % (
158 last_commit_on_page.idx, last_commit_on_page.short_id)
183 last_commit_on_page.idx, last_commit_on_page.short_id)
159 )
184 )
@@ -168,10 +193,10 b' class TestChangelogController(TestContro'
168 '/vcs/exceptions.py',
193 '/vcs/exceptions.py',
169 '//vcs/exceptions.py'
194 '//vcs/exceptions.py'
170 ])
195 ])
171 def test_changelog_with_filenode(self, backend, test_path):
196 def test_commits_with_filenode(self, backend, test_path):
172 self.log_user()
197 self.log_user()
173 response = self.app.get(
198 response = self.app.get(
174 route_path('repo_changelog_file', repo_name=backend.repo_name,
199 route_path('repo_commits_file', repo_name=backend.repo_name,
175 commit_id='tip', f_path=test_path),
200 commit_id='tip', f_path=test_path),
176 )
201 )
177
202
@@ -180,16 +205,16 b' class TestChangelogController(TestContro'
180 response.mustcontain('Added not implemented hg backend test case')
205 response.mustcontain('Added not implemented hg backend test case')
181 response.mustcontain('Added BaseChangeset class')
206 response.mustcontain('Added BaseChangeset class')
182
207
183 def test_changelog_with_filenode_that_is_dirnode(self, backend):
208 def test_commits_with_filenode_that_is_dirnode(self, backend):
184 self.log_user()
209 self.log_user()
185 self.app.get(
210 self.app.get(
186 route_path('repo_changelog_file', repo_name=backend.repo_name,
211 route_path('repo_commits_file', repo_name=backend.repo_name,
187 commit_id='tip', f_path='/tests'),
212 commit_id='tip', f_path='/tests'),
188 status=302)
213 status=302)
189
214
190 def test_changelog_with_filenode_not_existing(self, backend):
215 def test_commits_with_filenode_not_existing(self, backend):
191 self.log_user()
216 self.log_user()
192 self.app.get(
217 self.app.get(
193 route_path('repo_changelog_file', repo_name=backend.repo_name,
218 route_path('repo_commits_file', repo_name=backend.repo_name,
194 commit_id='tip', f_path='wrong_path'),
219 commit_id='tip', f_path='wrong_path'),
195 status=302)
220 status=302)
@@ -94,6 +94,7 b' class TestCompareView(object):'
94 origin_repo = origin.scm_instance(cache=False)
94 origin_repo = origin.scm_instance(cache=False)
95 origin_repo.config.clear_section('hooks')
95 origin_repo.config.clear_section('hooks')
96 origin_repo.pull(fork.repo_full_path, commit_ids=[commit3.raw_id])
96 origin_repo.pull(fork.repo_full_path, commit_ids=[commit3.raw_id])
97 origin_repo = origin.scm_instance(cache=False) # cache rebuild
97
98
98 # Verify test fixture setup
99 # Verify test fixture setup
99 # This does not work for git
100 # This does not work for git
@@ -162,8 +163,7 b' class TestCompareView(object):'
162 compare_page.target_source_are_disabled()
163 compare_page.target_source_are_disabled()
163
164
164 @pytest.mark.xfail_backends("svn", reason="Depends on branch support")
165 @pytest.mark.xfail_backends("svn", reason="Depends on branch support")
165 def test_compare_forks_on_branch_extra_commits_origin_has_incomming(
166 def test_compare_forks_on_branch_extra_commits_origin_has_incomming(self, backend):
166 self, backend):
167 repo1 = backend.create_repo()
167 repo1 = backend.create_repo()
168
168
169 # commit something !
169 # commit something !
@@ -21,6 +21,7 b''
21 import pytest
21 import pytest
22
22
23 from rhodecode.lib.vcs import nodes
23 from rhodecode.lib.vcs import nodes
24 from rhodecode.lib.vcs.backends.base import EmptyCommit
24 from rhodecode.tests.fixture import Fixture
25 from rhodecode.tests.fixture import Fixture
25 from rhodecode.tests.utils import commit_change
26 from rhodecode.tests.utils import commit_change
26
27
@@ -43,70 +44,7 b' def route_path(name, params=None, **kwar'
43 @pytest.mark.usefixtures("autologin_user", "app")
44 @pytest.mark.usefixtures("autologin_user", "app")
44 class TestSideBySideDiff(object):
45 class TestSideBySideDiff(object):
45
46
46 def test_diff_side_by_side(self, app, backend, backend_stub):
47 def test_diff_sidebyside_single_commit(self, app, backend):
47 f_path = 'test_sidebyside_file.py'
48 commit1_content = 'content-25d7e49c18b159446c\n'
49 commit2_content = 'content-603d6c72c46d953420\n'
50 repo = backend.create_repo()
51
52 commit1 = commit_change(
53 repo.repo_name, filename=f_path, content=commit1_content,
54 message='A', vcs_type=backend.alias, parent=None, newfile=True)
55
56 commit2 = commit_change(
57 repo.repo_name, filename=f_path, content=commit2_content,
58 message='B, child of A', vcs_type=backend.alias, parent=commit1)
59
60 response = self.app.get(route_path(
61 'repo_compare',
62 repo_name=repo.repo_name,
63 source_ref_type='rev',
64 source_ref=commit1.raw_id,
65 target_ref_type='rev',
66 target_ref=commit2.raw_id,
67 params=dict(f_path=f_path, target_repo=repo.repo_name, diffmode='sidebyside')
68 ))
69
70 response.mustcontain('Expand 1 commit')
71 response.mustcontain('1 file changed')
72
73 response.mustcontain(
74 'r%s:%s...r%s:%s' % (
75 commit1.idx, commit1.short_id, commit2.idx, commit2.short_id))
76
77 response.mustcontain('<strong>{}</strong>'.format(f_path))
78
79 def test_diff_side_by_side_with_empty_file(self, app, backend, backend_stub):
80 commits = [
81 {'message': 'First commit'},
82 {'message': 'Commit with binary',
83 'added': [nodes.FileNode('file.empty', content='')]},
84 ]
85 f_path = 'file.empty'
86 repo = backend.create_repo(commits=commits)
87 commit1 = repo.get_commit(commit_idx=0)
88 commit2 = repo.get_commit(commit_idx=1)
89
90 response = self.app.get(route_path(
91 'repo_compare',
92 repo_name=repo.repo_name,
93 source_ref_type='rev',
94 source_ref=commit1.raw_id,
95 target_ref_type='rev',
96 target_ref=commit2.raw_id,
97 params=dict(f_path=f_path, target_repo=repo.repo_name, diffmode='sidebyside')
98 ))
99
100 response.mustcontain('Expand 1 commit')
101 response.mustcontain('1 file changed')
102
103 response.mustcontain(
104 'r%s:%s...r%s:%s' % (
105 commit1.idx, commit1.short_id, commit2.idx, commit2.short_id))
106
107 response.mustcontain('<strong>{}</strong>'.format(f_path))
108
109 def test_diff_sidebyside_two_commits(self, app, backend):
110 commit_id_range = {
48 commit_id_range = {
111 'hg': {
49 'hg': {
112 'commits': ['25d7e49c18b159446cadfa506a5cf8ad1cb04067',
50 'commits': ['25d7e49c18b159446cadfa506a5cf8ad1cb04067',
@@ -141,26 +79,164 b' class TestSideBySideDiff(object):'
141 params=dict(target_repo=backend.repo_name, diffmode='sidebyside')
79 params=dict(target_repo=backend.repo_name, diffmode='sidebyside')
142 ))
80 ))
143
81
82 response.mustcontain(file_changes)
144 response.mustcontain('Expand 1 commit')
83 response.mustcontain('Expand 1 commit')
145 response.mustcontain(file_changes)
146
84
147 def test_diff_sidebyside_two_commits_single_file(self, app, backend):
85 def test_diff_sidebyside_two_commits(self, app, backend):
148 commit_id_range = {
86 commit_id_range = {
149 'hg': {
87 'hg': {
150 'commits': ['25d7e49c18b159446cadfa506a5cf8ad1cb04067',
88 'commits': ['4fdd71e9427417b2e904e0464c634fdee85ec5a7',
151 '603d6c72c46d953420c89d36372f08d9f305f5dd'],
89 '603d6c72c46d953420c89d36372f08d9f305f5dd'],
152 'changes': '1 file changed: 1 inserted, 1 deleted'
90 'changes': '32 files changed: 1165 inserted, 308 deleted'
153 },
91 },
154 'git': {
92 'git': {
155 'commits': ['6fc9270775aaf5544c1deb014f4ddd60c952fcbb',
93 'commits': ['f5fbf9cfd5f1f1be146f6d3b38bcd791a7480c13',
156 '03fa803d7e9fb14daa9a3089e0d1494eda75d986'],
94 '03fa803d7e9fb14daa9a3089e0d1494eda75d986'],
157 'changes': '1 file changed: 1 inserted, 1 deleted'
95 'changes': '32 files changed: 1165 inserted, 308 deleted'
158 },
96 },
159
97
160 'svn': {
98 'svn': {
161 'commits': ['336',
99 'commits': ['335',
162 '337'],
100 '337'],
163 'changes': '1 file changed: 1 inserted, 1 deleted'
101 'changes': '32 files changed: 1179 inserted, 310 deleted'
102 },
103 }
104
105 commit_info = commit_id_range[backend.alias]
106 commit2, commit1 = commit_info['commits']
107 file_changes = commit_info['changes']
108
109 response = self.app.get(route_path(
110 'repo_compare',
111 repo_name=backend.repo_name,
112 source_ref_type='rev',
113 source_ref=commit2,
114 target_repo=backend.repo_name,
115 target_ref_type='rev',
116 target_ref=commit1,
117 params=dict(target_repo=backend.repo_name, diffmode='sidebyside')
118 ))
119
120 response.mustcontain(file_changes)
121 response.mustcontain('Expand 2 commits')
122
123 @pytest.mark.xfail(reason='GIT does not handle empty commit compare correct (missing 1 commit)')
124 def test_diff_side_by_side_from_0_commit(self, app, backend, backend_stub):
125 f_path = 'test_sidebyside_file.py'
126 commit1_content = 'content-25d7e49c18b159446c\n'
127 commit2_content = 'content-603d6c72c46d953420\n'
128 repo = backend.create_repo()
129
130 commit1 = commit_change(
131 repo.repo_name, filename=f_path, content=commit1_content,
132 message='A', vcs_type=backend.alias, parent=None, newfile=True)
133
134 commit2 = commit_change(
135 repo.repo_name, filename=f_path, content=commit2_content,
136 message='B, child of A', vcs_type=backend.alias, parent=commit1)
137
138 response = self.app.get(route_path(
139 'repo_compare',
140 repo_name=repo.repo_name,
141 source_ref_type='rev',
142 source_ref=EmptyCommit().raw_id,
143 target_ref_type='rev',
144 target_ref=commit2.raw_id,
145 params=dict(diffmode='sidebyside')
146 ))
147
148 response.mustcontain('Expand 2 commits')
149 response.mustcontain('123 file changed')
150
151 response.mustcontain(
152 'r%s:%s...r%s:%s' % (
153 commit1.idx, commit1.short_id, commit2.idx, commit2.short_id))
154
155 response.mustcontain('<strong>{}</strong>'.format(f_path))
156
157 @pytest.mark.xfail(reason='GIT does not handle empty commit compare correct (missing 1 commit)')
158 def test_diff_side_by_side_from_0_commit_with_file_filter(self, app, backend, backend_stub):
159 f_path = 'test_sidebyside_file.py'
160 commit1_content = 'content-25d7e49c18b159446c\n'
161 commit2_content = 'content-603d6c72c46d953420\n'
162 repo = backend.create_repo()
163
164 commit1 = commit_change(
165 repo.repo_name, filename=f_path, content=commit1_content,
166 message='A', vcs_type=backend.alias, parent=None, newfile=True)
167
168 commit2 = commit_change(
169 repo.repo_name, filename=f_path, content=commit2_content,
170 message='B, child of A', vcs_type=backend.alias, parent=commit1)
171
172 response = self.app.get(route_path(
173 'repo_compare',
174 repo_name=repo.repo_name,
175 source_ref_type='rev',
176 source_ref=EmptyCommit().raw_id,
177 target_ref_type='rev',
178 target_ref=commit2.raw_id,
179 params=dict(f_path=f_path, target_repo=repo.repo_name, diffmode='sidebyside')
180 ))
181
182 response.mustcontain('Expand 2 commits')
183 response.mustcontain('1 file changed')
184
185 response.mustcontain(
186 'r%s:%s...r%s:%s' % (
187 commit1.idx, commit1.short_id, commit2.idx, commit2.short_id))
188
189 response.mustcontain('<strong>{}</strong>'.format(f_path))
190
191 def test_diff_side_by_side_with_empty_file(self, app, backend, backend_stub):
192 commits = [
193 {'message': 'First commit'},
194 {'message': 'Second commit'},
195 {'message': 'Commit with binary',
196 'added': [nodes.FileNode('file.empty', content='')]},
197 ]
198 f_path = 'file.empty'
199 repo = backend.create_repo(commits=commits)
200 commit1 = repo.get_commit(commit_idx=0)
201 commit2 = repo.get_commit(commit_idx=1)
202 commit3 = repo.get_commit(commit_idx=2)
203
204 response = self.app.get(route_path(
205 'repo_compare',
206 repo_name=repo.repo_name,
207 source_ref_type='rev',
208 source_ref=commit1.raw_id,
209 target_ref_type='rev',
210 target_ref=commit3.raw_id,
211 params=dict(f_path=f_path, target_repo=repo.repo_name, diffmode='sidebyside')
212 ))
213
214 response.mustcontain('Expand 2 commits')
215 response.mustcontain('1 file changed')
216
217 response.mustcontain(
218 'r%s:%s...r%s:%s' % (
219 commit2.idx, commit2.short_id, commit3.idx, commit3.short_id))
220
221 response.mustcontain('<strong>{}</strong>'.format(f_path))
222
223 def test_diff_sidebyside_two_commits_with_file_filter(self, app, backend):
224 commit_id_range = {
225 'hg': {
226 'commits': ['4fdd71e9427417b2e904e0464c634fdee85ec5a7',
227 '603d6c72c46d953420c89d36372f08d9f305f5dd'],
228 'changes': '1 file changed: 3 inserted, 3 deleted'
229 },
230 'git': {
231 'commits': ['f5fbf9cfd5f1f1be146f6d3b38bcd791a7480c13',
232 '03fa803d7e9fb14daa9a3089e0d1494eda75d986'],
233 'changes': '1 file changed: 3 inserted, 3 deleted'
234 },
235
236 'svn': {
237 'commits': ['335',
238 '337'],
239 'changes': '1 file changed: 3 inserted, 3 deleted'
164 },
240 },
165 }
241 }
166 f_path = 'docs/conf.py'
242 f_path = 'docs/conf.py'
@@ -179,5 +255,5 b' class TestSideBySideDiff(object):'
179 params=dict(f_path=f_path, target_repo=backend.repo_name, diffmode='sidebyside')
255 params=dict(f_path=f_path, target_repo=backend.repo_name, diffmode='sidebyside')
180 ))
256 ))
181
257
182 response.mustcontain('Expand 1 commit')
258 response.mustcontain('Expand 2 commits')
183 response.mustcontain(file_changes)
259 response.mustcontain(file_changes)
@@ -243,7 +243,7 b' class TestFilesViews(object):'
243 repo_name=backend.repo_name,
243 repo_name=backend.repo_name,
244 commit_id=commit.raw_id, f_path='vcs/nodes.py'))
244 commit_id=commit.raw_id, f_path='vcs/nodes.py'))
245
245
246 msgbox = """<div class="commit right-content">%s</div>"""
246 msgbox = """<div class="commit">%s</div>"""
247 response.mustcontain(msgbox % (commit.message, ))
247 response.mustcontain(msgbox % (commit.message, ))
248
248
249 assert_response = response.assert_response()
249 assert_response = response.assert_response()
@@ -313,6 +313,7 b' class TestFilesViews(object):'
313
313
314 expected_data = json.loads(
314 expected_data = json.loads(
315 fixture.load_resource('svn_node_history_branches.json'))
315 fixture.load_resource('svn_node_history_branches.json'))
316
316 assert expected_data == response.json
317 assert expected_data == response.json
317
318
318 def test_file_source_history_with_annotation(self, backend, xhr_header):
319 def test_file_source_history_with_annotation(self, backend, xhr_header):
@@ -521,10 +522,10 b' class TestRepositoryArchival(object):'
521 def test_archival(self, backend):
522 def test_archival(self, backend):
522 backend.enable_downloads()
523 backend.enable_downloads()
523 commit = backend.repo.get_commit(commit_idx=173)
524 commit = backend.repo.get_commit(commit_idx=173)
524 for archive, info in settings.ARCHIVE_SPECS.items():
525 for a_type, content_type, extension in settings.ARCHIVE_SPECS:
525 mime_type, arch_ext = info
526
526 short = commit.short_id + arch_ext
527 short = commit.short_id + extension
527 fname = commit.raw_id + arch_ext
528 fname = commit.raw_id + extension
528 filename = '%s-%s' % (backend.repo_name, short)
529 filename = '%s-%s' % (backend.repo_name, short)
529 response = self.app.get(
530 response = self.app.get(
530 route_path('repo_archivefile',
531 route_path('repo_archivefile',
@@ -534,7 +535,7 b' class TestRepositoryArchival(object):'
534 assert response.status == '200 OK'
535 assert response.status == '200 OK'
535 headers = [
536 headers = [
536 ('Content-Disposition', 'attachment; filename=%s' % filename),
537 ('Content-Disposition', 'attachment; filename=%s' % filename),
537 ('Content-Type', '%s' % mime_type),
538 ('Content-Type', '%s' % content_type),
538 ]
539 ]
539
540
540 for header in headers:
541 for header in headers:
@@ -761,7 +762,7 b' class TestModifyFilesWithWebInterface(ob'
761
762
762 @pytest.mark.xfail_backends("svn", reason="Depends on online editing")
763 @pytest.mark.xfail_backends("svn", reason="Depends on online editing")
763 def test_add_file_into_repo_missing_content(self, backend, csrf_token):
764 def test_add_file_into_repo_missing_content(self, backend, csrf_token):
764 repo = backend.create_repo()
765 backend.create_repo()
765 filename = 'init.py'
766 filename = 'init.py'
766 response = self.app.post(
767 response = self.app.post(
767 route_path('repo_files_create_file',
768 route_path('repo_files_create_file',
@@ -770,26 +771,25 b' class TestModifyFilesWithWebInterface(ob'
770 params={
771 params={
771 'content': "",
772 'content': "",
772 'filename': filename,
773 'filename': filename,
773 'location': "",
774 'csrf_token': csrf_token,
774 'csrf_token': csrf_token,
775 },
775 },
776 status=302)
776 status=302)
777 assert_session_flash(response,
777 expected_msg = 'Successfully committed new file `{}`'.format(os.path.join(filename))
778 'Successfully committed new file `{}`'.format(
778 assert_session_flash(response, expected_msg)
779 os.path.join(filename)))
780
779
781 def test_add_file_into_repo_missing_filename(self, backend, csrf_token):
780 def test_add_file_into_repo_missing_filename(self, backend, csrf_token):
781 commit_id = backend.repo.get_commit().raw_id
782 response = self.app.post(
782 response = self.app.post(
783 route_path('repo_files_create_file',
783 route_path('repo_files_create_file',
784 repo_name=backend.repo_name,
784 repo_name=backend.repo_name,
785 commit_id='tip', f_path='/'),
785 commit_id=commit_id, f_path='/'),
786 params={
786 params={
787 'content': "foo",
787 'content': "foo",
788 'csrf_token': csrf_token,
788 'csrf_token': csrf_token,
789 },
789 },
790 status=302)
790 status=302)
791
791
792 assert_session_flash(response, 'No filename')
792 assert_session_flash(response, 'No filename specified')
793
793
794 def test_add_file_into_repo_errors_and_no_commits(
794 def test_add_file_into_repo_errors_and_no_commits(
795 self, backend, csrf_token):
795 self, backend, csrf_token):
@@ -806,7 +806,7 b' class TestModifyFilesWithWebInterface(ob'
806 },
806 },
807 status=302)
807 status=302)
808
808
809 assert_session_flash(response, 'No filename')
809 assert_session_flash(response, 'No filename specified')
810
810
811 # Not allowed, redirect to the summary
811 # Not allowed, redirect to the summary
812 redirected = response.follow()
812 redirected = response.follow()
@@ -817,52 +817,51 b' class TestModifyFilesWithWebInterface(ob'
817
817
818 assert redirected.request.path == summary_url
818 assert redirected.request.path == summary_url
819
819
820 @pytest.mark.parametrize("location, filename", [
820 @pytest.mark.parametrize("filename, clean_filename", [
821 ('/abs', 'foo'),
821 ('/abs/foo', 'abs/foo'),
822 ('../rel', 'foo'),
822 ('../rel/foo', 'rel/foo'),
823 ('file/../foo', 'foo'),
823 ('file/../foo/foo', 'file/foo/foo'),
824 ])
824 ])
825 def test_add_file_into_repo_bad_filenames(
825 def test_add_file_into_repo_bad_filenames(self, filename, clean_filename, backend, csrf_token):
826 self, location, filename, backend, csrf_token):
826 repo = backend.create_repo()
827 commit_id = repo.get_commit().raw_id
828
827 response = self.app.post(
829 response = self.app.post(
828 route_path('repo_files_create_file',
830 route_path('repo_files_create_file',
829 repo_name=backend.repo_name,
831 repo_name=repo.repo_name,
830 commit_id='tip', f_path='/'),
832 commit_id=commit_id, f_path='/'),
831 params={
833 params={
832 'content': "foo",
834 'content': "foo",
833 'filename': filename,
835 'filename': filename,
834 'location': location,
835 'csrf_token': csrf_token,
836 'csrf_token': csrf_token,
836 },
837 },
837 status=302)
838 status=302)
838
839
839 assert_session_flash(
840 expected_msg = 'Successfully committed new file `{}`'.format(clean_filename)
840 response,
841 assert_session_flash(response, expected_msg)
841 'The location specified must be a relative path and must not '
842 'contain .. in the path')
843
842
844 @pytest.mark.parametrize("cnt, location, filename", [
843 @pytest.mark.parametrize("cnt, filename, content", [
845 (1, '', 'foo.txt'),
844 (1, 'foo.txt', "Content"),
846 (2, 'dir', 'foo.rst'),
845 (2, 'dir/foo.rst', "Content"),
847 (3, 'rel/dir', 'foo.bar'),
846 (3, 'dir/foo-second.rst', "Content"),
847 (4, 'rel/dir/foo.bar', "Content"),
848 ])
848 ])
849 def test_add_file_into_repo(self, cnt, location, filename, backend,
849 def test_add_file_into_empty_repo(self, cnt, filename, content, backend, csrf_token):
850 csrf_token):
851 repo = backend.create_repo()
850 repo = backend.create_repo()
851 commit_id = repo.get_commit().raw_id
852 response = self.app.post(
852 response = self.app.post(
853 route_path('repo_files_create_file',
853 route_path('repo_files_create_file',
854 repo_name=repo.repo_name,
854 repo_name=repo.repo_name,
855 commit_id='tip', f_path='/'),
855 commit_id=commit_id, f_path='/'),
856 params={
856 params={
857 'content': "foo",
857 'content': content,
858 'filename': filename,
858 'filename': filename,
859 'location': location,
860 'csrf_token': csrf_token,
859 'csrf_token': csrf_token,
861 },
860 },
862 status=302)
861 status=302)
863 assert_session_flash(response,
862
864 'Successfully committed new file `{}`'.format(
863 expected_msg = 'Successfully committed new file `{}`'.format(filename)
865 os.path.join(location, filename)))
864 assert_session_flash(response, expected_msg)
866
865
867 def test_edit_file_view(self, backend):
866 def test_edit_file_view(self, backend):
868 response = self.app.get(
867 response = self.app.get(
@@ -884,8 +883,7 b' class TestModifyFilesWithWebInterface(ob'
884 f_path='vcs/nodes.py'),
883 f_path='vcs/nodes.py'),
885 status=302)
884 status=302)
886 assert_session_flash(
885 assert_session_flash(
887 response,
886 response, 'Cannot modify file. Given commit `tip` is not head of a branch.')
888 'You can only edit files with commit being a valid branch')
889
887
890 def test_edit_file_view_commit_changes(self, backend, csrf_token):
888 def test_edit_file_view_commit_changes(self, backend, csrf_token):
891 repo = backend.create_repo()
889 repo = backend.create_repo()
@@ -953,8 +951,7 b' class TestModifyFilesWithWebInterface(ob'
953 f_path='vcs/nodes.py'),
951 f_path='vcs/nodes.py'),
954 status=302)
952 status=302)
955 assert_session_flash(
953 assert_session_flash(
956 response,
954 response, 'Cannot modify file. Given commit `tip` is not head of a branch.')
957 'You can only delete files with commit being a valid branch')
958
955
959 def test_delete_file_view_commit_changes(self, backend, csrf_token):
956 def test_delete_file_view_commit_changes(self, backend, csrf_token):
960 repo = backend.create_repo()
957 repo = backend.create_repo()
@@ -992,7 +989,7 b' class TestFilesViewOtherCases(object):'
992 repo_file_add_url = route_path(
989 repo_file_add_url = route_path(
993 'repo_files_add_file',
990 'repo_files_add_file',
994 repo_name=repo.repo_name,
991 repo_name=repo.repo_name,
995 commit_id=0, f_path='') + '#edit'
992 commit_id=0, f_path='')
996
993
997 assert_session_flash(
994 assert_session_flash(
998 response,
995 response,
@@ -1009,7 +1006,7 b' class TestFilesViewOtherCases(object):'
1009 repo_file_add_url = route_path(
1006 repo_file_add_url = route_path(
1010 'repo_files_add_file',
1007 'repo_files_add_file',
1011 repo_name=repo.repo_name,
1008 repo_name=repo.repo_name,
1012 commit_id=0, f_path='') + '#edit'
1009 commit_id=0, f_path='')
1013
1010
1014 response = self.app.get(
1011 response = self.app.get(
1015 route_path('repo_files',
1012 route_path('repo_files',
@@ -40,6 +40,8 b' def route_path(name, params=None, **kwar'
40 base_url = {
40 base_url = {
41 'repo_changelog': '/{repo_name}/changelog',
41 'repo_changelog': '/{repo_name}/changelog',
42 'repo_changelog_file': '/{repo_name}/changelog/{commit_id}/{f_path}',
42 'repo_changelog_file': '/{repo_name}/changelog/{commit_id}/{f_path}',
43 'repo_commits': '/{repo_name}/commits',
44 'repo_commits_file': '/{repo_name}/commits/{commit_id}/{f_path}',
43 'pullrequest_show': '/{repo_name}/pull-request/{pull_request_id}',
45 'pullrequest_show': '/{repo_name}/pull-request/{pull_request_id}',
44 'pullrequest_show_all': '/{repo_name}/pull-request',
46 'pullrequest_show_all': '/{repo_name}/pull-request',
45 'pullrequest_show_all_data': '/{repo_name}/pull-request-data',
47 'pullrequest_show_all_data': '/{repo_name}/pull-request-data',
@@ -998,11 +1000,11 b' class TestPullrequestsView(object):'
998 assert len(target_children) == 1
1000 assert len(target_children) == 1
999
1001
1000 expected_origin_link = route_path(
1002 expected_origin_link = route_path(
1001 'repo_changelog',
1003 'repo_commits',
1002 repo_name=pull_request.source_repo.scm_instance().name,
1004 repo_name=pull_request.source_repo.scm_instance().name,
1003 params=dict(branch='origin'))
1005 params=dict(branch='origin'))
1004 expected_target_link = route_path(
1006 expected_target_link = route_path(
1005 'repo_changelog',
1007 'repo_commits',
1006 repo_name=pull_request.target_repo.scm_instance().name,
1008 repo_name=pull_request.target_repo.scm_instance().name,
1007 params=dict(branch='target'))
1009 params=dict(branch='target'))
1008 assert origin_children[0].attrib['href'] == expected_origin_link
1010 assert origin_children[0].attrib['href'] == expected_origin_link
@@ -350,11 +350,11 b' class TestCreateReferenceData(object):'
350 {
350 {
351 'children': [
351 'children': [
352 {
352 {
353 'id': 'a', 'raw_id': 'a_id', 'text': 'a', 'type': 't1',
353 'id': 'a', 'idx': 0, 'raw_id': 'a_id', 'text': 'a', 'type': 't1',
354 'files_url': expected_files_url + 'a/?at=a',
354 'files_url': expected_files_url + 'a/?at=a',
355 },
355 },
356 {
356 {
357 'id': 'b', 'raw_id': 'b_id', 'text': 'b', 'type': 't1',
357 'id': 'b', 'idx': 0, 'raw_id': 'b_id', 'text': 'b', 'type': 't1',
358 'files_url': expected_files_url + 'b/?at=b',
358 'files_url': expected_files_url + 'b/?at=b',
359 }
359 }
360 ],
360 ],
@@ -363,7 +363,7 b' class TestCreateReferenceData(object):'
363 {
363 {
364 'children': [
364 'children': [
365 {
365 {
366 'id': 'c', 'raw_id': 'c_id', 'text': 'c', 'type': 't2',
366 'id': 'c', 'idx': 0, 'raw_id': 'c_id', 'text': 'c', 'type': 't2',
367 'files_url': expected_files_url + 'c/?at=c',
367 'files_url': expected_files_url + 'c/?at=c',
368 }
368 }
369 ],
369 ],
@@ -385,12 +385,12 b' class TestCreateReferenceData(object):'
385 {
385 {
386 'children': [
386 'children': [
387 {
387 {
388 'id': 'a@a_id', 'raw_id': 'a_id',
388 'id': 'a@a_id', 'idx': 0, 'raw_id': 'a_id',
389 'text': 'a', 'type': 't1',
389 'text': 'a', 'type': 't1',
390 'files_url': expected_files_url + 'a_id/a?at=a',
390 'files_url': expected_files_url + 'a_id/a?at=a',
391 },
391 },
392 {
392 {
393 'id': 'b@b_id', 'raw_id': 'b_id',
393 'id': 'b@b_id', 'idx': 0, 'raw_id': 'b_id',
394 'text': 'b', 'type': 't1',
394 'text': 'b', 'type': 't1',
395 'files_url': expected_files_url + 'b_id/b?at=b',
395 'files_url': expected_files_url + 'b_id/b?at=b',
396 }
396 }
@@ -400,7 +400,7 b' class TestCreateReferenceData(object):'
400 {
400 {
401 'children': [
401 'children': [
402 {
402 {
403 'id': 'c@c_id', 'raw_id': 'c_id',
403 'id': 'c@c_id', 'idx': 0, 'raw_id': 'c_id',
404 'text': 'c', 'type': 't2',
404 'text': 'c', 'type': 't2',
405 'files_url': expected_files_url + 'c_id/c?at=c',
405 'files_url': expected_files_url + 'c_id/c?at=c',
406 }
406 }
@@ -516,6 +516,7 b' class TestReferenceItems(object):'
516 'text': ref_name,
516 'text': ref_name,
517 'id': self._format_function(ref_name, ref_id),
517 'id': self._format_function(ref_name, ref_id),
518 'raw_id': ref_id,
518 'raw_id': ref_id,
519 'idx': 0,
519 'type': self.ref_type,
520 'type': self.ref_type,
520 'files_url': self.fake_url
521 'files_url': self.fake_url
521 }
522 }
@@ -113,7 +113,7 b' class RepoChangelogView(RepoAppView):'
113 h.flash('Branch {} is not found.'.format(h.escape(branch_name)),
113 h.flash('Branch {} is not found.'.format(h.escape(branch_name)),
114 category='warning')
114 category='warning')
115 redirect_url = h.route_path(
115 redirect_url = h.route_path(
116 'repo_changelog_file', repo_name=repo_name,
116 'repo_commits_file', repo_name=repo_name,
117 commit_id=branch_name, f_path=f_path or '')
117 commit_id=branch_name, f_path=f_path or '')
118 raise HTTPFound(redirect_url)
118 raise HTTPFound(redirect_url)
119
119
@@ -127,13 +127,13 b' class RepoChangelogView(RepoAppView):'
127 if f_path:
127 if f_path:
128 # changelog for file
128 # changelog for file
129 return h.route_path(
129 return h.route_path(
130 'repo_changelog_file',
130 'repo_commits_file',
131 repo_name=c.rhodecode_db_repo.repo_name,
131 repo_name=c.rhodecode_db_repo.repo_name,
132 commit_id=commit_id, f_path=f_path,
132 commit_id=commit_id, f_path=f_path,
133 _query=query_params)
133 _query=query_params)
134 else:
134 else:
135 return h.route_path(
135 return h.route_path(
136 'repo_changelog',
136 'repo_commits',
137 repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
137 repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
138
138
139 c.total_cs = len(collection)
139 c.total_cs = len(collection)
@@ -171,11 +171,18 b' class RepoChangelogView(RepoAppView):'
171 @HasRepoPermissionAnyDecorator(
171 @HasRepoPermissionAnyDecorator(
172 'repository.read', 'repository.write', 'repository.admin')
172 'repository.read', 'repository.write', 'repository.admin')
173 @view_config(
173 @view_config(
174 route_name='repo_commits', request_method='GET',
175 renderer='rhodecode:templates/commits/changelog.mako')
176 @view_config(
177 route_name='repo_commits_file', request_method='GET',
178 renderer='rhodecode:templates/commits/changelog.mako')
179 # old routes for backward compat
180 @view_config(
174 route_name='repo_changelog', request_method='GET',
181 route_name='repo_changelog', request_method='GET',
175 renderer='rhodecode:templates/changelog/changelog.mako')
182 renderer='rhodecode:templates/commits/changelog.mako')
176 @view_config(
183 @view_config(
177 route_name='repo_changelog_file', request_method='GET',
184 route_name='repo_changelog_file', request_method='GET',
178 renderer='rhodecode:templates/changelog/changelog.mako')
185 renderer='rhodecode:templates/commits/changelog.mako')
179 def repo_changelog(self):
186 def repo_changelog(self):
180 c = self.load_default_context()
187 c = self.load_default_context()
181
188
@@ -224,7 +231,7 b' class RepoChangelogView(RepoAppView):'
224 except RepositoryError as e:
231 except RepositoryError as e:
225 h.flash(safe_str(e), category='warning')
232 h.flash(safe_str(e), category='warning')
226 redirect_url = h.route_path(
233 redirect_url = h.route_path(
227 'repo_changelog', repo_name=self.db_repo_name)
234 'repo_commits', repo_name=self.db_repo_name)
228 raise HTTPFound(redirect_url)
235 raise HTTPFound(redirect_url)
229 collection = list(reversed(collection))
236 collection = list(reversed(collection))
230 else:
237 else:
@@ -246,14 +253,14 b' class RepoChangelogView(RepoAppView):'
246 log.exception(safe_str(e))
253 log.exception(safe_str(e))
247 h.flash(safe_str(h.escape(e)), category='error')
254 h.flash(safe_str(h.escape(e)), category='error')
248 raise HTTPFound(
255 raise HTTPFound(
249 h.route_path('repo_changelog', repo_name=self.db_repo_name))
256 h.route_path('repo_commits', repo_name=self.db_repo_name))
250
257
251 if partial_xhr or self.request.environ.get('HTTP_X_PJAX'):
258 if partial_xhr or self.request.environ.get('HTTP_X_PJAX'):
252 # case when loading dynamic file history in file view
259 # case when loading dynamic file history in file view
253 # loading from ajax, we don't want the first result, it's popped
260 # loading from ajax, we don't want the first result, it's popped
254 # in the code above
261 # in the code above
255 html = render(
262 html = render(
256 'rhodecode:templates/changelog/changelog_file_history.mako',
263 'rhodecode:templates/commits/changelog_file_history.mako',
257 self._get_template_context(c), self.request)
264 self._get_template_context(c), self.request)
258 return Response(html)
265 return Response(html)
259
266
@@ -271,14 +278,14 b' class RepoChangelogView(RepoAppView):'
271 @HasRepoPermissionAnyDecorator(
278 @HasRepoPermissionAnyDecorator(
272 'repository.read', 'repository.write', 'repository.admin')
279 'repository.read', 'repository.write', 'repository.admin')
273 @view_config(
280 @view_config(
274 route_name='repo_changelog_elements', request_method=('GET', 'POST'),
281 route_name='repo_commits_elements', request_method=('GET', 'POST'),
275 renderer='rhodecode:templates/changelog/changelog_elements.mako',
282 renderer='rhodecode:templates/commits/changelog_elements.mako',
276 xhr=True)
283 xhr=True)
277 @view_config(
284 @view_config(
278 route_name='repo_changelog_elements_file', request_method=('GET', 'POST'),
285 route_name='repo_commits_elements_file', request_method=('GET', 'POST'),
279 renderer='rhodecode:templates/changelog/changelog_elements.mako',
286 renderer='rhodecode:templates/commits/changelog_elements.mako',
280 xhr=True)
287 xhr=True)
281 def repo_changelog_elements(self):
288 def repo_commits_elements(self):
282 c = self.load_default_context()
289 c = self.load_default_context()
283 commit_id = self.request.matchdict.get('commit_id')
290 commit_id = self.request.matchdict.get('commit_id')
284 f_path = self._get_f_path(self.request.matchdict)
291 f_path = self._get_f_path(self.request.matchdict)
@@ -312,7 +319,7 b' class RepoChangelogView(RepoAppView):'
312 except (RepositoryError, CommitDoesNotExistError, Exception) as e:
319 except (RepositoryError, CommitDoesNotExistError, Exception) as e:
313 log.exception(safe_str(e))
320 log.exception(safe_str(e))
314 raise HTTPFound(
321 raise HTTPFound(
315 h.route_path('repo_changelog', repo_name=self.db_repo_name))
322 h.route_path('repo_commits', repo_name=self.db_repo_name))
316
323
317 collection = base_commit.get_path_history(
324 collection = base_commit.get_path_history(
318 f_path, limit=hist_limit, pre_load=pre_load)
325 f_path, limit=hist_limit, pre_load=pre_load)
@@ -105,10 +105,9 b' class RepoCommitsView(RepoAppView):'
105
105
106 c.commit_ranges = commits
106 c.commit_ranges = commits
107 if not c.commit_ranges:
107 if not c.commit_ranges:
108 raise RepositoryError(
108 raise RepositoryError('The commit range returned an empty result')
109 'The commit range returned an empty result')
109 except CommitDoesNotExistError as e:
110 except CommitDoesNotExistError:
110 msg = _('No such commit exists. Org exception: `{}`').format(e)
111 msg = _('No such commit exists for this repository')
112 h.flash(msg, category='error')
111 h.flash(msg, category='error')
113 raise HTTPNotFound()
112 raise HTTPNotFound()
114 except Exception:
113 except Exception:
@@ -214,16 +214,10 b' class RepoCompareView(RepoAppView):'
214 pre_load = ["author", "branch", "date", "message"]
214 pre_load = ["author", "branch", "date", "message"]
215 c.ancestor = None
215 c.ancestor = None
216
216
217 if c.file_path:
218 if source_commit == target_commit:
219 c.commit_ranges = []
220 else:
221 c.commit_ranges = [target_commit]
222 else:
223 try:
217 try:
224 c.commit_ranges = source_scm.compare(
218 c.commit_ranges = source_scm.compare(
225 source_commit.raw_id, target_commit.raw_id,
219 source_commit.raw_id, target_commit.raw_id,
226 target_scm, merge, pre_load=pre_load)
220 target_scm, merge, pre_load=pre_load) or []
227 if merge:
221 if merge:
228 c.ancestor = source_scm.get_common_ancestor(
222 c.ancestor = source_scm.get_common_ancestor(
229 source_commit.raw_id, target_commit.raw_id, target_scm)
223 source_commit.raw_id, target_commit.raw_id, target_scm)
@@ -25,6 +25,7 b' import shutil'
25 import tempfile
25 import tempfile
26 import collections
26 import collections
27 import urllib
27 import urllib
28 import pathlib2
28
29
29 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound
30 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound
30 from pyramid.view import view_config
31 from pyramid.view import view_config
@@ -42,7 +43,7 b' from rhodecode.lib.exceptions import Non'
42 from rhodecode.lib.codeblocks import (
43 from rhodecode.lib.codeblocks import (
43 filenode_as_lines_tokens, filenode_as_annotated_lines_tokens)
44 filenode_as_lines_tokens, filenode_as_annotated_lines_tokens)
44 from rhodecode.lib.utils2 import (
45 from rhodecode.lib.utils2 import (
45 convert_line_endings, detect_mode, safe_str, str2bool, safe_int)
46 convert_line_endings, detect_mode, safe_str, str2bool, safe_int, sha1, safe_unicode)
46 from rhodecode.lib.auth import (
47 from rhodecode.lib.auth import (
47 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
48 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
48 from rhodecode.lib.vcs import path as vcspath
49 from rhodecode.lib.vcs import path as vcspath
@@ -87,7 +88,7 b' class RepoFilesView(RepoAppView):'
87 c.enable_downloads = self.db_repo.enable_downloads
88 c.enable_downloads = self.db_repo.enable_downloads
88 return c
89 return c
89
90
90 def _ensure_not_locked(self):
91 def _ensure_not_locked(self, commit_id='tip'):
91 _ = self.request.translate
92 _ = self.request.translate
92
93
93 repo = self.db_repo
94 repo = self.db_repo
@@ -98,21 +99,41 b' class RepoFilesView(RepoAppView):'
98 'warning')
99 'warning')
99 files_url = h.route_path(
100 files_url = h.route_path(
100 'repo_files:default_path',
101 'repo_files:default_path',
101 repo_name=self.db_repo_name, commit_id='tip')
102 repo_name=self.db_repo_name, commit_id=commit_id)
102 raise HTTPFound(files_url)
103 raise HTTPFound(files_url)
103
104
104 def check_branch_permission(self, branch_name):
105 def forbid_non_head(self, is_head, f_path, commit_id='tip', json_mode=False):
106 _ = self.request.translate
107
108 if not is_head:
109 message = _('Cannot modify file. '
110 'Given commit `{}` is not head of a branch.').format(commit_id)
111 h.flash(message, category='warning')
112
113 if json_mode:
114 return message
115
116 files_url = h.route_path(
117 'repo_files', repo_name=self.db_repo_name, commit_id=commit_id,
118 f_path=f_path)
119 raise HTTPFound(files_url)
120
121 def check_branch_permission(self, branch_name, commit_id='tip', json_mode=False):
105 _ = self.request.translate
122 _ = self.request.translate
106
123
107 rule, branch_perm = self._rhodecode_user.get_rule_and_branch_permission(
124 rule, branch_perm = self._rhodecode_user.get_rule_and_branch_permission(
108 self.db_repo_name, branch_name)
125 self.db_repo_name, branch_name)
109 if branch_perm and branch_perm not in ['branch.push', 'branch.push_force']:
126 if branch_perm and branch_perm not in ['branch.push', 'branch.push_force']:
110 h.flash(
127 message = _('Branch `{}` changes forbidden by rule {}.').format(
111 _('Branch `{}` changes forbidden by rule {}.').format(branch_name, rule),
128 branch_name, rule)
112 'warning')
129 h.flash(message, 'warning')
130
131 if json_mode:
132 return message
133
113 files_url = h.route_path(
134 files_url = h.route_path(
114 'repo_files:default_path',
135 'repo_files:default_path', repo_name=self.db_repo_name, commit_id=commit_id)
115 repo_name=self.db_repo_name, commit_id='tip')
136
116 raise HTTPFound(files_url)
137 raise HTTPFound(files_url)
117
138
118 def _get_commit_and_path(self):
139 def _get_commit_and_path(self):
@@ -146,8 +167,7 b' class RepoFilesView(RepoAppView):'
146
167
147 _url = h.route_path(
168 _url = h.route_path(
148 'repo_files_add_file',
169 'repo_files_add_file',
149 repo_name=self.db_repo_name, commit_id=0, f_path='',
170 repo_name=self.db_repo_name, commit_id=0, f_path='')
150 _anchor='edit')
151
171
152 if h.HasRepoPermissionAny(
172 if h.HasRepoPermissionAny(
153 'repository.write', 'repository.admin')(self.db_repo_name):
173 'repository.write', 'repository.admin')(self.db_repo_name):
@@ -185,8 +205,7 b' class RepoFilesView(RepoAppView):'
185 h.flash(_('No such commit exists for this repository'), category='error')
205 h.flash(_('No such commit exists for this repository'), category='error')
186 raise HTTPNotFound()
206 raise HTTPNotFound()
187 except RepositoryError as e:
207 except RepositoryError as e:
188 log.warning('Repository error while fetching '
208 log.warning('Repository error while fetching filenode `%s`. Err:%s', path, e)
189 'filenode `%s`. Err:%s', path, e)
190 h.flash(safe_str(h.escape(e)), category='error')
209 h.flash(safe_str(h.escape(e)), category='error')
191 raise HTTPNotFound()
210 raise HTTPNotFound()
192
211
@@ -195,12 +214,7 b' class RepoFilesView(RepoAppView):'
195 def _is_valid_head(self, commit_id, repo):
214 def _is_valid_head(self, commit_id, repo):
196 branch_name = sha_commit_id = ''
215 branch_name = sha_commit_id = ''
197 is_head = False
216 is_head = False
198
217 log.debug('Checking if commit_id `%s` is a head for %s.', commit_id, repo)
199 if h.is_svn(repo) and not repo.is_empty():
200 # Note: Subversion only has one head.
201 if commit_id == repo.get_commit(commit_idx=-1).raw_id:
202 is_head = True
203 return branch_name, sha_commit_id, is_head
204
218
205 for _branch_name, branch_commit_id in repo.branches.items():
219 for _branch_name, branch_commit_id in repo.branches.items():
206 # simple case we pass in branch name, it's a HEAD
220 # simple case we pass in branch name, it's a HEAD
@@ -216,8 +230,14 b' class RepoFilesView(RepoAppView):'
216 sha_commit_id = branch_commit_id
230 sha_commit_id = branch_commit_id
217 break
231 break
218
232
233 if h.is_svn(repo) and not repo.is_empty():
234 # Note: Subversion only has one head.
235 if commit_id == repo.get_commit(commit_idx=-1).raw_id:
236 is_head = True
237 return branch_name, sha_commit_id, is_head
238
219 # checked branches, means we only need to try to get the branch/commit_sha
239 # checked branches, means we only need to try to get the branch/commit_sha
220 if not repo.is_empty:
240 if not repo.is_empty():
221 commit = repo.get_commit(commit_id=commit_id)
241 commit = repo.get_commit(commit_id=commit_id)
222 if commit:
242 if commit:
223 branch_name = commit.branch
243 branch_name = commit.branch
@@ -225,8 +245,7 b' class RepoFilesView(RepoAppView):'
225
245
226 return branch_name, sha_commit_id, is_head
246 return branch_name, sha_commit_id, is_head
227
247
228 def _get_tree_at_commit(
248 def _get_tree_at_commit(self, c, commit_id, f_path, full_load=False):
229 self, c, commit_id, f_path, full_load=False):
230
249
231 repo_id = self.db_repo.repo_id
250 repo_id = self.db_repo.repo_id
232 force_recache = self.get_recache_flag()
251 force_recache = self.get_recache_flag()
@@ -244,16 +263,16 b' class RepoFilesView(RepoAppView):'
244
263
245 @region.conditional_cache_on_arguments(namespace=cache_namespace_uid,
264 @region.conditional_cache_on_arguments(namespace=cache_namespace_uid,
246 condition=cache_on)
265 condition=cache_on)
247 def compute_file_tree(repo_id, commit_id, f_path, full_load):
266 def compute_file_tree(ver, repo_id, commit_id, f_path, full_load):
248 log.debug('Generating cached file tree for repo_id: %s, %s, %s',
267 log.debug('Generating cached file tree at ver:%s for repo_id: %s, %s, %s',
249 repo_id, commit_id, f_path)
268 ver, repo_id, commit_id, f_path)
250
269
251 c.full_load = full_load
270 c.full_load = full_load
252 return render(
271 return render(
253 'rhodecode:templates/files/files_browser_tree.mako',
272 'rhodecode:templates/files/files_browser_tree.mako',
254 self._get_template_context(c), self.request)
273 self._get_template_context(c), self.request)
255
274
256 return compute_file_tree(self.db_repo.repo_id, commit_id, f_path, full_load)
275 return compute_file_tree('v1', self.db_repo.repo_id, commit_id, f_path, full_load)
257
276
258 def _get_archive_spec(self, fname):
277 def _get_archive_spec(self, fname):
259 log.debug('Detecting archive spec for: `%s`', fname)
278 log.debug('Detecting archive spec for: `%s`', fname)
@@ -261,8 +280,7 b' class RepoFilesView(RepoAppView):'
261 fileformat = None
280 fileformat = None
262 ext = None
281 ext = None
263 content_type = None
282 content_type = None
264 for a_type, ext_data in settings.ARCHIVE_SPECS.items():
283 for a_type, content_type, extension in settings.ARCHIVE_SPECS:
265 content_type, extension = ext_data
266
284
267 if fname.endswith(extension):
285 if fname.endswith(extension):
268 fileformat = a_type
286 fileformat = a_type
@@ -278,6 +296,15 b' class RepoFilesView(RepoAppView):'
278
296
279 return commit_id, ext, fileformat, content_type
297 return commit_id, ext, fileformat, content_type
280
298
299 def create_pure_path(self, *parts):
300 # Split paths and sanitize them, removing any ../ etc
301 sanitized_path = [
302 x for x in pathlib2.PurePath(*parts).parts
303 if x not in ['.', '..']]
304
305 pure_path = pathlib2.PurePath(*sanitized_path)
306 return pure_path
307
281 @LoginRequired()
308 @LoginRequired()
282 @HasRepoPermissionAnyDecorator(
309 @HasRepoPermissionAnyDecorator(
283 'repository.read', 'repository.write', 'repository.admin')
310 'repository.read', 'repository.write', 'repository.admin')
@@ -289,9 +316,10 b' class RepoFilesView(RepoAppView):'
289 from rhodecode import CONFIG
316 from rhodecode import CONFIG
290 _ = self.request.translate
317 _ = self.request.translate
291 self.load_default_context()
318 self.load_default_context()
292
319 default_at_path = '/'
293 fname = self.request.matchdict['fname']
320 fname = self.request.matchdict['fname']
294 subrepos = self.request.GET.get('subrepos') == 'true'
321 subrepos = self.request.GET.get('subrepos') == 'true'
322 at_path = self.request.GET.get('at_path') or default_at_path
295
323
296 if not self.db_repo.enable_downloads:
324 if not self.db_repo.enable_downloads:
297 return Response(_('Downloads disabled'))
325 return Response(_('Downloads disabled'))
@@ -311,10 +339,31 b' class RepoFilesView(RepoAppView):'
311 except EmptyRepositoryError:
339 except EmptyRepositoryError:
312 return Response(_('Empty repository'))
340 return Response(_('Empty repository'))
313
341
314 archive_name = '%s-%s%s%s' % (
342 try:
315 safe_str(self.db_repo_name.replace('/', '_')),
343 at_path = commit.get_node(at_path).path or default_at_path
344 except Exception:
345 return Response(_('No node at path {} for this repository').format(at_path))
346
347 path_sha = sha1(at_path)[:8]
348
349 # original backward compat name of archive
350 clean_name = safe_str(self.db_repo_name.replace('/', '_'))
351 short_sha = safe_str(commit.short_id)
352
353 if at_path == default_at_path:
354 archive_name = '{}-{}{}{}'.format(
355 clean_name,
316 '-sub' if subrepos else '',
356 '-sub' if subrepos else '',
317 safe_str(commit.short_id), ext)
357 short_sha,
358 ext)
359 # custom path and new name
360 else:
361 archive_name = '{}-{}{}-{}{}'.format(
362 clean_name,
363 '-sub' if subrepos else '',
364 short_sha,
365 path_sha,
366 ext)
318
367
319 use_cached_archive = False
368 use_cached_archive = False
320 archive_cache_enabled = CONFIG.get(
369 archive_cache_enabled = CONFIG.get(
@@ -339,7 +388,8 b' class RepoFilesView(RepoAppView):'
339 fd, archive = tempfile.mkstemp()
388 fd, archive = tempfile.mkstemp()
340 log.debug('Creating new temp archive in %s', archive)
389 log.debug('Creating new temp archive in %s', archive)
341 try:
390 try:
342 commit.archive_repo(archive, kind=fileformat, subrepos=subrepos)
391 commit.archive_repo(archive, kind=fileformat, subrepos=subrepos,
392 archive_at_path=at_path)
343 except ImproperArchiveTypeError:
393 except ImproperArchiveTypeError:
344 return _('Unknown archive type')
394 return _('Unknown archive type')
345 if archive_cache_enabled:
395 if archive_cache_enabled:
@@ -632,8 +682,7 b' class RepoFilesView(RepoAppView):'
632 c.authors = []
682 c.authors = []
633 # this loads a simple tree without metadata to speed things up
683 # this loads a simple tree without metadata to speed things up
634 # later via ajax we call repo_nodetree_full and fetch whole
684 # later via ajax we call repo_nodetree_full and fetch whole
635 c.file_tree = self._get_tree_at_commit(
685 c.file_tree = self._get_tree_at_commit(c, c.commit.raw_id, f_path)
636 c, c.commit.raw_id, f_path)
637
686
638 except RepositoryError as e:
687 except RepositoryError as e:
639 h.flash(safe_str(h.escape(e)), category='error')
688 h.flash(safe_str(h.escape(e)), category='error')
@@ -875,18 +924,17 b' class RepoFilesView(RepoAppView):'
875 self.db_repo_name, self.db_repo.repo_id, commit.raw_id, f_path)
924 self.db_repo_name, self.db_repo.repo_id, commit.raw_id, f_path)
876 return {'nodes': metadata}
925 return {'nodes': metadata}
877
926
878 def _create_references(
927 def _create_references(self, branches_or_tags, symbolic_reference, f_path, ref_type):
879 self, branches_or_tags, symbolic_reference, f_path):
880 items = []
928 items = []
881 for name, commit_id in branches_or_tags.items():
929 for name, commit_id in branches_or_tags.items():
882 sym_ref = symbolic_reference(commit_id, name, f_path)
930 sym_ref = symbolic_reference(commit_id, name, f_path, ref_type)
883 items.append((sym_ref, name))
931 items.append((sym_ref, name, ref_type))
884 return items
932 return items
885
933
886 def _symbolic_reference(self, commit_id, name, f_path):
934 def _symbolic_reference(self, commit_id, name, f_path, ref_type):
887 return commit_id
935 return commit_id
888
936
889 def _symbolic_reference_svn(self, commit_id, name, f_path):
937 def _symbolic_reference_svn(self, commit_id, name, f_path, ref_type):
890 new_f_path = vcspath.join(name, f_path)
938 new_f_path = vcspath.join(name, f_path)
891 return u'%s@%s' % (new_f_path, commit_id)
939 return u'%s@%s' % (new_f_path, commit_id)
892
940
@@ -916,7 +964,7 b' class RepoFilesView(RepoAppView):'
916 for commit in commits:
964 for commit in commits:
917 branch = ' (%s)' % commit.branch if commit.branch else ''
965 branch = ' (%s)' % commit.branch if commit.branch else ''
918 n_desc = 'r%s:%s%s' % (commit.idx, commit.short_id, branch)
966 n_desc = 'r%s:%s%s' % (commit.idx, commit.short_id, branch)
919 commits_group[0].append((commit.raw_id, n_desc,))
967 commits_group[0].append((commit.raw_id, n_desc, 'sha'))
920 history.append(commits_group)
968 history.append(commits_group)
921
969
922 symbolic_reference = self._symbolic_reference
970 symbolic_reference = self._symbolic_reference
@@ -932,11 +980,11 b' class RepoFilesView(RepoAppView):'
932 symbolic_reference = self._symbolic_reference_svn
980 symbolic_reference = self._symbolic_reference_svn
933
981
934 branches = self._create_references(
982 branches = self._create_references(
935 self.rhodecode_vcs_repo.branches, symbolic_reference, f_path)
983 self.rhodecode_vcs_repo.branches, symbolic_reference, f_path, 'branch')
936 branches_group = (branches, _("Branches"))
984 branches_group = (branches, _("Branches"))
937
985
938 tags = self._create_references(
986 tags = self._create_references(
939 self.rhodecode_vcs_repo.tags, symbolic_reference, f_path)
987 self.rhodecode_vcs_repo.tags, symbolic_reference, f_path, 'tag')
940 tags_group = (tags, _("Tags"))
988 tags_group = (tags, _("Tags"))
941
989
942 history.append(branches_group)
990 history.append(branches_group)
@@ -964,7 +1012,7 b' class RepoFilesView(RepoAppView):'
964 for obj in file_history:
1012 for obj in file_history:
965 res.append({
1013 res.append({
966 'text': obj[1],
1014 'text': obj[1],
967 'children': [{'id': o[0], 'text': o[1]} for o in obj[0]]
1015 'children': [{'id': o[0], 'text': o[1], 'type': o[2]} for o in obj[0]]
968 })
1016 })
969
1017
970 data = {
1018 data = {
@@ -1035,15 +1083,9 b' class RepoFilesView(RepoAppView):'
1035 _branch_name, _sha_commit_id, is_head = \
1083 _branch_name, _sha_commit_id, is_head = \
1036 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1084 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1037
1085
1038 if not is_head:
1086 self.forbid_non_head(is_head, f_path)
1039 h.flash(_('You can only delete files with commit '
1087 self.check_branch_permission(_branch_name)
1040 'being a valid branch head.'), category='warning')
1041 raise HTTPFound(
1042 h.route_path('repo_files',
1043 repo_name=self.db_repo_name, commit_id='tip',
1044 f_path=f_path))
1045
1088
1046 self.check_branch_permission(_branch_name)
1047 c.commit = self._get_commit_or_redirect(commit_id)
1089 c.commit = self._get_commit_or_redirect(commit_id)
1048 c.file = self._get_filenode_or_redirect(c.commit, f_path)
1090 c.file = self._get_filenode_or_redirect(c.commit, f_path)
1049
1091
@@ -1069,13 +1111,7 b' class RepoFilesView(RepoAppView):'
1069 _branch_name, _sha_commit_id, is_head = \
1111 _branch_name, _sha_commit_id, is_head = \
1070 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1112 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1071
1113
1072 if not is_head:
1114 self.forbid_non_head(is_head, f_path)
1073 h.flash(_('You can only delete files with commit '
1074 'being a valid branch head.'), category='warning')
1075 raise HTTPFound(
1076 h.route_path('repo_files',
1077 repo_name=self.db_repo_name, commit_id='tip',
1078 f_path=f_path))
1079 self.check_branch_permission(_branch_name)
1115 self.check_branch_permission(_branch_name)
1080
1116
1081 c.commit = self._get_commit_or_redirect(commit_id)
1117 c.commit = self._get_commit_or_redirect(commit_id)
@@ -1125,14 +1161,8 b' class RepoFilesView(RepoAppView):'
1125 _branch_name, _sha_commit_id, is_head = \
1161 _branch_name, _sha_commit_id, is_head = \
1126 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1162 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1127
1163
1128 if not is_head:
1164 self.forbid_non_head(is_head, f_path, commit_id=commit_id)
1129 h.flash(_('You can only edit files with commit '
1165 self.check_branch_permission(_branch_name, commit_id=commit_id)
1130 'being a valid branch head.'), category='warning')
1131 raise HTTPFound(
1132 h.route_path('repo_files',
1133 repo_name=self.db_repo_name, commit_id='tip',
1134 f_path=f_path))
1135 self.check_branch_permission(_branch_name)
1136
1166
1137 c.commit = self._get_commit_or_redirect(commit_id)
1167 c.commit = self._get_commit_or_redirect(commit_id)
1138 c.file = self._get_filenode_or_redirect(c.commit, f_path)
1168 c.file = self._get_filenode_or_redirect(c.commit, f_path)
@@ -1144,8 +1174,7 b' class RepoFilesView(RepoAppView):'
1144 commit_id=c.commit.raw_id, f_path=f_path)
1174 commit_id=c.commit.raw_id, f_path=f_path)
1145 raise HTTPFound(files_url)
1175 raise HTTPFound(files_url)
1146
1176
1147 c.default_message = _(
1177 c.default_message = _('Edited file {} via RhodeCode Enterprise').format(f_path)
1148 'Edited file {} via RhodeCode Enterprise').format(f_path)
1149 c.f_path = f_path
1178 c.f_path = f_path
1150
1179
1151 return self._get_template_context(c)
1180 return self._get_template_context(c)
@@ -1162,32 +1191,23 b' class RepoFilesView(RepoAppView):'
1162 commit_id, f_path = self._get_commit_and_path()
1191 commit_id, f_path = self._get_commit_and_path()
1163
1192
1164 self._ensure_not_locked()
1193 self._ensure_not_locked()
1165 _branch_name, _sha_commit_id, is_head = \
1166 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1167
1168 if not is_head:
1169 h.flash(_('You can only edit files with commit '
1170 'being a valid branch head.'), category='warning')
1171 raise HTTPFound(
1172 h.route_path('repo_files',
1173 repo_name=self.db_repo_name, commit_id='tip',
1174 f_path=f_path))
1175
1176 self.check_branch_permission(_branch_name)
1177
1194
1178 c.commit = self._get_commit_or_redirect(commit_id)
1195 c.commit = self._get_commit_or_redirect(commit_id)
1179 c.file = self._get_filenode_or_redirect(c.commit, f_path)
1196 c.file = self._get_filenode_or_redirect(c.commit, f_path)
1180
1197
1181 if c.file.is_binary:
1198 if c.file.is_binary:
1182 raise HTTPFound(
1199 raise HTTPFound(h.route_path('repo_files', repo_name=self.db_repo_name,
1183 h.route_path('repo_files',
1200 commit_id=c.commit.raw_id, f_path=f_path))
1184 repo_name=self.db_repo_name,
1201
1185 commit_id=c.commit.raw_id,
1202 _branch_name, _sha_commit_id, is_head = \
1186 f_path=f_path))
1203 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1187
1204
1188 c.default_message = _(
1205 self.forbid_non_head(is_head, f_path, commit_id=commit_id)
1189 'Edited file {} via RhodeCode Enterprise').format(f_path)
1206 self.check_branch_permission(_branch_name, commit_id=commit_id)
1207
1208 c.default_message = _('Edited file {} via RhodeCode Enterprise').format(f_path)
1190 c.f_path = f_path
1209 c.f_path = f_path
1210
1191 old_content = c.file.content
1211 old_content = c.file.content
1192 sl = old_content.splitlines(1)
1212 sl = old_content.splitlines(1)
1193 first_line = sl[0] if sl else ''
1213 first_line = sl[0] if sl else ''
@@ -1198,20 +1218,25 b' class RepoFilesView(RepoAppView):'
1198 content = convert_line_endings(r_post.get('content', ''), line_ending_mode)
1218 content = convert_line_endings(r_post.get('content', ''), line_ending_mode)
1199
1219
1200 message = r_post.get('message') or c.default_message
1220 message = r_post.get('message') or c.default_message
1201 org_f_path = c.file.unicode_path
1221 org_node_path = c.file.unicode_path
1202 filename = r_post['filename']
1222 filename = r_post['filename']
1203 org_filename = c.file.name
1223
1224 root_path = c.file.dir_path
1225 pure_path = self.create_pure_path(root_path, filename)
1226 node_path = safe_unicode(bytes(pure_path))
1204
1227
1205 if content == old_content and filename == org_filename:
1228 default_redirect_url = h.route_path('repo_commit', repo_name=self.db_repo_name,
1206 h.flash(_('No changes'), category='warning')
1229 commit_id=commit_id)
1207 raise HTTPFound(
1230 if content == old_content and node_path == org_node_path:
1208 h.route_path('repo_commit', repo_name=self.db_repo_name,
1231 h.flash(_('No changes detected on {}').format(org_node_path),
1209 commit_id='tip'))
1232 category='warning')
1233 raise HTTPFound(default_redirect_url)
1234
1210 try:
1235 try:
1211 mapping = {
1236 mapping = {
1212 org_f_path: {
1237 org_node_path: {
1213 'org_filename': org_f_path,
1238 'org_filename': org_node_path,
1214 'filename': os.path.join(c.file.dir_path, filename),
1239 'filename': node_path,
1215 'content': content,
1240 'content': content,
1216 'lexer': '',
1241 'lexer': '',
1217 'op': 'mod',
1242 'op': 'mod',
@@ -1219,7 +1244,7 b' class RepoFilesView(RepoAppView):'
1219 }
1244 }
1220 }
1245 }
1221
1246
1222 ScmModel().update_nodes(
1247 commit = ScmModel().update_nodes(
1223 user=self._rhodecode_db_user.user_id,
1248 user=self._rhodecode_db_user.user_id,
1224 repo=self.db_repo,
1249 repo=self.db_repo,
1225 message=message,
1250 message=message,
@@ -1227,21 +1252,25 b' class RepoFilesView(RepoAppView):'
1227 parent_commit=c.commit,
1252 parent_commit=c.commit,
1228 )
1253 )
1229
1254
1230 h.flash(
1255 h.flash(_('Successfully committed changes to file `{}`').format(
1231 _('Successfully committed changes to file `{}`').format(
1232 h.escape(f_path)), category='success')
1256 h.escape(f_path)), category='success')
1257 default_redirect_url = h.route_path(
1258 'repo_commit', repo_name=self.db_repo_name, commit_id=commit.raw_id)
1259
1233 except Exception:
1260 except Exception:
1234 log.exception('Error occurred during commit')
1261 log.exception('Error occurred during commit')
1235 h.flash(_('Error occurred during commit'), category='error')
1262 h.flash(_('Error occurred during commit'), category='error')
1236 raise HTTPFound(
1263
1237 h.route_path('repo_commit', repo_name=self.db_repo_name,
1264 raise HTTPFound(default_redirect_url)
1238 commit_id='tip'))
1239
1265
1240 @LoginRequired()
1266 @LoginRequired()
1241 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
1267 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
1242 @view_config(
1268 @view_config(
1243 route_name='repo_files_add_file', request_method='GET',
1269 route_name='repo_files_add_file', request_method='GET',
1244 renderer='rhodecode:templates/files/files_add.mako')
1270 renderer='rhodecode:templates/files/files_add.mako')
1271 @view_config(
1272 route_name='repo_files_upload_file', request_method='GET',
1273 renderer='rhodecode:templates/files/files_upload.mako')
1245 def repo_files_add_file(self):
1274 def repo_files_add_file(self):
1246 _ = self.request.translate
1275 _ = self.request.translate
1247 c = self.load_default_context()
1276 c = self.load_default_context()
@@ -1252,27 +1281,20 b' class RepoFilesView(RepoAppView):'
1252 c.commit = self._get_commit_or_redirect(commit_id, redirect_after=False)
1281 c.commit = self._get_commit_or_redirect(commit_id, redirect_after=False)
1253 if c.commit is None:
1282 if c.commit is None:
1254 c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias)
1283 c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias)
1255 c.default_message = (_('Added file via RhodeCode Enterprise'))
1256 c.f_path = f_path.lstrip('/') # ensure not relative path
1257
1284
1258 if self.rhodecode_vcs_repo.is_empty:
1285 if self.rhodecode_vcs_repo.is_empty():
1259 # for empty repository we cannot check for current branch, we rely on
1286 # for empty repository we cannot check for current branch, we rely on
1260 # c.commit.branch instead
1287 # c.commit.branch instead
1261 _branch_name = c.commit.branch
1288 _branch_name, _sha_commit_id, is_head = c.commit.branch, '', True
1262 is_head = True
1263 else:
1289 else:
1264 _branch_name, _sha_commit_id, is_head = \
1290 _branch_name, _sha_commit_id, is_head = \
1265 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1291 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1266
1292
1267 if not is_head:
1293 self.forbid_non_head(is_head, f_path, commit_id=commit_id)
1268 h.flash(_('You can only add files with commit '
1294 self.check_branch_permission(_branch_name, commit_id=commit_id)
1269 'being a valid branch head.'), category='warning')
1270 raise HTTPFound(
1271 h.route_path('repo_files',
1272 repo_name=self.db_repo_name, commit_id='tip',
1273 f_path=f_path))
1274
1295
1275 self.check_branch_permission(_branch_name)
1296 c.default_message = (_('Added file via RhodeCode Enterprise'))
1297 c.f_path = f_path.lstrip('/') # ensure not relative path
1276
1298
1277 return self._get_template_context(c)
1299 return self._get_template_context(c)
1278
1300
@@ -1289,86 +1311,62 b' class RepoFilesView(RepoAppView):'
1289
1311
1290 self._ensure_not_locked()
1312 self._ensure_not_locked()
1291
1313
1292 r_post = self.request.POST
1314 c.commit = self._get_commit_or_redirect(commit_id, redirect_after=False)
1293
1294 c.commit = self._get_commit_or_redirect(
1295 commit_id, redirect_after=False)
1296 if c.commit is None:
1315 if c.commit is None:
1297 c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias)
1316 c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias)
1298
1317
1299 if self.rhodecode_vcs_repo.is_empty:
1318 # calculate redirect URL
1300 # for empty repository we cannot check for current branch, we rely on
1319 if self.rhodecode_vcs_repo.is_empty():
1301 # c.commit.branch instead
1302 _branch_name = c.commit.branch
1303 is_head = True
1304 else:
1305 _branch_name, _sha_commit_id, is_head = \
1306 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1307
1308 if not is_head:
1309 h.flash(_('You can only add files with commit '
1310 'being a valid branch head.'), category='warning')
1311 raise HTTPFound(
1312 h.route_path('repo_files',
1313 repo_name=self.db_repo_name, commit_id='tip',
1314 f_path=f_path))
1315
1316 self.check_branch_permission(_branch_name)
1317
1318 c.default_message = (_('Added file via RhodeCode Enterprise'))
1319 c.f_path = f_path
1320 unix_mode = 0
1321 content = convert_line_endings(r_post.get('content', ''), unix_mode)
1322
1323 message = r_post.get('message') or c.default_message
1324 filename = r_post.get('filename')
1325 location = r_post.get('location', '') # dir location
1326 file_obj = r_post.get('upload_file', None)
1327
1328 if file_obj is not None and hasattr(file_obj, 'filename'):
1329 filename = r_post.get('filename_upload')
1330 content = file_obj.file
1331
1332 if hasattr(content, 'file'):
1333 # non posix systems store real file under file attr
1334 content = content.file
1335
1336 if self.rhodecode_vcs_repo.is_empty:
1337 default_redirect_url = h.route_path(
1320 default_redirect_url = h.route_path(
1338 'repo_summary', repo_name=self.db_repo_name)
1321 'repo_summary', repo_name=self.db_repo_name)
1339 else:
1322 else:
1340 default_redirect_url = h.route_path(
1323 default_redirect_url = h.route_path(
1341 'repo_commit', repo_name=self.db_repo_name, commit_id='tip')
1324 'repo_commit', repo_name=self.db_repo_name, commit_id='tip')
1342
1325
1326 if self.rhodecode_vcs_repo.is_empty():
1327 # for empty repository we cannot check for current branch, we rely on
1328 # c.commit.branch instead
1329 _branch_name, _sha_commit_id, is_head = c.commit.branch, '', True
1330 else:
1331 _branch_name, _sha_commit_id, is_head = \
1332 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1333
1334 self.forbid_non_head(is_head, f_path, commit_id=commit_id)
1335 self.check_branch_permission(_branch_name, commit_id=commit_id)
1336
1337 c.default_message = (_('Added file via RhodeCode Enterprise'))
1338 c.f_path = f_path
1339
1340 r_post = self.request.POST
1341 message = r_post.get('message') or c.default_message
1342 filename = r_post.get('filename')
1343 unix_mode = 0
1344 content = convert_line_endings(r_post.get('content', ''), unix_mode)
1345
1346 if not filename:
1343 # If there's no commit, redirect to repo summary
1347 # If there's no commit, redirect to repo summary
1344 if type(c.commit) is EmptyCommit:
1348 if type(c.commit) is EmptyCommit:
1345 redirect_url = h.route_path(
1349 redirect_url = h.route_path(
1346 'repo_summary', repo_name=self.db_repo_name)
1350 'repo_summary', repo_name=self.db_repo_name)
1347 else:
1351 else:
1348 redirect_url = default_redirect_url
1352 redirect_url = default_redirect_url
1349
1353 h.flash(_('No filename specified'), category='warning')
1350 if not filename:
1351 h.flash(_('No filename'), category='warning')
1352 raise HTTPFound(redirect_url)
1354 raise HTTPFound(redirect_url)
1353
1355
1354 # extract the location from filename,
1356 root_path = f_path
1355 # allows using foo/bar.txt syntax to create subdirectories
1357 pure_path = self.create_pure_path(root_path, filename)
1356 subdir_loc = filename.rsplit('/', 1)
1358 node_path = safe_unicode(bytes(pure_path).lstrip('/'))
1357 if len(subdir_loc) == 2:
1358 location = os.path.join(location, subdir_loc[0])
1359
1359
1360 # strip all crap out of file, just leave the basename
1361 filename = os.path.basename(filename)
1362 node_path = os.path.join(location, filename)
1363 author = self._rhodecode_db_user.full_contact
1360 author = self._rhodecode_db_user.full_contact
1364
1365 try:
1366 nodes = {
1361 nodes = {
1367 node_path: {
1362 node_path: {
1368 'content': content
1363 'content': content
1369 }
1364 }
1370 }
1365 }
1371 ScmModel().create_nodes(
1366
1367 try:
1368
1369 commit = ScmModel().create_nodes(
1372 user=self._rhodecode_db_user.user_id,
1370 user=self._rhodecode_db_user.user_id,
1373 repo=self.db_repo,
1371 repo=self.db_repo,
1374 message=message,
1372 message=message,
@@ -1377,13 +1375,15 b' class RepoFilesView(RepoAppView):'
1377 author=author,
1375 author=author,
1378 )
1376 )
1379
1377
1380 h.flash(
1378 h.flash(_('Successfully committed new file `{}`').format(
1381 _('Successfully committed new file `{}`').format(
1382 h.escape(node_path)), category='success')
1379 h.escape(node_path)), category='success')
1380
1381 default_redirect_url = h.route_path(
1382 'repo_commit', repo_name=self.db_repo_name, commit_id=commit.raw_id)
1383
1383 except NonRelativePathError:
1384 except NonRelativePathError:
1384 log.exception('Non Relative path found')
1385 log.exception('Non Relative path found')
1385 h.flash(_(
1386 h.flash(_('The location specified must be a relative path and must not '
1386 'The location specified must be a relative path and must not '
1387 'contain .. in the path'), category='warning')
1387 'contain .. in the path'), category='warning')
1388 raise HTTPFound(default_redirect_url)
1388 raise HTTPFound(default_redirect_url)
1389 except (NodeError, NodeAlreadyExistsError) as e:
1389 except (NodeError, NodeAlreadyExistsError) as e:
@@ -1393,3 +1393,134 b' class RepoFilesView(RepoAppView):'
1393 h.flash(_('Error occurred during commit'), category='error')
1393 h.flash(_('Error occurred during commit'), category='error')
1394
1394
1395 raise HTTPFound(default_redirect_url)
1395 raise HTTPFound(default_redirect_url)
1396
1397 @LoginRequired()
1398 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
1399 @CSRFRequired()
1400 @view_config(
1401 route_name='repo_files_upload_file', request_method='POST',
1402 renderer='json_ext')
1403 def repo_files_upload_file(self):
1404 _ = self.request.translate
1405 c = self.load_default_context()
1406 commit_id, f_path = self._get_commit_and_path()
1407
1408 self._ensure_not_locked()
1409
1410 c.commit = self._get_commit_or_redirect(commit_id, redirect_after=False)
1411 if c.commit is None:
1412 c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias)
1413
1414 # calculate redirect URL
1415 if self.rhodecode_vcs_repo.is_empty():
1416 default_redirect_url = h.route_path(
1417 'repo_summary', repo_name=self.db_repo_name)
1418 else:
1419 default_redirect_url = h.route_path(
1420 'repo_commit', repo_name=self.db_repo_name, commit_id='tip')
1421
1422 if self.rhodecode_vcs_repo.is_empty():
1423 # for empty repository we cannot check for current branch, we rely on
1424 # c.commit.branch instead
1425 _branch_name, _sha_commit_id, is_head = c.commit.branch, '', True
1426 else:
1427 _branch_name, _sha_commit_id, is_head = \
1428 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1429
1430 error = self.forbid_non_head(is_head, f_path, json_mode=True)
1431 if error:
1432 return {
1433 'error': error,
1434 'redirect_url': default_redirect_url
1435 }
1436 error = self.check_branch_permission(_branch_name, json_mode=True)
1437 if error:
1438 return {
1439 'error': error,
1440 'redirect_url': default_redirect_url
1441 }
1442
1443 c.default_message = (_('Uploaded file via RhodeCode Enterprise'))
1444 c.f_path = f_path
1445
1446 r_post = self.request.POST
1447
1448 message = c.default_message
1449 user_message = r_post.getall('message')
1450 if isinstance(user_message, list) and user_message:
1451 # we take the first from duplicated results if it's not empty
1452 message = user_message[0] if user_message[0] else message
1453
1454 nodes = {}
1455
1456 for file_obj in r_post.getall('files_upload') or []:
1457 content = file_obj.file
1458 filename = file_obj.filename
1459
1460 root_path = f_path
1461 pure_path = self.create_pure_path(root_path, filename)
1462 node_path = safe_unicode(bytes(pure_path).lstrip('/'))
1463
1464 nodes[node_path] = {
1465 'content': content
1466 }
1467
1468 if not nodes:
1469 error = 'missing files'
1470 return {
1471 'error': error,
1472 'redirect_url': default_redirect_url
1473 }
1474
1475 author = self._rhodecode_db_user.full_contact
1476
1477 try:
1478 commit = ScmModel().create_nodes(
1479 user=self._rhodecode_db_user.user_id,
1480 repo=self.db_repo,
1481 message=message,
1482 nodes=nodes,
1483 parent_commit=c.commit,
1484 author=author,
1485 )
1486 if len(nodes) == 1:
1487 flash_message = _('Successfully committed {} new files').format(len(nodes))
1488 else:
1489 flash_message = _('Successfully committed 1 new file')
1490
1491 h.flash(flash_message, category='success')
1492
1493 default_redirect_url = h.route_path(
1494 'repo_commit', repo_name=self.db_repo_name, commit_id=commit.raw_id)
1495
1496 except NonRelativePathError:
1497 log.exception('Non Relative path found')
1498 error = _('The location specified must be a relative path and must not '
1499 'contain .. in the path')
1500 h.flash(error, category='warning')
1501
1502 return {
1503 'error': error,
1504 'redirect_url': default_redirect_url
1505 }
1506 except (NodeError, NodeAlreadyExistsError) as e:
1507 error = h.escape(e)
1508 h.flash(error, category='error')
1509
1510 return {
1511 'error': error,
1512 'redirect_url': default_redirect_url
1513 }
1514 except Exception:
1515 log.exception('Error occurred during commit')
1516 error = _('Error occurred during commit')
1517 h.flash(error, category='error')
1518 return {
1519 'error': error,
1520 'redirect_url': default_redirect_url
1521 }
1522
1523 return {
1524 'error': None,
1525 'redirect_url': default_redirect_url
1526 }
@@ -72,6 +72,7 b' class RepoSummaryView(RepoAppView):'
72 log.debug("Searching for a README file.")
72 log.debug("Searching for a README file.")
73 readme_node = ReadmeFinder(_renderer_type).search(commit)
73 readme_node = ReadmeFinder(_renderer_type).search(commit)
74 if readme_node:
74 if readme_node:
75 log.debug('Found README node: %s', readme_node)
75 relative_urls = {
76 relative_urls = {
76 'raw': h.route_path(
77 'raw': h.route_path(
77 'repo_file_raw', repo_name=_repo_name,
78 'repo_file_raw', repo_name=_repo_name,
@@ -82,7 +83,8 b' class RepoSummaryView(RepoAppView):'
82 }
83 }
83 readme_data = self._render_readme_or_none(
84 readme_data = self._render_readme_or_none(
84 commit, readme_node, relative_urls)
85 commit, readme_node, relative_urls)
85 readme_filename = readme_node.path
86 readme_filename = readme_node.unicode_path
87
86 return readme_data, readme_filename
88 return readme_data, readme_filename
87
89
88 inv_context_manager = rc_cache.InvalidationContext(
90 inv_context_manager = rc_cache.InvalidationContext(
@@ -152,6 +154,26 b' class RepoSummaryView(RepoAppView):'
152 c.comments = self.db_repo.get_comments(page_ids)
154 c.comments = self.db_repo.get_comments(page_ids)
153 c.statuses = self.db_repo.statuses(page_ids)
155 c.statuses = self.db_repo.statuses(page_ids)
154
156
157 def _prepare_and_set_clone_url(self, c):
158 username = ''
159 if self._rhodecode_user.username != User.DEFAULT_USER:
160 username = safe_str(self._rhodecode_user.username)
161
162 _def_clone_uri = _def_clone_uri_id = c.clone_uri_tmpl
163 _def_clone_uri_ssh = c.clone_uri_ssh_tmpl
164
165 if '{repo}' in _def_clone_uri:
166 _def_clone_uri_id = _def_clone_uri.replace('{repo}', '_{repoid}')
167 elif '{repoid}' in _def_clone_uri:
168 _def_clone_uri_id = _def_clone_uri.replace('_{repoid}', '{repo}')
169
170 c.clone_repo_url = self.db_repo.clone_url(
171 user=username, uri_tmpl=_def_clone_uri)
172 c.clone_repo_url_id = self.db_repo.clone_url(
173 user=username, uri_tmpl=_def_clone_uri_id)
174 c.clone_repo_url_ssh = self.db_repo.clone_url(
175 uri_tmpl=_def_clone_uri_ssh, ssh=True)
176
155 @LoginRequired()
177 @LoginRequired()
156 @HasRepoPermissionAnyDecorator(
178 @HasRepoPermissionAnyDecorator(
157 'repository.read', 'repository.write', 'repository.admin')
179 'repository.read', 'repository.write', 'repository.admin')
@@ -160,6 +182,7 b' class RepoSummaryView(RepoAppView):'
160 renderer='rhodecode:templates/summary/summary_commits.mako')
182 renderer='rhodecode:templates/summary/summary_commits.mako')
161 def summary_commits(self):
183 def summary_commits(self):
162 c = self.load_default_context()
184 c = self.load_default_context()
185 self._prepare_and_set_clone_url(c)
163 self._load_commits_context(c)
186 self._load_commits_context(c)
164 return self._get_template_context(c)
187 return self._get_template_context(c)
165
188
@@ -179,26 +202,11 b' class RepoSummaryView(RepoAppView):'
179 c = self.load_default_context()
202 c = self.load_default_context()
180
203
181 # Prepare the clone URL
204 # Prepare the clone URL
182 username = ''
205 self._prepare_and_set_clone_url(c)
183 if self._rhodecode_user.username != User.DEFAULT_USER:
184 username = safe_str(self._rhodecode_user.username)
185
186 _def_clone_uri = _def_clone_uri_id = c.clone_uri_tmpl
187 _def_clone_uri_ssh = c.clone_uri_ssh_tmpl
188
206
189 if '{repo}' in _def_clone_uri:
207 # update every 5 min
190 _def_clone_uri_id = _def_clone_uri.replace(
208 if self.db_repo.last_commit_cache_update_diff > 60 * 5:
191 '{repo}', '_{repoid}')
209 self.db_repo.update_commit_cache()
192 elif '{repoid}' in _def_clone_uri:
193 _def_clone_uri_id = _def_clone_uri.replace(
194 '_{repoid}', '{repo}')
195
196 c.clone_repo_url = self.db_repo.clone_url(
197 user=username, uri_tmpl=_def_clone_uri)
198 c.clone_repo_url_id = self.db_repo.clone_url(
199 user=username, uri_tmpl=_def_clone_uri_id)
200 c.clone_repo_url_ssh = self.db_repo.clone_url(
201 uri_tmpl=_def_clone_uri_ssh, ssh=True)
202
210
203 # If enabled, get statistics data
211 # If enabled, get statistics data
204
212
@@ -231,8 +239,6 b' class RepoSummaryView(RepoAppView):'
231 c.enable_downloads = self.db_repo.enable_downloads
239 c.enable_downloads = self.db_repo.enable_downloads
232 c.repository_followers = scm_model.get_followers(self.db_repo)
240 c.repository_followers = scm_model.get_followers(self.db_repo)
233 c.repository_forks = scm_model.get_forks(self.db_repo)
241 c.repository_forks = scm_model.get_forks(self.db_repo)
234 c.repository_is_user_following = scm_model.is_following_repo(
235 self.db_repo_name, self._rhodecode_user.user_id)
236
242
237 # first interaction with the VCS instance after here...
243 # first interaction with the VCS instance after here...
238 if c.repository_requirements_missing:
244 if c.repository_requirements_missing:
@@ -317,8 +323,7 b' class RepoSummaryView(RepoAppView):'
317 (_("Tag"), repo.tags, 'tag'),
323 (_("Tag"), repo.tags, 'tag'),
318 (_("Bookmark"), repo.bookmarks, 'book'),
324 (_("Bookmark"), repo.bookmarks, 'book'),
319 ]
325 ]
320 res = self._create_reference_data(
326 res = self._create_reference_data(repo, self.db_repo_name, refs_to_create)
321 repo, self.db_repo_name, refs_to_create)
322 data = {
327 data = {
323 'more': False,
328 'more': False,
324 'results': res
329 'results': res
@@ -365,8 +370,7 b' class RepoSummaryView(RepoAppView):'
365 })
370 })
366 return result
371 return result
367
372
368 def _create_reference_items(self, repo, full_repo_name, refs, ref_type,
373 def _create_reference_items(self, repo, full_repo_name, refs, ref_type, format_ref_id):
369 format_ref_id):
370 result = []
374 result = []
371 is_svn = h.is_svn(repo)
375 is_svn = h.is_svn(repo)
372 for ref_name, raw_id in refs.iteritems():
376 for ref_name, raw_id in refs.iteritems():
@@ -378,6 +382,7 b' class RepoSummaryView(RepoAppView):'
378 'raw_id': raw_id,
382 'raw_id': raw_id,
379 'type': ref_type,
383 'type': ref_type,
380 'files_url': files_url,
384 'files_url': files_url,
385 'idx': 0,
381 })
386 })
382 return result
387 return result
383
388
@@ -20,12 +20,13 b''
20
20
21 import os
21 import os
22 import sys
22 import sys
23 import shutil
24 import logging
23 import logging
25 import tempfile
24 import tempfile
26 import textwrap
25 import textwrap
27
26 import collections
28 from .base import VcsServer
27 from .base import VcsServer
28 from rhodecode.model.db import RhodeCodeUi
29 from rhodecode.model.settings import VcsSettingsModel
29
30
30 log = logging.getLogger(__name__)
31 log = logging.getLogger(__name__)
31
32
@@ -37,62 +38,46 b' class MercurialTunnelWrapper(object):'
37 self.server = server
38 self.server = server
38 self.stdin = sys.stdin
39 self.stdin = sys.stdin
39 self.stdout = sys.stdout
40 self.stdout = sys.stdout
40 self.svn_conf_fd, self.svn_conf_path = tempfile.mkstemp()
41 self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp(prefix='hgrc_rhodecode_')
41 self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp()
42
42
43 def create_hooks_env(self):
43 def create_hooks_env(self):
44 repo_name = self.server.repo_name
45 hg_flags = self.server.config_to_hgrc(repo_name)
44
46
45 content = textwrap.dedent(
47 content = textwrap.dedent(
46 '''
48 '''
47 # SSH hooks version=1.0.0
49 # RhodeCode SSH hooks version=2.0.0
48 [hooks]
50 {custom}
49 pretxnchangegroup.ssh_auth=python:vcsserver.hooks.pre_push_ssh_auth
51 '''
50 pretxnchangegroup.ssh=python:vcsserver.hooks.pre_push_ssh
52 ).format(custom='\n'.join(hg_flags))
51 changegroup.ssh=python:vcsserver.hooks.post_push_ssh
52
53
53 preoutgoing.ssh=python:vcsserver.hooks.pre_pull_ssh
54 root = self.server.get_root_store()
54 outgoing.ssh=python:vcsserver.hooks.post_pull_ssh
55 hgrc_custom = os.path.join(root, repo_name, '.hg', 'hgrc_rhodecode')
56 hgrc_main = os.path.join(root, repo_name, '.hg', 'hgrc')
55
57
56 '''
58 # cleanup custom hgrc file
57 )
59 if os.path.isfile(hgrc_custom):
60 with open(hgrc_custom, 'wb') as f:
61 f.write('')
62 log.debug('Cleanup custom hgrc file under %s', hgrc_custom)
58
63
64 # write temp
59 with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file:
65 with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file:
60 hooks_env_file.write(content)
66 hooks_env_file.write(content)
61 root = self.server.get_root_store()
62
67
63 hgrc_custom = os.path.join(
68 return self.hooks_env_path
64 root, self.server.repo_name, '.hg', 'hgrc_rhodecode')
65 log.debug('Wrote custom hgrc file under %s', hgrc_custom)
66 shutil.move(
67 self.hooks_env_path, hgrc_custom)
68
69 hgrc_main = os.path.join(
70 root, self.server.repo_name, '.hg', 'hgrc')
71 include_marker = '%include hgrc_rhodecode'
72
69
73 if not os.path.isfile(hgrc_main):
70 def remove_configs(self):
74 os.mknod(hgrc_main)
71 os.remove(self.hooks_env_path)
75
76 with open(hgrc_main, 'rb') as f:
77 data = f.read()
78 has_marker = include_marker in data
79
72
80 if not has_marker:
73 def command(self, hgrc_path):
81 log.debug('Adding include marker for hooks')
82 with open(hgrc_main, 'wa') as f:
83 f.write(textwrap.dedent('''
84 # added by RhodeCode
85 {}
86 '''.format(include_marker)))
87
88 def command(self):
89 root = self.server.get_root_store()
74 root = self.server.get_root_store()
90
75
91 command = (
76 command = (
92 "cd {root}; {hg_path} -R {root}{repo_name} "
77 "cd {root}; HGRCPATH={hgrc} {hg_path} -R {root}{repo_name} "
93 "serve --stdio".format(
78 "serve --stdio".format(
94 root=root, hg_path=self.server.hg_path,
79 root=root, hg_path=self.server.hg_path,
95 repo_name=self.server.repo_name))
80 repo_name=self.server.repo_name, hgrc=hgrc_path))
96 log.debug("Final CMD: %s", command)
81 log.debug("Final CMD: %s", command)
97 return command
82 return command
98
83
@@ -102,22 +87,61 b' class MercurialTunnelWrapper(object):'
102 action = '?'
87 action = '?'
103 # permissions are check via `pre_push_ssh_auth` hook
88 # permissions are check via `pre_push_ssh_auth` hook
104 self.server.update_environment(action=action, extras=extras)
89 self.server.update_environment(action=action, extras=extras)
105 self.create_hooks_env()
90 custom_hgrc_file = self.create_hooks_env()
106 return os.system(self.command())
91
92 try:
93 return os.system(self.command(custom_hgrc_file))
94 finally:
95 self.remove_configs()
107
96
108
97
109 class MercurialServer(VcsServer):
98 class MercurialServer(VcsServer):
110 backend = 'hg'
99 backend = 'hg'
100 cli_flags = ['phases', 'largefiles', 'extensions', 'experimental', 'hooks']
111
101
112 def __init__(self, store, ini_path, repo_name,
102 def __init__(self, store, ini_path, repo_name, user, user_permissions, config, env):
113 user, user_permissions, config, env):
103 super(MercurialServer, self).__init__(user, user_permissions, config, env)
114 super(MercurialServer, self).\
115 __init__(user, user_permissions, config, env)
116
104
117 self.store = store
105 self.store = store
118 self.ini_path = ini_path
106 self.ini_path = ini_path
119 self.repo_name = repo_name
107 self.repo_name = repo_name
120 self._path = self.hg_path = config.get(
108 self._path = self.hg_path = config.get('app:main', 'ssh.executable.hg')
121 'app:main', 'ssh.executable.hg')
109 self.tunnel = MercurialTunnelWrapper(server=self)
110
111 def config_to_hgrc(self, repo_name):
112 ui_sections = collections.defaultdict(list)
113 ui = VcsSettingsModel(repo=repo_name).get_ui_settings(section=None, key=None)
114
115 # write default hooks
116 default_hooks = [
117 ('pretxnchangegroup.ssh_auth', 'python:vcsserver.hooks.pre_push_ssh_auth'),
118 ('pretxnchangegroup.ssh', 'python:vcsserver.hooks.pre_push_ssh'),
119 ('changegroup.ssh', 'python:vcsserver.hooks.post_push_ssh'),
120
121 ('preoutgoing.ssh', 'python:vcsserver.hooks.pre_pull_ssh'),
122 ('outgoing.ssh', 'python:vcsserver.hooks.post_pull_ssh'),
123 ]
124
125 for k, v in default_hooks:
126 ui_sections['hooks'].append((k, v))
122
127
123 self.tunnel = MercurialTunnelWrapper(server=self)
128 for entry in ui:
129 if not entry.active:
130 continue
131 sec = entry.section
132 key = entry.key
133
134 if sec in self.cli_flags:
135 # we want only custom hooks, so we skip builtins
136 if sec == 'hooks' and key in RhodeCodeUi.HOOKS_BUILTIN:
137 continue
138
139 ui_sections[sec].append([key, entry.value])
140
141 flags = []
142 for _sec, key_val in ui_sections.items():
143 flags.append(' ')
144 flags.append('[{}]'.format(_sec))
145 for key, val in key_val:
146 flags.append('{}= {}'.format(key, val))
147 return flags
@@ -18,6 +18,7 b''
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import mock
22 import mock
22 import pytest
23 import pytest
23
24
@@ -68,14 +69,16 b' def hg_server(app):'
68
69
69 class TestMercurialServer(object):
70 class TestMercurialServer(object):
70
71
71 def test_command(self, hg_server):
72 def test_command(self, hg_server, tmpdir):
72 server = hg_server.create()
73 server = hg_server.create()
74 custom_hgrc = os.path.join(str(tmpdir), 'hgrc')
73 expected_command = (
75 expected_command = (
74 'cd {root}; {hg_path} -R {root}{repo_name} serve --stdio'.format(
76 'cd {root}; HGRCPATH={custom_hgrc} {hg_path} -R {root}{repo_name} serve --stdio'.format(
75 root=hg_server.root, hg_path=hg_server.hg_path,
77 root=hg_server.root, custom_hgrc=custom_hgrc, hg_path=hg_server.hg_path,
76 repo_name=hg_server.repo_name)
78 repo_name=hg_server.repo_name)
77 )
79 )
78 assert expected_command == server.tunnel.command()
80 server_command = server.tunnel.command(custom_hgrc)
81 assert expected_command == server_command
79
82
80 @pytest.mark.parametrize('permissions, action, code', [
83 @pytest.mark.parametrize('permissions, action, code', [
81 ({}, 'pull', -2),
84 ({}, 'pull', -2),
This diff has been collapsed as it changes many lines, (910 lines changed) Show them Hide them
@@ -28,23 +28,16 b''
28 {
28 {
29 "license": [
29 "license": [
30 {
30 {
31 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
32 "shortName": "bsdOriginal",
33 "spdxId": "BSD-4-Clause",
34 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
35 }
36 ],
37 "name": "python2.7-coverage-3.7.1"
38 },
39 {
40 "license": [
41 {
42 "fullName": "MIT License",
31 "fullName": "MIT License",
43 "shortName": "mit",
32 "shortName": "mit",
44 "spdxId": "MIT",
33 "spdxId": "MIT",
45 "url": "http://spdx.org/licenses/MIT.html"
34 "url": "http://spdx.org/licenses/MIT.html"
46 }
35 }
47 ],
36 ],
37 "name": "python2.7-beautifulsoup4-4.6.3"
38 },
39 {
40 "license": "UNKNOWN",
48 "name": "python2.7-bootstrapped-pip-9.0.1"
41 "name": "python2.7-bootstrapped-pip-9.0.1"
49 },
42 },
50 {
43 {
@@ -56,29 +49,7 b''
56 "url": "http://spdx.org/licenses/MIT.html"
49 "url": "http://spdx.org/licenses/MIT.html"
57 }
50 }
58 ],
51 ],
59 "name": "python2.7-cov-core-1.15.0"
52 "name": "python2.7-webtest-2.0.32"
60 },
61 {
62 "license": [
63 {
64 "fullName": "MIT License",
65 "shortName": "mit",
66 "spdxId": "MIT",
67 "url": "http://spdx.org/licenses/MIT.html"
68 }
69 ],
70 "name": "python2.7-webtest-2.0.29"
71 },
72 {
73 "license": [
74 {
75 "fullName": "MIT License",
76 "shortName": "mit",
77 "spdxId": "MIT",
78 "url": "http://spdx.org/licenses/MIT.html"
79 }
80 ],
81 "name": "python2.7-beautifulsoup4-4.6.3"
82 },
53 },
83 {
54 {
84 "license": [
55 "license": [
@@ -100,7 +71,7 b''
100 "url": "http://spdx.org/licenses/MIT.html"
71 "url": "http://spdx.org/licenses/MIT.html"
101 }
72 }
102 ],
73 ],
103 "name": "python2.7-webob-1.7.4"
74 "name": "python2.7-webob-1.8.4"
104 },
75 },
105 {
76 {
106 "license": [
77 "license": [
@@ -116,6 +87,28 b''
116 {
87 {
117 "license": [
88 "license": [
118 {
89 {
90 "fullName": "Apache License 2.0",
91 "shortName": "asl20",
92 "spdxId": "Apache-2.0",
93 "url": "http://spdx.org/licenses/Apache-2.0.html"
94 }
95 ],
96 "name": "python2.7-coverage-4.5.1"
97 },
98 {
99 "license": [
100 {
101 "fullName": "MIT License",
102 "shortName": "mit",
103 "spdxId": "MIT",
104 "url": "http://spdx.org/licenses/MIT.html"
105 }
106 ],
107 "name": "python2.7-cov-core-1.15.0"
108 },
109 {
110 "license": [
111 {
119 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
112 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
120 "shortName": "bsdOriginal",
113 "shortName": "bsdOriginal",
121 "spdxId": "BSD-4-Clause",
114 "spdxId": "BSD-4-Clause",
@@ -127,6 +120,17 b''
127 {
120 {
128 "license": [
121 "license": [
129 {
122 {
123 "fullName": "GNU Lesser General Public License v3 or later (LGPLv3+)"
124 },
125 {
126 "fullName": "LGPL"
127 }
128 ],
129 "name": "python2.7-gprof2dot-2017.9.19"
130 },
131 {
132 "license": [
133 {
130 "fullName": "MIT License",
134 "fullName": "MIT License",
131 "shortName": "mit",
135 "shortName": "mit",
132 "spdxId": "MIT",
136 "spdxId": "MIT",
@@ -136,7 +140,7 b''
136 "fullName": "DFSG approved"
140 "fullName": "DFSG approved"
137 }
141 }
138 ],
142 ],
139 "name": "python2.7-pytest-timeout-1.2.1"
143 "name": "python2.7-pytest-timeout-1.3.2"
140 },
144 },
141 {
145 {
142 "license": [
146 "license": [
@@ -147,7 +151,32 b''
147 "url": "http://spdx.org/licenses/MIT.html"
151 "url": "http://spdx.org/licenses/MIT.html"
148 }
152 }
149 ],
153 ],
150 "name": "python2.7-pytest-3.6.0"
154 "name": "python2.7-pytest-3.8.2"
155 },
156 {
157 "license": [
158 {
159 "fullName": "MIT License",
160 "shortName": "mit",
161 "spdxId": "MIT",
162 "url": "http://spdx.org/licenses/MIT.html"
163 }
164 ],
165 "name": "python2.7-pathlib2-2.3.3"
166 },
167 {
168 "license": [
169 {
170 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
171 "shortName": "bsdOriginal",
172 "spdxId": "BSD-4-Clause",
173 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
174 },
175 {
176 "fullName": "New BSD License"
177 }
178 ],
179 "name": "python2.7-scandir-1.9.0"
151 },
180 },
152 {
181 {
153 "license": [
182 "license": [
@@ -172,7 +201,7 b''
172 "url": "http://spdx.org/licenses/MIT.html"
201 "url": "http://spdx.org/licenses/MIT.html"
173 }
202 }
174 ],
203 ],
175 "name": "python2.7-pluggy-0.6.0"
204 "name": "python2.7-pluggy-0.9.0"
176 },
205 },
177 {
206 {
178 "license": [
207 "license": [
@@ -183,7 +212,7 b''
183 "url": "http://spdx.org/licenses/MIT.html"
212 "url": "http://spdx.org/licenses/MIT.html"
184 }
213 }
185 ],
214 ],
186 "name": "python2.7-atomicwrites-1.1.5"
215 "name": "python2.7-atomicwrites-1.2.1"
187 },
216 },
188 {
217 {
189 "license": [
218 "license": [
@@ -194,7 +223,7 b''
194 "url": "http://spdx.org/licenses/MIT.html"
223 "url": "http://spdx.org/licenses/MIT.html"
195 }
224 }
196 ],
225 ],
197 "name": "python2.7-more-itertools-4.3.0"
226 "name": "python2.7-more-itertools-5.0.0"
198 },
227 },
199 {
228 {
200 "license": [
229 "license": [
@@ -205,7 +234,7 b''
205 "url": "http://spdx.org/licenses/MIT.html"
234 "url": "http://spdx.org/licenses/MIT.html"
206 }
235 }
207 ],
236 ],
208 "name": "python2.7-attrs-18.1.0"
237 "name": "python2.7-attrs-18.2.0"
209 },
238 },
210 {
239 {
211 "license": [
240 "license": [
@@ -216,18 +245,7 b''
216 "url": "http://spdx.org/licenses/MIT.html"
245 "url": "http://spdx.org/licenses/MIT.html"
217 }
246 }
218 ],
247 ],
219 "name": "python2.7-py-1.5.3"
248 "name": "python2.7-py-1.6.0"
220 },
221 {
222 "license": [
223 {
224 "fullName": "GNU Lesser General Public License v3 or later (LGPLv3+)"
225 },
226 {
227 "fullName": "LGPL"
228 }
229 ],
230 "name": "python2.7-gprof2dot-2017.9.19"
231 },
249 },
232 {
250 {
233 "license": [
251 "license": [
@@ -254,17 +272,6 b''
254 {
272 {
255 "license": [
273 "license": [
256 {
274 {
257 "fullName": "MIT License",
258 "shortName": "mit",
259 "spdxId": "MIT",
260 "url": "http://spdx.org/licenses/MIT.html"
261 }
262 ],
263 "name": "python2.7-setuptools-scm-2.1.0"
264 },
265 {
266 "license": [
267 {
268 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
275 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
269 "shortName": "bsdOriginal",
276 "shortName": "bsdOriginal",
270 "spdxId": "BSD-4-Clause",
277 "spdxId": "BSD-4-Clause",
@@ -299,7 +306,7 b''
299 "url": "http://spdx.org/licenses/MIT.html"
306 "url": "http://spdx.org/licenses/MIT.html"
300 }
307 }
301 ],
308 ],
302 "name": "python2.7-pytest-cov-2.5.1"
309 "name": "python2.7-pytest-cov-2.6.0"
303 },
310 },
304 {
311 {
305 "license": [
312 "license": [
@@ -310,7 +317,7 b''
310 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
317 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
311 }
318 }
312 ],
319 ],
313 "name": "python2.7-appenlight-client-0.6.25"
320 "name": "python2.7-appenlight-client-0.6.26"
314 },
321 },
315 {
322 {
316 "license": [
323 "license": [
@@ -326,10 +333,107 b''
326 {
333 {
327 "license": [
334 "license": [
328 {
335 {
329 "fullName": "AGPLv3 and Proprietary"
336 "fullName": "Apache 2.0 and Proprietary"
337 }
338 ],
339 "name": "python2.7-rhodecode-tools-1.2.1"
340 },
341 {
342 "license": [
343 {
344 "fullName": "Apache License 2.0",
345 "shortName": "asl20",
346 "spdxId": "Apache-2.0",
347 "url": "http://spdx.org/licenses/Apache-2.0.html"
348 }
349 ],
350 "name": "python2.7-elasticsearch1-dsl-0.0.12"
351 },
352 {
353 "license": [
354 {
355 "fullName": "Apache License 2.0",
356 "shortName": "asl20",
357 "spdxId": "Apache-2.0",
358 "url": "http://spdx.org/licenses/Apache-2.0.html"
359 }
360 ],
361 "name": "python2.7-elasticsearch1-1.10.0"
362 },
363 {
364 "license": [
365 {
366 "fullName": "MIT License",
367 "shortName": "mit",
368 "spdxId": "MIT",
369 "url": "http://spdx.org/licenses/MIT.html"
330 }
370 }
331 ],
371 ],
332 "name": "python2.7-rhodecode-tools-0.16.0"
372 "name": "python2.7-urllib3-1.24.1"
373 },
374 {
375 "license": [
376 {
377 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
378 "shortName": "bsdOriginal",
379 "spdxId": "BSD-4-Clause",
380 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
381 },
382 {
383 "fullName": "Apache License 2.0",
384 "shortName": "asl20",
385 "spdxId": "Apache-2.0",
386 "url": "http://spdx.org/licenses/Apache-2.0.html"
387 },
388 {
389 "fullName": "Dual License"
390 }
391 ],
392 "name": "python2.7-python-dateutil-2.8.0"
393 },
394 {
395 "license": [
396 {
397 "fullName": "Apache License 2.0",
398 "shortName": "asl20",
399 "spdxId": "Apache-2.0",
400 "url": "http://spdx.org/licenses/Apache-2.0.html"
401 }
402 ],
403 "name": "python2.7-elasticsearch2-2.5.0"
404 },
405 {
406 "license": [
407 {
408 "fullName": "Apache License 2.0",
409 "shortName": "asl20",
410 "spdxId": "Apache-2.0",
411 "url": "http://spdx.org/licenses/Apache-2.0.html"
412 }
413 ],
414 "name": "python2.7-elasticsearch-dsl-6.3.1"
415 },
416 {
417 "license": [
418 {
419 "fullName": "Python Software Foundation License version 2",
420 "shortName": "psfl",
421 "spdxId": "Python-2.0",
422 "url": "http://spdx.org/licenses/Python-2.0.html"
423 }
424 ],
425 "name": "python2.7-ipaddress-1.0.22"
426 },
427 {
428 "license": [
429 {
430 "fullName": "Apache License 2.0",
431 "shortName": "asl20",
432 "spdxId": "Apache-2.0",
433 "url": "http://spdx.org/licenses/Apache-2.0.html"
434 }
435 ],
436 "name": "python2.7-elasticsearch-6.3.1"
333 },
437 },
334 {
438 {
335 "license": [
439 "license": [
@@ -351,66 +455,13 b''
351 {
455 {
352 "license": [
456 "license": [
353 {
457 {
354 "fullName": "MIT License",
355 "shortName": "mit",
356 "spdxId": "MIT",
357 "url": "http://spdx.org/licenses/MIT.html"
358 }
359 ],
360 "name": "python2.7-urllib3-1.21"
361 },
362 {
363 "license": [
364 {
365 "fullName": "Apache License 2.0",
366 "shortName": "asl20",
367 "spdxId": "Apache-2.0",
368 "url": "http://spdx.org/licenses/Apache-2.0.html"
369 }
370 ],
371 "name": "python2.7-elasticsearch-dsl-2.2.0"
372 },
373 {
374 "license": [
375 {
376 "fullName": "Apache License 2.0",
377 "shortName": "asl20",
378 "spdxId": "Apache-2.0",
379 "url": "http://spdx.org/licenses/Apache-2.0.html"
380 }
381 ],
382 "name": "python2.7-elasticsearch-2.3.0"
383 },
384 {
385 "license": [
386 {
387 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
388 "shortName": "bsdOriginal",
389 "spdxId": "BSD-4-Clause",
390 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
391 },
392 {
393 "fullName": "Apache License 2.0",
394 "shortName": "asl20",
395 "spdxId": "Apache-2.0",
396 "url": "http://spdx.org/licenses/Apache-2.0.html"
397 },
398 {
399 "fullName": "Dual License"
400 }
401 ],
402 "name": "python2.7-python-dateutil-2.7.3"
403 },
404 {
405 "license": [
406 {
407 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
458 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
408 "shortName": "bsdOriginal",
459 "shortName": "bsdOriginal",
409 "spdxId": "BSD-4-Clause",
460 "spdxId": "BSD-4-Clause",
410 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
461 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
411 }
462 }
412 ],
463 ],
413 "name": "python2.7-markupsafe-1.0"
464 "name": "python2.7-markupsafe-1.1.0"
414 },
465 },
415 {
466 {
416 "license": [
467 "license": [
@@ -443,29 +494,7 b''
443 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
494 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
444 }
495 }
445 ],
496 ],
446 "name": "python2.7-click-6.6"
497 "name": "python2.7-click-7.0"
447 },
448 {
449 "license": [
450 {
451 "fullName": "MIT License",
452 "shortName": "mit",
453 "spdxId": "MIT",
454 "url": "http://spdx.org/licenses/MIT.html"
455 }
456 ],
457 "name": "python2.7-bottle-0.12.13"
458 },
459 {
460 "license": [
461 {
462 "fullName": "MIT License",
463 "shortName": "mit",
464 "spdxId": "MIT",
465 "url": "http://spdx.org/licenses/MIT.html"
466 }
467 ],
468 "name": "python2.7-cprofilev-1.0.7"
469 },
498 },
470 {
499 {
471 "license": [
500 "license": [
@@ -519,31 +548,6 b''
519 "url": "http://spdx.org/licenses/MIT.html"
548 "url": "http://spdx.org/licenses/MIT.html"
520 }
549 }
521 ],
550 ],
522 "name": "python2.7-pathlib2-2.3.0"
523 },
524 {
525 "license": [
526 {
527 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
528 "shortName": "bsdOriginal",
529 "spdxId": "BSD-4-Clause",
530 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
531 },
532 {
533 "fullName": "New BSD License"
534 }
535 ],
536 "name": "python2.7-scandir-1.9.0"
537 },
538 {
539 "license": [
540 {
541 "fullName": "MIT License",
542 "shortName": "mit",
543 "spdxId": "MIT",
544 "url": "http://spdx.org/licenses/MIT.html"
545 }
546 ],
547 "name": "python2.7-backports.shutil-get-terminal-size-1.0.0"
551 "name": "python2.7-backports.shutil-get-terminal-size-1.0.0"
548 },
552 },
549 {
553 {
@@ -555,7 +559,7 b''
555 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
559 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
556 }
560 }
557 ],
561 ],
558 "name": "python2.7-pygments-2.2.0"
562 "name": "python2.7-pygments-2.3.1"
559 },
563 },
560 {
564 {
561 "license": [
565 "license": [
@@ -646,7 +650,7 b''
646 "url": "http://spdx.org/licenses/MIT.html"
650 "url": "http://spdx.org/licenses/MIT.html"
647 }
651 }
648 ],
652 ],
649 "name": "python2.7-pickleshare-0.7.4"
653 "name": "python2.7-pickleshare-0.7.5"
650 },
654 },
651 {
655 {
652 "license": [
656 "license": [
@@ -690,7 +694,7 b''
690 "url": "http://spdx.org/licenses/MIT.html"
694 "url": "http://spdx.org/licenses/MIT.html"
691 }
695 }
692 ],
696 ],
693 "name": "python2.7-greenlet-0.4.13"
697 "name": "python2.7-greenlet-0.4.15"
694 },
698 },
695 {
699 {
696 "license": [
700 "license": [
@@ -701,7 +705,7 b''
701 "url": "http://spdx.org/licenses/MIT.html"
705 "url": "http://spdx.org/licenses/MIT.html"
702 }
706 }
703 ],
707 ],
704 "name": "python2.7-gevent-1.3.5"
708 "name": "python2.7-gevent-1.4.0"
705 },
709 },
706 {
710 {
707 "license": [
711 "license": [
@@ -712,7 +716,7 b''
712 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
716 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
713 }
717 }
714 ],
718 ],
715 "name": "python2.7-psutil-5.4.6"
719 "name": "python2.7-psutil-5.5.1"
716 },
720 },
717 {
721 {
718 "license": [
722 "license": [
@@ -745,7 +749,7 b''
745 "url": "http://spdx.org/licenses/MIT.html"
749 "url": "http://spdx.org/licenses/MIT.html"
746 }
750 }
747 ],
751 ],
748 "name": "python2.7-alembic-0.9.9"
752 "name": "python2.7-alembic-1.0.5"
749 },
753 },
750 {
754 {
751 "license": {
755 "license": {
@@ -754,7 +758,7 b''
754 "spdxId": "Apache-2.0",
758 "spdxId": "Apache-2.0",
755 "url": "http://spdx.org/licenses/Apache-2.0.html"
759 "url": "http://spdx.org/licenses/Apache-2.0.html"
756 },
760 },
757 "name": "python2.7-python-editor-1.0.3"
761 "name": "python2.7-python-editor-1.0.4"
758 },
762 },
759 {
763 {
760 "license": [
764 "license": [
@@ -842,39 +846,6 b''
842 {
846 {
843 "license": [
847 "license": [
844 {
848 {
845 "fullName": "Apache License 2.0",
846 "shortName": "asl20",
847 "spdxId": "Apache-2.0",
848 "url": "http://spdx.org/licenses/Apache-2.0.html"
849 }
850 ],
851 "name": "python2.7-bleach-2.1.4"
852 },
853 {
854 "license": [
855 {
856 "fullName": "MIT License",
857 "shortName": "mit",
858 "spdxId": "MIT",
859 "url": "http://spdx.org/licenses/MIT.html"
860 }
861 ],
862 "name": "python2.7-html5lib-1.0.1"
863 },
864 {
865 "license": [
866 {
867 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
868 "shortName": "bsdOriginal",
869 "spdxId": "BSD-4-Clause",
870 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
871 }
872 ],
873 "name": "python2.7-webencodings-0.5.1"
874 },
875 {
876 "license": [
877 {
878 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
849 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
879 "shortName": "bsdOriginal",
850 "shortName": "bsdOriginal",
880 "spdxId": "BSD-4-Clause",
851 "spdxId": "BSD-4-Clause",
@@ -892,7 +863,7 b''
892 "url": "http://spdx.org/licenses/MIT.html"
863 "url": "http://spdx.org/licenses/MIT.html"
893 }
864 }
894 ],
865 ],
895 "name": "python2.7-testpath-0.3.1"
866 "name": "python2.7-testpath-0.4.2"
896 },
867 },
897 {
868 {
898 "license": [
869 "license": [
@@ -908,6 +879,28 b''
908 {
879 {
909 "license": [
880 "license": [
910 {
881 {
882 "fullName": "Apache License 2.0",
883 "shortName": "asl20",
884 "spdxId": "Apache-2.0",
885 "url": "http://spdx.org/licenses/Apache-2.0.html"
886 }
887 ],
888 "name": "python2.7-bleach-3.1.0"
889 },
890 {
891 "license": [
892 {
893 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
894 "shortName": "bsdOriginal",
895 "spdxId": "BSD-4-Clause",
896 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
897 }
898 ],
899 "name": "python2.7-webencodings-0.5.1"
900 },
901 {
902 "license": [
903 {
911 "fullName": "MIT License",
904 "fullName": "MIT License",
912 "shortName": "mit",
905 "shortName": "mit",
913 "spdxId": "MIT",
906 "spdxId": "MIT",
@@ -925,7 +918,7 b''
925 "url": "http://spdx.org/licenses/MIT.html"
918 "url": "http://spdx.org/licenses/MIT.html"
926 }
919 }
927 ],
920 ],
928 "name": "python2.7-configparser-3.5.0"
921 "name": "python2.7-configparser-3.7.3"
929 },
922 },
930 {
923 {
931 "license": [
924 "license": [
@@ -947,7 +940,73 b''
947 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
940 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
948 }
941 }
949 ],
942 ],
950 "name": "python2.7-mistune-0.8.3"
943 "name": "python2.7-mistune-0.8.4"
944 },
945 {
946 "license": {
947 "fullName": "GNU Lesser General Public License v3.0 or later",
948 "shortName": "lgpl3Plus",
949 "spdxId": "LGPL-3.0+",
950 "url": "http://spdx.org/licenses/LGPL-3.0+.html"
951 },
952 "name": "python2.7-psycopg2-2.7.7"
953 },
954 {
955 "license": {
956 "fullName": "PostgreSQL License",
957 "shortName": "postgresql",
958 "spdxId": "PostgreSQL",
959 "url": "http://spdx.org/licenses/PostgreSQL.html"
960 },
961 "name": "postgresql-9.6.10"
962 },
963 {
964 "license": [
965 {
966 "fullName": "zlib License",
967 "shortName": "zlib",
968 "spdxId": "Zlib",
969 "url": "http://spdx.org/licenses/Zlib.html"
970 },
971 {
972 "fullName": "libpng License",
973 "shortName": "libpng",
974 "spdxId": "Libpng",
975 "url": "http://spdx.org/licenses/Libpng.html"
976 }
977 ],
978 "name": "python2.7-pysqlite-2.8.3"
979 },
980 {
981 "license": [
982 {
983 "fullName": "MIT License",
984 "shortName": "mit",
985 "spdxId": "MIT",
986 "url": "http://spdx.org/licenses/MIT.html"
987 }
988 ],
989 "name": "python2.7-pymysql-0.8.1"
990 },
991 {
992 "license": [
993 {
994 "fullName": "GNU General Public License v1.0 only",
995 "shortName": "gpl1",
996 "spdxId": "GPL-1.0",
997 "url": "http://spdx.org/licenses/GPL-1.0.html"
998 }
999 ],
1000 "name": "python2.7-mysql-python-1.2.5"
1001 },
1002 {
1003 "license": {
1004 "fullName": "GNU Library General Public License v2.1 only",
1005 "shortName": "lgpl21",
1006 "spdxId": "LGPL-2.1",
1007 "url": "http://spdx.org/licenses/LGPL-2.1.html"
1008 },
1009 "name": "mariadb-connector-c-2.3.4"
951 },
1010 },
952 {
1011 {
953 "license": [
1012 "license": [
@@ -958,7 +1017,7 b''
958 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1017 "url": "http://spdx.org/licenses/ZPL-2.1.html"
959 }
1018 }
960 ],
1019 ],
961 "name": "python2.7-zope.interface-4.5.0"
1020 "name": "python2.7-zope.interface-4.6.0"
962 },
1021 },
963 {
1022 {
964 "license": [
1023 "license": [
@@ -969,7 +1028,7 b''
969 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1028 "url": "http://spdx.org/licenses/ZPL-2.1.html"
970 }
1029 }
971 ],
1030 ],
972 "name": "python2.7-zope.event-4.3.0"
1031 "name": "python2.7-zope.event-4.4"
973 },
1032 },
974 {
1033 {
975 "license": [
1034 "license": [
@@ -980,7 +1039,7 b''
980 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1039 "url": "http://spdx.org/licenses/ZPL-2.1.html"
981 }
1040 }
982 ],
1041 ],
983 "name": "python2.7-zope.deprecation-4.3.0"
1042 "name": "python2.7-zope.deprecation-4.4.0"
984 },
1043 },
985 {
1044 {
986 "license": [
1045 "license": [
@@ -1043,7 +1102,7 b''
1043 "url": "http://spdx.org/licenses/MIT.html"
1102 "url": "http://spdx.org/licenses/MIT.html"
1044 }
1103 }
1045 ],
1104 ],
1046 "name": "python2.7-paste-2.0.3"
1105 "name": "python2.7-paste-3.0.5"
1047 },
1106 },
1048 {
1107 {
1049 "license": [
1108 "license": [
@@ -1061,7 +1120,7 b''
1061 "fullName": "Repoze License",
1120 "fullName": "Repoze License",
1062 "url": "http://www.repoze.org/LICENSE.txt"
1121 "url": "http://www.repoze.org/LICENSE.txt"
1063 },
1122 },
1064 "name": "python2.7-venusian-1.1.0"
1123 "name": "python2.7-venusian-1.2.0"
1065 },
1124 },
1066 {
1125 {
1067 "license": {
1126 "license": {
@@ -1072,17 +1131,6 b''
1072 "name": "python2.7-urlobject-2.4.3"
1131 "name": "python2.7-urlobject-2.4.3"
1073 },
1132 },
1074 {
1133 {
1075 "license": [
1076 {
1077 "fullName": "Apache License 2.0",
1078 "shortName": "asl20",
1079 "spdxId": "Apache-2.0",
1080 "url": "http://spdx.org/licenses/Apache-2.0.html"
1081 }
1082 ],
1083 "name": "python2.7-trollius-1.0.4"
1084 },
1085 {
1086 "license": {
1134 "license": {
1087 "fullName": "Repoze License",
1135 "fullName": "Repoze License",
1088 "url": "http://www.repoze.org/LICENSE.txt"
1136 "url": "http://www.repoze.org/LICENSE.txt"
@@ -1095,7 +1143,7 b''
1095 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1143 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1096 }
1144 }
1097 ],
1145 ],
1098 "name": "python2.7-supervisor-3.3.4"
1146 "name": "python2.7-supervisor-3.3.5"
1099 },
1147 },
1100 {
1148 {
1101 "license": [
1149 "license": [
@@ -1114,7 +1162,7 b''
1114 "url": "http://spdx.org/licenses/Python-2.0.html"
1162 "url": "http://spdx.org/licenses/Python-2.0.html"
1115 }
1163 }
1116 ],
1164 ],
1117 "name": "python2.7-subprocess32-3.5.1"
1165 "name": "python2.7-subprocess32-3.5.3"
1118 },
1166 },
1119 {
1167 {
1120 "license": [
1168 "license": [
@@ -1125,7 +1173,7 b''
1125 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1173 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1126 }
1174 }
1127 ],
1175 ],
1128 "name": "python2.7-sshpubkeys-2.2.0"
1176 "name": "python2.7-sshpubkeys-3.1.0"
1129 },
1177 },
1130 {
1178 {
1131 "license": [
1179 "license": [
@@ -1141,11 +1189,55 b''
1141 {
1189 {
1142 "license": [
1190 "license": [
1143 {
1191 {
1144 "fullName": "Public Domain",
1192 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1145 "shortName": "publicDomain"
1193 "shortName": "bsdOriginal",
1194 "spdxId": "BSD-4-Clause",
1195 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1196 },
1197 {
1198 "fullName": "BSD or Apache License, Version 2.0"
1199 },
1200 {
1201 "fullName": "Apache License 2.0",
1202 "shortName": "asl20",
1203 "spdxId": "Apache-2.0",
1204 "url": "http://spdx.org/licenses/Apache-2.0.html"
1146 }
1205 }
1147 ],
1206 ],
1148 "name": "python2.7-pycrypto-2.6.1"
1207 "name": "python2.7-cryptography-2.5"
1208 },
1209 {
1210 "license": [
1211 {
1212 "fullName": "MIT License",
1213 "shortName": "mit",
1214 "spdxId": "MIT",
1215 "url": "http://spdx.org/licenses/MIT.html"
1216 }
1217 ],
1218 "name": "python2.7-cffi-1.12.1"
1219 },
1220 {
1221 "license": [
1222 {
1223 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1224 "shortName": "bsdOriginal",
1225 "spdxId": "BSD-4-Clause",
1226 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1227 }
1228 ],
1229 "name": "python2.7-pycparser-2.19"
1230 },
1231 {
1232 "license": [
1233 {
1234 "fullName": "MIT License",
1235 "shortName": "mit",
1236 "spdxId": "MIT",
1237 "url": "http://spdx.org/licenses/MIT.html"
1238 }
1239 ],
1240 "name": "python2.7-asn1crypto-0.24.0"
1149 },
1241 },
1150 {
1242 {
1151 "license": [
1243 "license": [
@@ -1159,18 +1251,7 b''
1159 "url": "http://spdx.org/licenses/MIT.html"
1251 "url": "http://spdx.org/licenses/MIT.html"
1160 }
1252 }
1161 ],
1253 ],
1162 "name": "python2.7-simplejson-3.11.1"
1254 "name": "python2.7-simplejson-3.16.0"
1163 },
1164 {
1165 "license": [
1166 {
1167 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1168 "shortName": "bsdOriginal",
1169 "spdxId": "BSD-4-Clause",
1170 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1171 }
1172 ],
1173 "name": "python2.7-setproctitle-1.1.10"
1174 },
1255 },
1175 {
1256 {
1176 "license": [
1257 "license": [
@@ -1210,7 +1291,7 b''
1210 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1291 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1211 }
1292 }
1212 ],
1293 ],
1213 "name": "python2.7-py-gfm-0.1.3"
1294 "name": "python2.7-py-gfm-0.1.4"
1214 },
1295 },
1215 {
1296 {
1216 "license": [
1297 "license": [
@@ -1248,6 +1329,72 b''
1248 {
1329 {
1249 "license": [
1330 "license": [
1250 {
1331 {
1332 "fullName": "MIT License",
1333 "shortName": "mit",
1334 "spdxId": "MIT",
1335 "url": "http://spdx.org/licenses/MIT.html"
1336 }
1337 ],
1338 "name": "python2.7-python-saml-2.4.2"
1339 },
1340 {
1341 "license": [
1342 {
1343 "fullName": "Python Software Foundation License version 2",
1344 "shortName": "psfl",
1345 "spdxId": "Python-2.0",
1346 "url": "http://spdx.org/licenses/Python-2.0.html"
1347 }
1348 ],
1349 "name": "python2.7-defusedxml-0.5.0"
1350 },
1351 {
1352 "license": [
1353 {
1354 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1355 "shortName": "bsdOriginal",
1356 "spdxId": "BSD-4-Clause",
1357 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1358 }
1359 ],
1360 "name": "python2.7-isodate-0.6.0"
1361 },
1362 {
1363 "license": [
1364 {
1365 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1366 "shortName": "bsdOriginal",
1367 "spdxId": "BSD-4-Clause",
1368 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1369 }
1370 ],
1371 "name": "python2.7-dm.xmlsec.binding-1.3.7"
1372 },
1373 {
1374 "license": [
1375 {
1376 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1377 "shortName": "bsdOriginal",
1378 "spdxId": "BSD-4-Clause",
1379 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1380 }
1381 ],
1382 "name": "python2.7-lxml-4.2.5"
1383 },
1384 {
1385 "license": [
1386 {
1387 "fullName": "MIT License",
1388 "shortName": "mit",
1389 "spdxId": "MIT",
1390 "url": "http://spdx.org/licenses/MIT.html"
1391 }
1392 ],
1393 "name": "python2.7-wheel-0.30.0"
1394 },
1395 {
1396 "license": [
1397 {
1251 "fullName": "License :: OSI Approved :: MIT License"
1398 "fullName": "License :: OSI Approved :: MIT License"
1252 },
1399 },
1253 {
1400 {
@@ -1260,14 +1407,7 b''
1260 "name": "python2.7-python-pam-1.8.4"
1407 "name": "python2.7-python-pam-1.8.4"
1261 },
1408 },
1262 {
1409 {
1263 "license": [
1410 "license": "UNKNOWN",
1264 {
1265 "fullName": "GNU General Public License v1.0 only",
1266 "shortName": "gpl1",
1267 "spdxId": "GPL-1.0",
1268 "url": "http://spdx.org/licenses/GPL-1.0.html"
1269 }
1270 ],
1271 "name": "linux-pam-1.3.0"
1411 "name": "linux-pam-1.3.0"
1272 },
1412 },
1273 {
1413 {
@@ -1302,9 +1442,7 b''
1302 "name": "libkrb5-1.15.2"
1442 "name": "libkrb5-1.15.2"
1303 },
1443 },
1304 {
1444 {
1305 "license":{
1445 "license": "UNKNOWN",
1306 "fullName": "BSD-derived (https://www.openldap.org/software/release/license.html)"
1307 },
1308 "name": "openldap-2.4.45"
1446 "name": "openldap-2.4.45"
1309 },
1447 },
1310 {
1448 {
@@ -1316,7 +1454,18 b''
1316 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1454 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1317 }
1455 }
1318 ],
1456 ],
1319 "name": "python2.7-pyasn1-modules-0.2.2"
1457 "name": "python2.7-pyasn1-modules-0.2.4"
1458 },
1459 {
1460 "license": [
1461 {
1462 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1463 "shortName": "bsdOriginal",
1464 "spdxId": "BSD-4-Clause",
1465 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1466 }
1467 ],
1468 "name": "python2.7-pyasn1-0.4.5"
1320 },
1469 },
1321 {
1470 {
1322 "license": [
1471 "license": [
@@ -1327,42 +1476,36 b''
1327 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1476 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1328 }
1477 }
1329 ],
1478 ],
1330 "name": "python2.7-pyasn1-0.4.4"
1479 "name": "python2.7-pyramid-mailer-0.15.1"
1331 },
1480 },
1332 {
1481 {
1333 "license": [
1482 "license": [
1334 {
1483 {
1335 "fullName": "zlib License",
1484 "fullName": "Zope Public License 2.1",
1336 "shortName": "zlib",
1485 "shortName": "zpl21",
1337 "spdxId": "Zlib",
1486 "spdxId": "ZPL-2.1",
1338 "url": "http://spdx.org/licenses/Zlib.html"
1487 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1488 }
1489 ],
1490 "name": "python2.7-transaction-2.4.0"
1339 },
1491 },
1340 {
1492 {
1341 "fullName": "libpng License",
1493 "license": [
1342 "shortName": "libpng",
1494 {
1343 "spdxId": "Libpng",
1495 "fullName": "Zope Public License 2.1",
1344 "url": "http://spdx.org/licenses/Libpng.html"
1496 "shortName": "zpl21",
1497 "spdxId": "ZPL-2.1",
1498 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1345 }
1499 }
1346 ],
1500 ],
1347 "name": "python2.7-pysqlite-2.8.3"
1501 "name": "python2.7-repoze.sendmail-4.4.1"
1348 },
1502 },
1349 {
1503 {
1350 "license": {
1504 "license": {
1351 "fullName": "Repoze License",
1505 "fullName": "Repoze License",
1352 "url": "http://www.repoze.org/LICENSE.txt"
1506 "url": "http://www.repoze.org/LICENSE.txt"
1353 },
1507 },
1354 "name": "python2.7-pyramid-1.9.2"
1508 "name": "python2.7-pyramid-1.10.1"
1355 },
1356 {
1357 "license": [
1358 {
1359 "fullName": "MIT License",
1360 "shortName": "mit",
1361 "spdxId": "MIT",
1362 "url": "http://spdx.org/licenses/MIT.html"
1363 }
1364 ],
1365 "name": "python2.7-hupper-1.3"
1366 },
1509 },
1367 {
1510 {
1368 "license": [
1511 "license": [
@@ -1395,7 +1538,18 b''
1395 "url": "http://spdx.org/licenses/MIT.html"
1538 "url": "http://spdx.org/licenses/MIT.html"
1396 }
1539 }
1397 ],
1540 ],
1398 "name": "python2.7-pastedeploy-1.5.2"
1541 "name": "python2.7-pastedeploy-2.0.1"
1542 },
1543 {
1544 "license": [
1545 {
1546 "fullName": "MIT License",
1547 "shortName": "mit",
1548 "spdxId": "MIT",
1549 "url": "http://spdx.org/licenses/MIT.html"
1550 }
1551 ],
1552 "name": "python2.7-hupper-1.5"
1399 },
1553 },
1400 {
1554 {
1401 "license": {
1555 "license": {
@@ -1428,18 +1582,7 b''
1428 "url": "http://www.repoze.org/LICENSE.txt"
1582 "url": "http://www.repoze.org/LICENSE.txt"
1429 }
1583 }
1430 ],
1584 ],
1431 "name": "python2.7-pyramid-debugtoolbar-4.4"
1585 "name": "python2.7-pyramid-debugtoolbar-4.5"
1432 },
1433 {
1434 "license": [
1435 {
1436 "fullName": "Python Software Foundation License version 2",
1437 "shortName": "psfl",
1438 "spdxId": "Python-2.0",
1439 "url": "http://spdx.org/licenses/Python-2.0.html"
1440 }
1441 ],
1442 "name": "python2.7-ipaddress-1.0.22"
1443 },
1586 },
1444 {
1587 {
1445 "license": {
1588 "license": {
@@ -1468,29 +1611,16 b''
1468 "url": "http://spdx.org/licenses/MIT.html"
1611 "url": "http://spdx.org/licenses/MIT.html"
1469 }
1612 }
1470 ],
1613 ],
1471 "name": "python2.7-pyparsing-1.5.7"
1614 "name": "python2.7-pyparsing-2.3.0"
1472 },
1615 },
1473 {
1616 {
1474 "license": [
1617 "license": [
1475 {
1618 {
1476 "fullName": "Apache License 2.0",
1619 "fullName": "Public Domain",
1477 "shortName": "asl20",
1620 "shortName": "publicDomain"
1478 "spdxId": "Apache-2.0",
1479 "url": "http://spdx.org/licenses/Apache-2.0.html"
1480 }
1621 }
1481 ],
1622 ],
1482 "name": "python2.7-pygments-markdown-lexer-0.1.0.dev39"
1623 "name": "python2.7-pycrypto-2.6.1"
1483 },
1484 {
1485 "license": [
1486 {
1487 "fullName": "MIT License",
1488 "shortName": "mit",
1489 "spdxId": "MIT",
1490 "url": "http://spdx.org/licenses/MIT.html"
1491 }
1492 ],
1493 "name": "python2.7-pyflakes-0.8.1"
1494 },
1624 },
1495 {
1625 {
1496 "license": {
1626 "license": {
@@ -1513,30 +1643,12 b''
1513 "name": "python2.7-py-bcrypt-0.4"
1643 "name": "python2.7-py-bcrypt-0.4"
1514 },
1644 },
1515 {
1645 {
1516 "license": {
1517 "fullName": "GNU Lesser General Public License v3.0 or later",
1518 "shortName": "lgpl3Plus",
1519 "spdxId": "LGPL-3.0+",
1520 "url": "http://spdx.org/licenses/LGPL-3.0+.html"
1521 },
1522 "name": "python2.7-psycopg2-2.7.4"
1523 },
1524 {
1525 "license": {
1526 "fullName": "PostgreSQL License",
1527 "shortName": "postgresql",
1528 "spdxId": "PostgreSQL",
1529 "url": "http://spdx.org/licenses/PostgreSQL.html"
1530 },
1531 "name": "postgresql-9.6.10"
1532 },
1533 {
1534 "license": [
1646 "license": [
1535 {
1647 {
1536 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1648 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1537 }
1649 }
1538 ],
1650 ],
1539 "name": "python2.7-peppercorn-0.5"
1651 "name": "python2.7-peppercorn-0.6"
1540 },
1652 },
1541 {
1653 {
1542 "license": [
1654 "license": [
@@ -1547,7 +1659,7 b''
1547 "url": "http://spdx.org/licenses/MIT.html"
1659 "url": "http://spdx.org/licenses/MIT.html"
1548 }
1660 }
1549 ],
1661 ],
1550 "name": "python2.7-pastescript-2.0.2"
1662 "name": "python2.7-pastescript-3.0.0"
1551 },
1663 },
1552 {
1664 {
1553 "license": [
1665 "license": [
@@ -1569,60 +1681,7 b''
1569 "url": "http://spdx.org/licenses/MIT.html"
1681 "url": "http://spdx.org/licenses/MIT.html"
1570 }
1682 }
1571 ],
1683 ],
1572 "name": "python2.7-objgraph-3.1.1"
1684 "name": "python2.7-pyotp-2.2.7"
1573 },
1574 {
1575 "license": [
1576 {
1577 "fullName": "MIT License",
1578 "shortName": "mit",
1579 "spdxId": "MIT",
1580 "url": "http://spdx.org/licenses/MIT.html"
1581 }
1582 ],
1583 "name": "python2.7-graphviz-0.9"
1584 },
1585 {
1586 "license": [
1587 {
1588 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1589 "shortName": "bsdOriginal",
1590 "spdxId": "BSD-4-Clause",
1591 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1592 }
1593 ],
1594 "name": "python2.7-pyotp-2.2.6"
1595 },
1596 {
1597 "license": [
1598 {
1599 "fullName": "MIT License",
1600 "shortName": "mit",
1601 "spdxId": "MIT",
1602 "url": "http://spdx.org/licenses/MIT.html"
1603 }
1604 ],
1605 "name": "python2.7-pymysql-0.8.1"
1606 },
1607 {
1608 "license": [
1609 {
1610 "fullName": "GNU General Public License v1.0 only",
1611 "shortName": "gpl1",
1612 "spdxId": "GPL-1.0",
1613 "url": "http://spdx.org/licenses/GPL-1.0.html"
1614 }
1615 ],
1616 "name": "python2.7-mysql-python-1.2.5"
1617 },
1618 {
1619 "license": {
1620 "fullName": "GNU Library General Public License v2.1 only",
1621 "shortName": "lgpl21",
1622 "spdxId": "LGPL-2.1",
1623 "url": "http://spdx.org/licenses/LGPL-2.1.html"
1624 },
1625 "name": "mariadb-connector-c-2.3.4"
1626 },
1685 },
1627 {
1686 {
1628 "license": [
1687 "license": [
@@ -1644,29 +1703,7 b''
1644 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1703 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1645 }
1704 }
1646 ],
1705 ],
1647 "name": "python2.7-lxml-3.7.3"
1706 "name": "python2.7-kombu-4.2.1"
1648 },
1649 {
1650 "license": [
1651 {
1652 "fullName": "MIT License",
1653 "shortName": "mit",
1654 "spdxId": "MIT",
1655 "url": "http://spdx.org/licenses/MIT.html"
1656 }
1657 ],
1658 "name": "python2.7-wheel-0.30.0"
1659 },
1660 {
1661 "license": [
1662 {
1663 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1664 "shortName": "bsdOriginal",
1665 "spdxId": "BSD-4-Clause",
1666 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1667 }
1668 ],
1669 "name": "python2.7-kombu-4.2.0"
1670 },
1707 },
1671 {
1708 {
1672 "license": [
1709 "license": [
@@ -1688,18 +1725,7 b''
1688 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1725 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1689 }
1726 }
1690 ],
1727 ],
1691 "name": "python2.7-vine-1.1.4"
1728 "name": "python2.7-vine-1.2.0"
1692 },
1693 {
1694 "license": [
1695 {
1696 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1697 "shortName": "bsdOriginal",
1698 "spdxId": "BSD-4-Clause",
1699 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1700 }
1701 ],
1702 "name": "python2.7-billiard-3.5.0.3"
1703 },
1729 },
1704 {
1730 {
1705 "license": [
1731 "license": [
@@ -1721,7 +1747,7 b''
1721 "url": "http://spdx.org/licenses/MIT.html"
1747 "url": "http://spdx.org/licenses/MIT.html"
1722 }
1748 }
1723 ],
1749 ],
1724 "name": "python2.7-iso8601-0.1.11"
1750 "name": "python2.7-iso8601-0.1.12"
1725 },
1751 },
1726 {
1752 {
1727 "license": [
1753 "license": [
@@ -1765,7 +1791,7 b''
1765 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1791 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1766 }
1792 }
1767 ],
1793 ],
1768 "name": "python2.7-dogpile.cache-0.6.6"
1794 "name": "python2.7-dogpile.cache-0.7.1"
1769 },
1795 },
1770 {
1796 {
1771 "license": {
1797 "license": {
@@ -1779,17 +1805,20 b''
1779 {
1805 {
1780 "license": [
1806 "license": [
1781 {
1807 {
1808 "fullName": "Repoze Public License"
1809 },
1810 {
1782 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1811 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1783 }
1812 }
1784 ],
1813 ],
1785 "name": "python2.7-deform-2.0.5"
1814 "name": "python2.7-deform-2.0.7"
1786 },
1815 },
1787 {
1816 {
1788 "license": {
1817 "license": {
1789 "fullName": "Repoze License",
1818 "fullName": "Repoze License",
1790 "url": "http://www.repoze.org/LICENSE.txt"
1819 "url": "http://www.repoze.org/LICENSE.txt"
1791 },
1820 },
1792 "name": "python2.7-colander-1.4"
1821 "name": "python2.7-colander-1.7.0"
1793 },
1822 },
1794 {
1823 {
1795 "license": [
1824 "license": [
@@ -1863,6 +1892,17 b''
1863 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1892 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1864 }
1893 }
1865 ],
1894 ],
1895 "name": "python2.7-billiard-3.5.0.3"
1896 },
1897 {
1898 "license": [
1899 {
1900 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1901 "shortName": "bsdOriginal",
1902 "spdxId": "BSD-4-Clause",
1903 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1904 }
1905 ],
1866 "name": "python2.7-babel-1.3"
1906 "name": "python2.7-babel-1.3"
1867 },
1907 },
1868 {
1908 {
@@ -1877,25 +1917,7 b''
1877 "name": "python2.7-authomatic-0.1.0.post1"
1917 "name": "python2.7-authomatic-0.1.0.post1"
1878 },
1918 },
1879 {
1919 {
1880 "license": [
1920 "license": "UNKNOWN",
1881 {
1882 "fullName": "MIT License",
1883 "shortName": "mit",
1884 "spdxId": "MIT",
1885 "url": "http://spdx.org/licenses/MIT.html"
1886 }
1887 ],
1888 "name": "node-grunt-cli-1.2.0"
1889 },
1890 {
1891 "license": [
1892 {
1893 "fullName": "MIT License",
1894 "shortName": "mit",
1895 "spdxId": "MIT",
1896 "url": "http://spdx.org/licenses/MIT.html"
1897 }
1898 ],
1899 "name": "python2.7-rhodecode-testdata-0.10.0"
1921 "name": "python2.7-rhodecode-testdata-0.10.0"
1900 }
1922 }
1901 ]
1923 ]
@@ -250,7 +250,7 b' def includeme(config):'
250
250
251 # Includes which are required. The application would fail without them.
251 # Includes which are required. The application would fail without them.
252 config.include('pyramid_mako')
252 config.include('pyramid_mako')
253 config.include('pyramid_beaker')
253 config.include('rhodecode.lib.rc_beaker')
254 config.include('rhodecode.lib.rc_cache')
254 config.include('rhodecode.lib.rc_cache')
255
255
256 config.include('rhodecode.apps._base.navigation')
256 config.include('rhodecode.apps._base.navigation')
@@ -28,8 +28,8 b' def _pre_push_hook(*args, **kwargs):'
28 [{u'hg_env|git_env': ...,
28 [{u'hg_env|git_env': ...,
29 u'multiple_heads': [],
29 u'multiple_heads': [],
30 u'name': u'default',
30 u'name': u'default',
31 u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
31 u'new_rev': u'd0b2ae0692e722e01d5677f27a104631cf798b69',
32 u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
32 u'old_rev': u'd0b1ae0692e722e01d5677f27a104631cf798b69',
33 u'ref': u'',
33 u'ref': u'',
34 u'total_commits': 2,
34 u'total_commits': 2,
35 u'type': u'branch'}]
35 u'type': u'branch'}]
@@ -47,13 +47,17 b' def _pre_push_hook(*args, **kwargs):'
47 forbid_files = repo_extra_fields.get('forbid_files_glob', {}).get('field_value')
47 forbid_files = repo_extra_fields.get('forbid_files_glob', {}).get('field_value')
48 forbid_files = aslist(forbid_files)
48 forbid_files = aslist(forbid_files)
49
49
50 # forbid_files = ['*'] # example pattern
51
50 # optionally get bytes limit for a single file, e.g 1024 for 1KB
52 # optionally get bytes limit for a single file, e.g 1024 for 1KB
51 forbid_size_over = repo_extra_fields.get('forbid_size_over', {}).get('field_value')
53 forbid_size_over = repo_extra_fields.get('forbid_size_over', {}).get('field_value')
52 forbid_size_over = int(forbid_size_over or 0)
54 forbid_size_over = int(forbid_size_over or 0)
53
55
56 # forbid_size_over = 1024 # example 1024
57
54 def validate_file_name_and_size(file_data, forbidden_files=None, size_limit=None):
58 def validate_file_name_and_size(file_data, forbidden_files=None, size_limit=None):
55 """
59 """
56 This function validates commited files against some sort of rules.
60 This function validates comited files against some sort of rules.
57 It should return a valid boolean, and a reason for failure
61 It should return a valid boolean, and a reason for failure
58
62
59 file_data =[
63 file_data =[
@@ -87,6 +91,9 b' def _pre_push_hook(*args, **kwargs):'
87
91
88 # validate A(dded) files and size
92 # validate A(dded) files and size
89 if size_limit and operation == 'A':
93 if size_limit and operation == 'A':
94 if 'file_size' in file_data:
95 size = file_data['file_size']
96 else:
90 size = len(file_data['raw_diff'])
97 size = len(file_data['raw_diff'])
91
98
92 reason = 'File {} size of {} bytes exceeds limit {}'.format(
99 reason = 'File {} size of {} bytes exceeds limit {}'.format(
@@ -34,12 +34,51 b' from rhodecode.lib.vcs.backends.hg.diff '
34 from rhodecode.lib.vcs.backends.git.diff import GitDiff
34 from rhodecode.lib.vcs.backends.git.diff import GitDiff
35
35
36
36
37 def get_hg_files(repo, refs):
37 def get_svn_files(repo, vcs_repo, refs):
38 txn_id = refs[0]
39 files = []
40 stdout, stderr = vcs_repo.run_svn_command(
41 ['svnlook', 'changed', repo.repo_full_path, '--transaction', txn_id])
42
43 svn_op_to_rc_op = {
44 'A': 'A',
45 'U': 'M',
46 'D': 'D',
47 }
48
49 for entry in stdout.splitlines():
50 parsed_entry = {
51 'raw_diff': '',
52 'filename': '',
53 'chunks': [],
54 'ops': {},
55 'file_size': 0
56 }
57
58 op = entry[0]
59 path = entry[1:].strip()
60
61 rc_op = svn_op_to_rc_op.get(op) or '?'
62 parsed_entry['filename'] = path
63 parsed_entry['operation'] = rc_op
64
65 if rc_op in ['A', 'M']:
66 stdout, stderr = vcs_repo.run_svn_command(
67 ['svnlook', 'filesize', repo.repo_full_path, path, '--transaction', txn_id])
68 file_size = int(stdout.strip())
69 parsed_entry['file_size'] = file_size
70
71 files.append(parsed_entry)
72
73 return files
74
75
76 def get_hg_files(repo, vcs_repo, refs):
38 files = []
77 files = []
39 return files
78 return files
40
79
41
80
42 def get_git_files(repo, refs):
81 def get_git_files(repo, vcs_repo, refs):
43 files = []
82 files = []
44
83
45 for data in refs:
84 for data in refs:
@@ -57,7 +96,7 b' def get_git_files(repo, refs):'
57 'diff', old_rev, new_rev
96 'diff', old_rev, new_rev
58 ]
97 ]
59
98
60 stdout, stderr = repo.run_git_command(cmd, extra_env=git_env)
99 stdout, stderr = vcs_repo.run_git_command(cmd, extra_env=git_env)
61 vcs_diff = GitDiff(stdout)
100 vcs_diff = GitDiff(stdout)
62
101
63 diff_processor = diffs.DiffProcessor(vcs_diff, format='newdiff')
102 diff_processor = diffs.DiffProcessor(vcs_diff, format='newdiff')
@@ -86,11 +125,14 b' def run(*args, **kwargs):'
86 if vcs_type == 'git':
125 if vcs_type == 'git':
87 for rev_data in kwargs['commit_ids']:
126 for rev_data in kwargs['commit_ids']:
88 new_environ = dict((k, v) for k, v in rev_data['git_env'])
127 new_environ = dict((k, v) for k, v in rev_data['git_env'])
89 files = get_git_files(vcs_repo, kwargs['commit_ids'])
128 files = get_git_files(repo, vcs_repo, kwargs['commit_ids'])
90
129
91 if vcs_type == 'hg':
130 if vcs_type == 'hg':
92 for rev_data in kwargs['commit_ids']:
131 for rev_data in kwargs['commit_ids']:
93 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
132 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
94 files = get_hg_files(vcs_repo, kwargs['commit_ids'])
133 files = get_hg_files(repo, vcs_repo, kwargs['commit_ids'])
134
135 if vcs_type == 'svn':
136 files = get_svn_files(repo, vcs_repo, kwargs['commit_ids'])
95
137
96 return files
138 return files
@@ -402,7 +402,8 b' class RepoIntegrationsView(IntegrationSe'
402 c.rhodecode_db_repo = self.repo
402 c.rhodecode_db_repo = self.repo
403 c.repo_name = self.db_repo.repo_name
403 c.repo_name = self.db_repo.repo_name
404 c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
404 c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
405
405 c.repository_is_user_following = ScmModel().is_following_repo(
406 c.repo_name, self._rhodecode_user.user_id)
406 c.has_origin_repo_read_perm = False
407 c.has_origin_repo_read_perm = False
407 if self.db_repo.fork:
408 if self.db_repo.fork:
408 c.has_origin_repo_read_perm = h.HasRepoPermissionAny(
409 c.has_origin_repo_read_perm = h.HasRepoPermissionAny(
@@ -92,6 +92,9 b' ACTIONS_V1 = {'
92 'repo.commit.comment.delete': {'data': {}},
92 'repo.commit.comment.delete': {'data': {}},
93 'repo.commit.vote': '',
93 'repo.commit.vote': '',
94
94
95 'repo.artifact.add': '',
96 'repo.artifact.delete': '',
97
95 'repo_group.create': {'data': {}},
98 'repo_group.create': {'data': {}},
96 'repo_group.edit': {'old_data': {}},
99 'repo_group.edit': {'old_data': {}},
97 'repo_group.edit.permissions': {},
100 'repo_group.edit.permissions': {},
@@ -2078,8 +2078,7 b' class HasRepoPermissionAny(PermsFunction'
2078 class HasRepoGroupPermissionAny(PermsFunction):
2078 class HasRepoGroupPermissionAny(PermsFunction):
2079 def __call__(self, group_name=None, check_location='', user=None):
2079 def __call__(self, group_name=None, check_location='', user=None):
2080 self.repo_group_name = group_name
2080 self.repo_group_name = group_name
2081 return super(HasRepoGroupPermissionAny, self).__call__(
2081 return super(HasRepoGroupPermissionAny, self).__call__(check_location, user)
2082 check_location, user)
2083
2082
2084 def check_permissions(self, user):
2083 def check_permissions(self, user):
2085 perms = user.permissions
2084 perms = user.permissions
@@ -2095,8 +2094,7 b' class HasRepoGroupPermissionAny(PermsFun'
2095 class HasRepoGroupPermissionAll(PermsFunction):
2094 class HasRepoGroupPermissionAll(PermsFunction):
2096 def __call__(self, group_name=None, check_location='', user=None):
2095 def __call__(self, group_name=None, check_location='', user=None):
2097 self.repo_group_name = group_name
2096 self.repo_group_name = group_name
2098 return super(HasRepoGroupPermissionAll, self).__call__(
2097 return super(HasRepoGroupPermissionAll, self).__call__(check_location, user)
2099 check_location, user)
2100
2098
2101 def check_permissions(self, user):
2099 def check_permissions(self, user):
2102 perms = user.permissions
2100 perms = user.permissions
@@ -2112,8 +2110,7 b' class HasRepoGroupPermissionAll(PermsFun'
2112 class HasUserGroupPermissionAny(PermsFunction):
2110 class HasUserGroupPermissionAny(PermsFunction):
2113 def __call__(self, user_group_name=None, check_location='', user=None):
2111 def __call__(self, user_group_name=None, check_location='', user=None):
2114 self.user_group_name = user_group_name
2112 self.user_group_name = user_group_name
2115 return super(HasUserGroupPermissionAny, self).__call__(
2113 return super(HasUserGroupPermissionAny, self).__call__(check_location, user)
2116 check_location, user)
2117
2114
2118 def check_permissions(self, user):
2115 def check_permissions(self, user):
2119 perms = user.permissions
2116 perms = user.permissions
@@ -2129,8 +2126,7 b' class HasUserGroupPermissionAny(PermsFun'
2129 class HasUserGroupPermissionAll(PermsFunction):
2126 class HasUserGroupPermissionAll(PermsFunction):
2130 def __call__(self, user_group_name=None, check_location='', user=None):
2127 def __call__(self, user_group_name=None, check_location='', user=None):
2131 self.user_group_name = user_group_name
2128 self.user_group_name = user_group_name
2132 return super(HasUserGroupPermissionAll, self).__call__(
2129 return super(HasUserGroupPermissionAll, self).__call__(check_location, user)
2133 check_location, user)
2134
2130
2135 def check_permissions(self, user):
2131 def check_permissions(self, user):
2136 perms = user.permissions
2132 perms = user.permissions
@@ -288,7 +288,6 b' def attach_context_attributes(context, r'
288 """
288 """
289 config = request.registry.settings
289 config = request.registry.settings
290
290
291
292 rc_config = SettingsModel().get_all_settings(cache=True)
291 rc_config = SettingsModel().get_all_settings(cache=True)
293
292
294 context.rhodecode_version = rhodecode.__version__
293 context.rhodecode_version = rhodecode.__version__
@@ -375,15 +374,20 b' def attach_context_attributes(context, r'
375 "sideside": "sideside"
374 "sideside": "sideside"
376 }.get(request.GET.get('diffmode'))
375 }.get(request.GET.get('diffmode'))
377
376
378 if diffmode and diffmode != request.session.get('rc_user_session_attr.diffmode'):
377 is_api = hasattr(request, 'rpc_user')
379 request.session['rc_user_session_attr.diffmode'] = diffmode
380
381 # session settings per user
382 session_attrs = {
378 session_attrs = {
383 # defaults
379 # defaults
384 "clone_url_format": "http",
380 "clone_url_format": "http",
385 "diffmode": "sideside"
381 "diffmode": "sideside"
386 }
382 }
383
384 if not is_api:
385 # don't access pyramid session for API calls
386 if diffmode and diffmode != request.session.get('rc_user_session_attr.diffmode'):
387 request.session['rc_user_session_attr.diffmode'] = diffmode
388
389 # session settings per user
390
387 for k, v in request.session.items():
391 for k, v in request.session.items():
388 pref = 'rc_user_session_attr.'
392 pref = 'rc_user_session_attr.'
389 if k and k.startswith(pref):
393 if k and k.startswith(pref):
@@ -420,8 +424,12 b' def attach_context_attributes(context, r'
420 'extra': {'plugins': {}}
424 'extra': {'plugins': {}}
421 }
425 }
422 # END CONFIG VARS
426 # END CONFIG VARS
427 if is_api:
428 csrf_token = None
429 else:
430 csrf_token = auth.get_csrf_token(session=request.session)
423
431
424 context.csrf_token = auth.get_csrf_token(session=request.session)
432 context.csrf_token = csrf_token
425 context.backends = rhodecode.BACKENDS.keys()
433 context.backends = rhodecode.BACKENDS.keys()
426 context.backends.sort()
434 context.backends.sort()
427 unread_count = 0
435 unread_count = 0
@@ -537,7 +545,7 b' def bootstrap_config(request):'
537
545
538 # allow pyramid lookup in testing
546 # allow pyramid lookup in testing
539 config.include('pyramid_mako')
547 config.include('pyramid_mako')
540 config.include('pyramid_beaker')
548 config.include('rhodecode.lib.rc_beaker')
541 config.include('rhodecode.lib.rc_cache')
549 config.include('rhodecode.lib.rc_cache')
542
550
543 add_events_routes(config)
551 add_events_routes(config)
@@ -375,6 +375,27 b' class DbManage(object):'
375 hgevolve.ui_active = False
375 hgevolve.ui_active = False
376 self.sa.add(hgevolve)
376 self.sa.add(hgevolve)
377
377
378 hgevolve = RhodeCodeUi()
379 hgevolve.ui_section = 'experimental'
380 hgevolve.ui_key = 'evolution'
381 hgevolve.ui_value = ''
382 hgevolve.ui_active = False
383 self.sa.add(hgevolve)
384
385 hgevolve = RhodeCodeUi()
386 hgevolve.ui_section = 'experimental'
387 hgevolve.ui_key = 'evolution.exchange'
388 hgevolve.ui_value = ''
389 hgevolve.ui_active = False
390 self.sa.add(hgevolve)
391
392 hgevolve = RhodeCodeUi()
393 hgevolve.ui_section = 'extensions'
394 hgevolve.ui_key = 'topic'
395 hgevolve.ui_value = ''
396 hgevolve.ui_active = False
397 self.sa.add(hgevolve)
398
378 # enable hggit disabled by default
399 # enable hggit disabled by default
379 hggit = RhodeCodeUi()
400 hggit = RhodeCodeUi()
380 hggit.ui_section = 'extensions'
401 hggit.ui_section = 'extensions'
@@ -464,9 +485,6 b' class DbManage(object):'
464 self.populate_default_permissions()
485 self.populate_default_permissions()
465 return fixed
486 return fixed
466
487
467 def update_repo_info(self):
468 RepoModel.update_repoinfo()
469
470 def config_prompt(self, test_repo_path='', retries=3):
488 def config_prompt(self, test_repo_path='', retries=3):
471 defaults = self.cli_args
489 defaults = self.cli_args
472 _path = defaults.get('repos_location')
490 _path = defaults.get('repos_location')
@@ -614,7 +614,7 b' class Repository(Base, BaseModel):'
614 if (cs_cache != self.changeset_cache or not self.changeset_cache):
614 if (cs_cache != self.changeset_cache or not self.changeset_cache):
615 _default = datetime.datetime.fromtimestamp(0)
615 _default = datetime.datetime.fromtimestamp(0)
616 last_change = cs_cache.get('date') or _default
616 last_change = cs_cache.get('date') or _default
617 log.debug('updated repo %s with new cs cache %s', self.repo_name, cs_cache)
617 log.debug('updated repo %s with new commit cache %s', self.repo_name, cs_cache)
618 self.updated_on = last_change
618 self.updated_on = last_change
619 self.changeset_cache = cs_cache
619 self.changeset_cache = cs_cache
620 Session().add(self)
620 Session().add(self)
@@ -38,8 +38,6 b' from sqlalchemy.orm import relationship,'
38 from sqlalchemy.exc import OperationalError
38 from sqlalchemy.exc import OperationalError
39 from beaker.cache import cache_region, region_invalidate
39 from beaker.cache import cache_region, region_invalidate
40 from webob.exc import HTTPNotFound
40 from webob.exc import HTTPNotFound
41 from Crypto.Cipher import AES
42 from Crypto import Random
43 from zope.cachedescriptors.property import Lazy as LazyProperty
41 from zope.cachedescriptors.property import Lazy as LazyProperty
44
42
45 from rhodecode.translation import _
43 from rhodecode.translation import _
@@ -2164,7 +2164,7 b' class Repository(Base, BaseModel):'
2164 if is_outdated(cs_cache) or not self.changeset_cache:
2164 if is_outdated(cs_cache) or not self.changeset_cache:
2165 _default = datetime.datetime.fromtimestamp(0)
2165 _default = datetime.datetime.fromtimestamp(0)
2166 last_change = cs_cache.get('date') or _default
2166 last_change = cs_cache.get('date') or _default
2167 log.debug('updated repo %s with new cs cache %s',
2167 log.debug('updated repo %s with new commit cache %s',
2168 self.repo_name, cs_cache)
2168 self.repo_name, cs_cache)
2169 self.updated_on = last_change
2169 self.updated_on = last_change
2170 self.changeset_cache = cs_cache
2170 self.changeset_cache = cs_cache
@@ -2230,7 +2230,7 b' class Repository(Base, BaseModel):'
2230 if is_outdated(cs_cache) or not self.changeset_cache:
2230 if is_outdated(cs_cache) or not self.changeset_cache:
2231 _default = datetime.datetime.fromtimestamp(0)
2231 _default = datetime.datetime.fromtimestamp(0)
2232 last_change = cs_cache.get('date') or _default
2232 last_change = cs_cache.get('date') or _default
2233 log.debug('updated repo %s with new cs cache %s',
2233 log.debug('updated repo %s with new commit cache %s',
2234 self.repo_name, cs_cache)
2234 self.repo_name, cs_cache)
2235 self.updated_on = last_change
2235 self.updated_on = last_change
2236 self.changeset_cache = cs_cache
2236 self.changeset_cache = cs_cache
@@ -2278,7 +2278,7 b' class Repository(Base, BaseModel):'
2278 # if yes, we use the current timestamp instead. Imagine you get
2278 # if yes, we use the current timestamp instead. Imagine you get
2279 # old commit pushed 1y ago, we'd set last update 1y to ago.
2279 # old commit pushed 1y ago, we'd set last update 1y to ago.
2280 last_change = _default
2280 last_change = _default
2281 log.debug('updated repo %s with new cs cache %s',
2281 log.debug('updated repo %s with new commit cache %s',
2282 self.repo_name, cs_cache)
2282 self.repo_name, cs_cache)
2283 self.updated_on = last_change
2283 self.updated_on = last_change
2284 self.changeset_cache = cs_cache
2284 self.changeset_cache = cs_cache
@@ -2301,7 +2301,7 b' class Repository(Base, BaseModel):'
2301 # if yes, we use the current timestamp instead. Imagine you get
2301 # if yes, we use the current timestamp instead. Imagine you get
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2303 last_change = _default
2303 last_change = _default
2304 log.debug('updated repo %s with new cs cache %s',
2304 log.debug('updated repo %s with new commit cache %s',
2305 self.repo_name, cs_cache)
2305 self.repo_name, cs_cache)
2306 self.updated_on = last_change
2306 self.updated_on = last_change
2307 self.changeset_cache = cs_cache
2307 self.changeset_cache = cs_cache
@@ -2301,7 +2301,7 b' class Repository(Base, BaseModel):'
2301 # if yes, we use the current timestamp instead. Imagine you get
2301 # if yes, we use the current timestamp instead. Imagine you get
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2303 last_change = _default
2303 last_change = _default
2304 log.debug('updated repo %s with new cs cache %s',
2304 log.debug('updated repo %s with new commit cache %s',
2305 self.repo_name, cs_cache)
2305 self.repo_name, cs_cache)
2306 self.updated_on = last_change
2306 self.updated_on = last_change
2307 self.changeset_cache = cs_cache
2307 self.changeset_cache = cs_cache
@@ -1865,7 +1865,7 b' class Repository(Base, BaseModel):'
1865 if is_outdated(cs_cache) or not self.changeset_cache:
1865 if is_outdated(cs_cache) or not self.changeset_cache:
1866 _default = datetime.datetime.fromtimestamp(0)
1866 _default = datetime.datetime.fromtimestamp(0)
1867 last_change = cs_cache.get('date') or _default
1867 last_change = cs_cache.get('date') or _default
1868 log.debug('updated repo %s with new cs cache %s',
1868 log.debug('updated repo %s with new commit cache %s',
1869 self.repo_name, cs_cache)
1869 self.repo_name, cs_cache)
1870 self.updated_on = last_change
1870 self.updated_on = last_change
1871 self.changeset_cache = cs_cache
1871 self.changeset_cache = cs_cache
@@ -1868,7 +1868,7 b' class Repository(Base, BaseModel):'
1868 if is_outdated(cs_cache) or not self.changeset_cache:
1868 if is_outdated(cs_cache) or not self.changeset_cache:
1869 _default = datetime.datetime.fromtimestamp(0)
1869 _default = datetime.datetime.fromtimestamp(0)
1870 last_change = cs_cache.get('date') or _default
1870 last_change = cs_cache.get('date') or _default
1871 log.debug('updated repo %s with new cs cache %s',
1871 log.debug('updated repo %s with new commit cache %s',
1872 self.repo_name, cs_cache)
1872 self.repo_name, cs_cache)
1873 self.updated_on = last_change
1873 self.updated_on = last_change
1874 self.changeset_cache = cs_cache
1874 self.changeset_cache = cs_cache
@@ -1867,7 +1867,7 b' class Repository(Base, BaseModel):'
1867 if is_outdated(cs_cache) or not self.changeset_cache:
1867 if is_outdated(cs_cache) or not self.changeset_cache:
1868 _default = datetime.datetime.fromtimestamp(0)
1868 _default = datetime.datetime.fromtimestamp(0)
1869 last_change = cs_cache.get('date') or _default
1869 last_change = cs_cache.get('date') or _default
1870 log.debug('updated repo %s with new cs cache %s',
1870 log.debug('updated repo %s with new commit cache %s',
1871 self.repo_name, cs_cache)
1871 self.repo_name, cs_cache)
1872 self.updated_on = last_change
1872 self.updated_on = last_change
1873 self.changeset_cache = cs_cache
1873 self.changeset_cache = cs_cache
@@ -1869,7 +1869,7 b' class Repository(Base, BaseModel):'
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1870 _default = datetime.datetime.fromtimestamp(0)
1870 _default = datetime.datetime.fromtimestamp(0)
1871 last_change = cs_cache.get('date') or _default
1871 last_change = cs_cache.get('date') or _default
1872 log.debug('updated repo %s with new cs cache %s',
1872 log.debug('updated repo %s with new commit cache %s',
1873 self.repo_name, cs_cache)
1873 self.repo_name, cs_cache)
1874 self.updated_on = last_change
1874 self.updated_on = last_change
1875 self.changeset_cache = cs_cache
1875 self.changeset_cache = cs_cache
@@ -1869,7 +1869,7 b' class Repository(Base, BaseModel):'
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1870 _default = datetime.datetime.fromtimestamp(0)
1870 _default = datetime.datetime.fromtimestamp(0)
1871 last_change = cs_cache.get('date') or _default
1871 last_change = cs_cache.get('date') or _default
1872 log.debug('updated repo %s with new cs cache %s',
1872 log.debug('updated repo %s with new commit cache %s',
1873 self.repo_name, cs_cache)
1873 self.repo_name, cs_cache)
1874 self.updated_on = last_change
1874 self.updated_on = last_change
1875 self.changeset_cache = cs_cache
1875 self.changeset_cache = cs_cache
@@ -1912,7 +1912,7 b' class Repository(Base, BaseModel):'
1912 if is_outdated(cs_cache) or not self.changeset_cache:
1912 if is_outdated(cs_cache) or not self.changeset_cache:
1913 _default = datetime.datetime.fromtimestamp(0)
1913 _default = datetime.datetime.fromtimestamp(0)
1914 last_change = cs_cache.get('date') or _default
1914 last_change = cs_cache.get('date') or _default
1915 log.debug('updated repo %s with new cs cache %s',
1915 log.debug('updated repo %s with new commit cache %s',
1916 self.repo_name, cs_cache)
1916 self.repo_name, cs_cache)
1917 self.updated_on = last_change
1917 self.updated_on = last_change
1918 self.changeset_cache = cs_cache
1918 self.changeset_cache = cs_cache
@@ -1913,7 +1913,7 b' class Repository(Base, BaseModel):'
1913 if is_outdated(cs_cache) or not self.changeset_cache:
1913 if is_outdated(cs_cache) or not self.changeset_cache:
1914 _default = datetime.datetime.fromtimestamp(0)
1914 _default = datetime.datetime.fromtimestamp(0)
1915 last_change = cs_cache.get('date') or _default
1915 last_change = cs_cache.get('date') or _default
1916 log.debug('updated repo %s with new cs cache %s',
1916 log.debug('updated repo %s with new commit cache %s',
1917 self.repo_name, cs_cache)
1917 self.repo_name, cs_cache)
1918 self.updated_on = last_change
1918 self.updated_on = last_change
1919 self.changeset_cache = cs_cache
1919 self.changeset_cache = cs_cache
@@ -2100,7 +2100,7 b' class Repository(Base, BaseModel):'
2100 if is_outdated(cs_cache) or not self.changeset_cache:
2100 if is_outdated(cs_cache) or not self.changeset_cache:
2101 _default = datetime.datetime.fromtimestamp(0)
2101 _default = datetime.datetime.fromtimestamp(0)
2102 last_change = cs_cache.get('date') or _default
2102 last_change = cs_cache.get('date') or _default
2103 log.debug('updated repo %s with new cs cache %s',
2103 log.debug('updated repo %s with new commit cache %s',
2104 self.repo_name, cs_cache)
2104 self.repo_name, cs_cache)
2105 self.updated_on = last_change
2105 self.updated_on = last_change
2106 self.changeset_cache = cs_cache
2106 self.changeset_cache = cs_cache
@@ -111,4 +111,28 b' class AESCipher(object):'
111
111
112 @staticmethod
112 @staticmethod
113 def _unpad(s):
113 def _unpad(s):
114 return s[:-ord(s[len(s)-1:])] No newline at end of file
114 return s[:-ord(s[len(s)-1:])]
115
116
117 def validate_and_get_enc_data(enc_data, enc_key, enc_strict_mode):
118 parts = enc_data.split('$', 3)
119 if not len(parts) == 3:
120 # probably not encrypted values
121 return enc_data
122 else:
123 if parts[0] != 'enc':
124 # parts ok but without our header ?
125 return enc_data
126
127 # at that stage we know it's our encryption
128 if parts[1] == 'aes':
129 decrypted_data = AESCipher(enc_key).decrypt(parts[2])
130 elif parts[1] == 'aes_hmac':
131 decrypted_data = AESCipher(
132 enc_key, hmac=True,
133 strict_verification=enc_strict_mode).decrypt(parts[2])
134 else:
135 raise ValueError(
136 'Encryption type part is wrong, must be `aes` '
137 'or `aes_hmac`, got `%s` instead' % (parts[1]))
138 return decrypted_data
@@ -199,6 +199,7 b' class _GetError(object):'
199 if form_errors and field_name in form_errors:
199 if form_errors and field_name in form_errors:
200 return literal(tmpl % form_errors.get(field_name))
200 return literal(tmpl % form_errors.get(field_name))
201
201
202
202 get_error = _GetError()
203 get_error = _GetError()
203
204
204
205
@@ -214,38 +215,45 b' class _ToolTip(object):'
214 tooltip_title = escape(tooltip_title)
215 tooltip_title = escape(tooltip_title)
215 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
216 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
216 return tooltip_title
217 return tooltip_title
218
219
217 tooltip = _ToolTip()
220 tooltip = _ToolTip()
218
221
222 files_icon = u'<i class="file-breadcrumb-copy tooltip icon-clipboard clipboard-action" data-clipboard-text="{}" title="Copy the full path"></i>'
219
223
220 def files_breadcrumbs(repo_name, commit_id, file_path):
224
225 def files_breadcrumbs(repo_name, commit_id, file_path, at_ref=None, limit_items=False, linkify_last_item=False):
221 if isinstance(file_path, str):
226 if isinstance(file_path, str):
222 file_path = safe_unicode(file_path)
227 file_path = safe_unicode(file_path)
223
228
224 # TODO: johbo: Is this always a url like path, or is this operating
229 route_qry = {'at': at_ref} if at_ref else None
225 # system dependent?
226 path_segments = file_path.split('/')
227
230
228 repo_name_html = escape(repo_name)
231 # first segment is a `..` link to repo files
229 if len(path_segments) == 1 and path_segments[0] == '':
232 root_name = literal(u'<i class="icon-home"></i>')
230 url_segments = [repo_name_html]
231 else:
232 url_segments = [
233 url_segments = [
233 link_to(
234 link_to(
234 repo_name_html,
235 root_name,
235 route_path(
236 route_path(
236 'repo_files',
237 'repo_files',
237 repo_name=repo_name,
238 repo_name=repo_name,
238 commit_id=commit_id,
239 commit_id=commit_id,
239 f_path=''),
240 f_path='',
240 class_='pjax-link')]
241 _query=route_qry),
242 )]
241
243
244 path_segments = file_path.split('/')
242 last_cnt = len(path_segments) - 1
245 last_cnt = len(path_segments) - 1
243 for cnt, segment in enumerate(path_segments):
246 for cnt, segment in enumerate(path_segments):
244 if not segment:
247 if not segment:
245 continue
248 continue
246 segment_html = escape(segment)
249 segment_html = escape(segment)
247
250
248 if cnt != last_cnt:
251 last_item = cnt == last_cnt
252
253 if last_item and linkify_last_item is False:
254 # plain version
255 url_segments.append(segment_html)
256 else:
249 url_segments.append(
257 url_segments.append(
250 link_to(
258 link_to(
251 segment_html,
259 segment_html,
@@ -253,12 +261,32 b' def files_breadcrumbs(repo_name, commit_'
253 'repo_files',
261 'repo_files',
254 repo_name=repo_name,
262 repo_name=repo_name,
255 commit_id=commit_id,
263 commit_id=commit_id,
256 f_path='/'.join(path_segments[:cnt + 1])),
264 f_path='/'.join(path_segments[:cnt + 1]),
257 class_='pjax-link'))
265 _query=route_qry),
266 ))
267
268 limited_url_segments = url_segments[:1] + ['...'] + url_segments[-5:]
269 if limit_items and len(limited_url_segments) < len(url_segments):
270 url_segments = limited_url_segments
271
272 full_path = file_path
273 icon = files_icon.format(escape(full_path))
274 if file_path == '':
275 return root_name
258 else:
276 else:
259 url_segments.append(segment_html)
277 return literal(' / '.join(url_segments) + icon)
278
279
280 def files_url_data(request):
281 matchdict = request.matchdict
260
282
261 return literal('/'.join(url_segments))
283 if 'f_path' not in matchdict:
284 matchdict['f_path'] = ''
285
286 if 'commit_id' not in matchdict:
287 matchdict['commit_id'] = 'tip'
288
289 return json.dumps(matchdict)
262
290
263
291
264 def code_highlight(code, lexer, formatter, use_hl_filter=False):
292 def code_highlight(code, lexer, formatter, use_hl_filter=False):
@@ -1196,7 +1224,7 b' class InitialsGravatar(object):'
1196 </text>
1224 </text>
1197 </svg>""".format(
1225 </svg>""".format(
1198 size=self.size,
1226 size=self.size,
1199 f_size=self.size/1.85, # scale the text inside the box nicely
1227 f_size=self.size/2.05, # scale the text inside the box nicely
1200 background=self.background,
1228 background=self.background,
1201 text_color=self.text_color,
1229 text_color=self.text_color,
1202 text=initials.upper(),
1230 text=initials.upper(),
@@ -1486,10 +1514,12 b' def breadcrumb_repo_link(repo):'
1486 """
1514 """
1487
1515
1488 path = [
1516 path = [
1489 link_to(group.name, route_path('repo_group_home', repo_group_name=group.group_name))
1517 link_to(group.name, route_path('repo_group_home', repo_group_name=group.group_name),
1518 title='last change:{}'.format(format_date(group.last_commit_change)))
1490 for group in repo.groups_with_parents
1519 for group in repo.groups_with_parents
1491 ] + [
1520 ] + [
1492 link_to(repo.just_name, route_path('repo_summary', repo_name=repo.repo_name))
1521 link_to(repo.just_name, route_path('repo_summary', repo_name=repo.repo_name),
1522 title='last change:{}'.format(format_date(repo.last_commit_change)))
1493 ]
1523 ]
1494
1524
1495 return literal(' &raquo; '.join(path))
1525 return literal(' &raquo; '.join(path))
@@ -1507,11 +1537,13 b' def breadcrumb_repo_group_link(repo_grou'
1507
1537
1508 path = [
1538 path = [
1509 link_to(group.name,
1539 link_to(group.name,
1510 route_path('repo_group_home', repo_group_name=group.group_name))
1540 route_path('repo_group_home', repo_group_name=group.group_name),
1541 title='last change:{}'.format(format_date(group.last_commit_change)))
1511 for group in repo_group.parents
1542 for group in repo_group.parents
1512 ] + [
1543 ] + [
1513 link_to(repo_group.name,
1544 link_to(repo_group.name,
1514 route_path('repo_group_home', repo_group_name=repo_group.group_name))
1545 route_path('repo_group_home', repo_group_name=repo_group.group_name),
1546 title='last change:{}'.format(format_date(repo_group.last_commit_change)))
1515 ]
1547 ]
1516
1548
1517 return literal(' &raquo; '.join(path))
1549 return literal(' &raquo; '.join(path))
@@ -1907,23 +1939,26 b' def secure_form(form_url, method="POST",'
1907
1939
1908 def dropdownmenu(name, selected, options, enable_filter=False, **attrs):
1940 def dropdownmenu(name, selected, options, enable_filter=False, **attrs):
1909 select_html = select(name, selected, options, **attrs)
1941 select_html = select(name, selected, options, **attrs)
1942
1910 select2 = """
1943 select2 = """
1911 <script>
1944 <script>
1912 $(document).ready(function() {
1945 $(document).ready(function() {
1913 $('#%s').select2({
1946 $('#%s').select2({
1914 containerCssClass: 'drop-menu',
1947 containerCssClass: 'drop-menu %s',
1915 dropdownCssClass: 'drop-menu-dropdown',
1948 dropdownCssClass: 'drop-menu-dropdown',
1916 dropdownAutoWidth: true%s
1949 dropdownAutoWidth: true%s
1917 });
1950 });
1918 });
1951 });
1919 </script>
1952 </script>
1920 """
1953 """
1954
1921 filter_option = """,
1955 filter_option = """,
1922 minimumResultsForSearch: -1
1956 minimumResultsForSearch: -1
1923 """
1957 """
1924 input_id = attrs.get('id') or name
1958 input_id = attrs.get('id') or name
1959 extra_classes = ' '.join(attrs.pop('extra_classes', []))
1925 filter_enabled = "" if enable_filter else filter_option
1960 filter_enabled = "" if enable_filter else filter_option
1926 select_script = literal(select2 % (input_id, filter_enabled))
1961 select_script = literal(select2 % (input_id, extra_classes, filter_enabled))
1927
1962
1928 return literal(select_html+select_script)
1963 return literal(select_html+select_script)
1929
1964
@@ -1944,7 +1979,7 b' def get_visual_attr(tmpl_context_var, at'
1944
1979
1945 def get_last_path_part(file_node):
1980 def get_last_path_part(file_node):
1946 if not file_node.path:
1981 if not file_node.path:
1947 return u''
1982 return u'/'
1948
1983
1949 path = safe_unicode(file_node.path.split('/')[-1])
1984 path = safe_unicode(file_node.path.split('/')[-1])
1950 return u'../' + path
1985 return u'../' + path
@@ -2033,10 +2068,11 b' def reviewer_as_json(*args, **kwargs):'
2033 def get_repo_view_type(request):
2068 def get_repo_view_type(request):
2034 route_name = request.matched_route.name
2069 route_name = request.matched_route.name
2035 route_to_view_type = {
2070 route_to_view_type = {
2036 'repo_changelog': 'changelog',
2071 'repo_changelog': 'commits',
2072 'repo_commits': 'commits',
2037 'repo_files': 'files',
2073 'repo_files': 'files',
2038 'repo_summary': 'summary',
2074 'repo_summary': 'summary',
2039 'repo_commit': 'commit'
2075 'repo_commit': 'commit'
2076 }
2040
2077
2041 }
2042 return route_to_view_type.get(route_name)
2078 return route_to_view_type.get(route_name)
@@ -80,7 +80,7 b' def trigger_log_create_pull_request_hook'
80 extras = _get_rc_scm_extras(username, repo_name, repo_alias,
80 extras = _get_rc_scm_extras(username, repo_name, repo_alias,
81 'create_pull_request')
81 'create_pull_request')
82 events.trigger(events.PullRequestCreateEvent(pull_request))
82 events.trigger(events.PullRequestCreateEvent(pull_request))
83 extras.update(pull_request.get_api_data())
83 extras.update(pull_request.get_api_data(with_merge_state=False))
84 hooks_base.log_create_pull_request(**extras)
84 hooks_base.log_create_pull_request(**extras)
85
85
86
86
@@ -80,6 +80,13 b' class BaseSearcher(object):'
80 def extract_search_tags(query):
80 def extract_search_tags(query):
81 return []
81 return []
82
82
83 @staticmethod
84 def escape_specials(val):
85 """
86 Handle and escape reserved chars for search
87 """
88 return val
89
83
90
84 def search_config(config, prefix='search.'):
91 def search_config(config, prefix='search.'):
85 _config = {}
92 _config = {}
@@ -20,7 +20,55 b''
20
20
21 import markdown
21 import markdown
22
22
23 from mdx_gfm import GithubFlavoredMarkdownExtension # pragma: no cover
23 from markdown.extensions import Extension
24 from markdown.extensions.fenced_code import FencedCodeExtension
25 from markdown.extensions.smart_strong import SmartEmphasisExtension
26 from markdown.extensions.tables import TableExtension
27 from markdown.extensions.nl2br import Nl2BrExtension
28
29 import gfm
30
31
32 class GithubFlavoredMarkdownExtension(Extension):
33 """
34 An extension that is as compatible as possible with GitHub-flavored
35 Markdown (GFM).
36
37 This extension aims to be compatible with the variant of GFM that GitHub
38 uses for Markdown-formatted gists and files (including READMEs). This
39 variant seems to have all the extensions described in the `GFM
40 documentation`_, except:
41
42 - Newlines in paragraphs are not transformed into ``br`` tags.
43 - Intra-GitHub links to commits, repositories, and issues are not
44 supported.
45
46 If you need support for features specific to GitHub comments and issues,
47 please use :class:`mdx_gfm.GithubFlavoredMarkdownExtension`.
48
49 .. _GFM documentation: https://guides.github.com/features/mastering-markdown/
50 """
51
52 def extendMarkdown(self, md, md_globals):
53 # Built-in extensions
54 FencedCodeExtension().extendMarkdown(md, md_globals)
55 SmartEmphasisExtension().extendMarkdown(md, md_globals)
56 TableExtension().extendMarkdown(md, md_globals)
57
58 # Custom extensions
59 gfm.AutolinkExtension().extendMarkdown(md, md_globals)
60 gfm.AutomailExtension().extendMarkdown(md, md_globals)
61 gfm.HiddenHiliteExtension([
62 ('guess_lang', 'False'),
63 ('css_class', 'highlight')
64 ]).extendMarkdown(md, md_globals)
65 gfm.SemiSaneListExtension().extendMarkdown(md, md_globals)
66 gfm.SpacedLinkExtension().extendMarkdown(md, md_globals)
67 gfm.StrikethroughExtension().extendMarkdown(md, md_globals)
68 gfm.TaskListExtension([
69 ('list_attrs', {'class': 'checkbox'})
70 ]).extendMarkdown(md, md_globals)
71 Nl2BrExtension().extendMarkdown(md, md_globals)
24
72
25
73
26 # Global Vars
74 # Global Vars
@@ -500,7 +500,6 b' class MarkupRenderer(object):'
500 (body, resources) = html_exporter.from_notebook_node(notebook)
500 (body, resources) = html_exporter.from_notebook_node(notebook)
501 header = '<!-- ## IPYTHON NOTEBOOK RENDERING ## -->'
501 header = '<!-- ## IPYTHON NOTEBOOK RENDERING ## -->'
502 js = MakoTemplate(r'''
502 js = MakoTemplate(r'''
503 <!-- Load mathjax -->
504 <!-- MathJax configuration -->
503 <!-- MathJax configuration -->
505 <script type="text/x-mathjax-config">
504 <script type="text/x-mathjax-config">
506 MathJax.Hub.Config({
505 MathJax.Hub.Config({
@@ -526,12 +525,13 b' class MarkupRenderer(object):'
526 showMathMenu: false
525 showMathMenu: false
527 });
526 });
528 </script>
527 </script>
529 <!-- End of mathjax configuration -->
528 <!-- End of MathJax configuration -->
530 <script src="${h.asset('js/src/math_jax/MathJax.js')}"></script>
529 <script src="${h.asset('js/src/math_jax/MathJax.js')}"></script>
531 ''').render(h=helpers)
530 ''').render(h=helpers)
532
531
533 css = '<style>{}</style>'.format(
532 css = MakoTemplate(r'''
534 ''.join(_sanitize_resources(resources['inlining']['css'])))
533 <link rel="stylesheet" type="text/css" href="${h.asset('css/style-ipython.css', ver=ver)}" media="screen"/>
534 ''').render(h=helpers, ver='ver1')
535
535
536 body = '\n'.join([header, css, js, body])
536 body = '\n'.join([header, css, js, body])
537 return body, resources
537 return body, resources
@@ -142,7 +142,7 b' class SimpleGit(simplevcs.SimpleVCS):'
142 return self.scm_app.create_git_wsgi_app(
142 return self.scm_app.create_git_wsgi_app(
143 repo_path, repo_name, config)
143 repo_path, repo_name, config)
144
144
145 def _create_config(self, extras, repo_name):
145 def _create_config(self, extras, repo_name, scheme='http'):
146 extras['git_update_server_info'] = utils2.str2bool(
146 extras['git_update_server_info'] = utils2.str2bool(
147 rhodecode.CONFIG.get('git_update_server_info'))
147 rhodecode.CONFIG.get('git_update_server_info'))
148
148
@@ -152,4 +152,5 b' class SimpleGit(simplevcs.SimpleVCS):'
152 extras['git_lfs_enabled'] = utils2.str2bool(
152 extras['git_lfs_enabled'] = utils2.str2bool(
153 config.get('vcs_git_lfs', 'enabled'))
153 config.get('vcs_git_lfs', 'enabled'))
154 extras['git_lfs_store_path'] = custom_store or default_lfs_store()
154 extras['git_lfs_store_path'] = custom_store or default_lfs_store()
155 extras['git_lfs_http_scheme'] = scheme
155 return extras
156 return extras
@@ -153,7 +153,7 b' class SimpleHg(simplevcs.SimpleVCS):'
153 def _create_wsgi_app(self, repo_path, repo_name, config):
153 def _create_wsgi_app(self, repo_path, repo_name, config):
154 return self.scm_app.create_hg_wsgi_app(repo_path, repo_name, config)
154 return self.scm_app.create_hg_wsgi_app(repo_path, repo_name, config)
155
155
156 def _create_config(self, extras, repo_name):
156 def _create_config(self, extras, repo_name, scheme='http'):
157 config = utils.make_db_config(repo=repo_name)
157 config = utils.make_db_config(repo=repo_name)
158 config.set('rhodecode', 'RC_SCM_DATA', json.dumps(extras))
158 config.set('rhodecode', 'RC_SCM_DATA', json.dumps(extras))
159
159
@@ -87,20 +87,22 b' class SimpleSvnApp(object):'
87 stream = True
87 stream = True
88
88
89 stream = stream
89 stream = stream
90 log.debug(
90 log.debug('Calling SVN PROXY at `%s`, using method:%s. Stream: %s',
91 'Calling SVN PROXY: method:%s via `%s`, Stream: %s',
91 path_info, req_method, stream)
92 req_method, path_info, stream)
92 try:
93 response = requests.request(
93 response = requests.request(
94 req_method, path_info,
94 req_method, path_info,
95 data=data, headers=request_headers, stream=stream)
95 data=data, headers=request_headers, stream=stream)
96 except requests.ConnectionError:
97 log.exception('ConnectionError occurred for endpoint %s', path_info)
98 raise
96
99
97 if response.status_code not in [200, 401]:
100 if response.status_code not in [200, 401]:
101 text = '\n{}'.format(response.text) if response.text else ''
98 if response.status_code >= 500:
102 if response.status_code >= 500:
99 log.error('Got SVN response:%s with text:\n`%s`',
103 log.error('Got SVN response:%s with text:`%s`', response, text)
100 response, response.text)
101 else:
104 else:
102 log.debug('Got SVN response:%s with text:\n`%s`',
105 log.debug('Got SVN response:%s with text:`%s`', response, text)
103 response, response.text)
104 else:
106 else:
105 log.debug('got response code: %s', response.status_code)
107 log.debug('got response code: %s', response.status_code)
106
108
@@ -217,7 +219,7 b' class SimpleSvn(simplevcs.SimpleVCS):'
217 conf = self.repo_vcs_config
219 conf = self.repo_vcs_config
218 return str2bool(conf.get('vcs_svn_proxy', 'http_requests_enabled'))
220 return str2bool(conf.get('vcs_svn_proxy', 'http_requests_enabled'))
219
221
220 def _create_config(self, extras, repo_name):
222 def _create_config(self, extras, repo_name, scheme='http'):
221 conf = self.repo_vcs_config
223 conf = self.repo_vcs_config
222 server_url = conf.get('vcs_svn_proxy', 'http_server_url')
224 server_url = conf.get('vcs_svn_proxy', 'http_server_url')
223 server_url = server_url or self.DEFAULT_HTTP_SERVER
225 server_url = server_url or self.DEFAULT_HTTP_SERVER
@@ -360,6 +360,13 b' class SimpleVCS(object):'
360
360
361 return perm_result
361 return perm_result
362
362
363 def _get_http_scheme(self, environ):
364 try:
365 return environ['wsgi.url_scheme']
366 except Exception:
367 log.exception('Failed to read http scheme')
368 return 'http'
369
363 def _check_ssl(self, environ, start_response):
370 def _check_ssl(self, environ, start_response):
364 """
371 """
365 Checks the SSL check flag and returns False if SSL is not present
372 Checks the SSL check flag and returns False if SSL is not present
@@ -597,7 +604,9 b' class SimpleVCS(object):'
597 extras, environ, action, txn_id=txn_id)
604 extras, environ, action, txn_id=txn_id)
598 log.debug('HOOKS extras is %s', extras)
605 log.debug('HOOKS extras is %s', extras)
599
606
600 config = self._create_config(extras, self.acl_repo_name)
607 http_scheme = self._get_http_scheme(environ)
608
609 config = self._create_config(extras, self.acl_repo_name, scheme=http_scheme)
601 app = self._create_wsgi_app(repo_path, self.url_repo_name, config)
610 app = self._create_wsgi_app(repo_path, self.url_repo_name, config)
602 with callback_daemon:
611 with callback_daemon:
603 app.rc_extras = extras
612 app.rc_extras = extras
@@ -643,7 +652,7 b' class SimpleVCS(object):'
643 """Return the WSGI app that will finally handle the request."""
652 """Return the WSGI app that will finally handle the request."""
644 raise NotImplementedError()
653 raise NotImplementedError()
645
654
646 def _create_config(self, extras, repo_name):
655 def _create_config(self, extras, repo_name, scheme='http'):
647 """Create a safe config representation."""
656 """Create a safe config representation."""
648 raise NotImplementedError()
657 raise NotImplementedError()
649
658
@@ -23,6 +23,7 b' import re'
23 import time
23 import time
24 import datetime
24 import datetime
25 import dateutil
25 import dateutil
26 import pickle
26
27
27 from rhodecode.model.db import DbSession, Session
28 from rhodecode.model.db import DbSession, Session
28
29
@@ -142,7 +143,6 b' class FileAuthSessions(BaseAuthSessions)'
142 return stats['callbacks']
143 return stats['callbacks']
143
144
144
145
145
146 class MemcachedAuthSessions(BaseAuthSessions):
146 class MemcachedAuthSessions(BaseAuthSessions):
147 SESSION_TYPE = 'ext:memcached'
147 SESSION_TYPE = 'ext:memcached'
148 _key_regex = re.compile(r'ITEM (.*_session) \[(.*); (.*)\]')
148 _key_regex = re.compile(r'ITEM (.*_session) \[(.*); (.*)\]')
@@ -195,6 +195,43 b' class MemcachedAuthSessions(BaseAuthSess'
195 raise CleanupCommand('Cleanup for this session type not yet available')
195 raise CleanupCommand('Cleanup for this session type not yet available')
196
196
197
197
198 class RedisAuthSessions(BaseAuthSessions):
199 SESSION_TYPE = 'ext:redis'
200
201 def _get_client(self):
202 import redis
203 args = {
204 'socket_timeout': 60,
205 'url': self.config.get('beaker.session.url')
206 }
207
208 client = redis.StrictRedis.from_url(**args)
209 return client
210
211 def get_count(self):
212 client = self._get_client()
213 return len(client.keys('beaker_cache:*'))
214
215 def get_expired_count(self, older_than_seconds=None):
216 expiry_date = self._seconds_to_date(older_than_seconds)
217 return self.NOT_AVAILABLE
218
219 def clean_sessions(self, older_than_seconds=None):
220 client = self._get_client()
221 expiry_time = time.time() - older_than_seconds
222 deleted_keys = 0
223 for key in client.keys('beaker_cache:*'):
224 data = client.get(key)
225 if data:
226 json_data = pickle.loads(data)
227 accessed_time = json_data['_accessed_time']
228 if accessed_time < expiry_time:
229 client.delete(key)
230 deleted_keys += 1
231
232 return deleted_keys
233
234
198 class MemoryAuthSessions(BaseAuthSessions):
235 class MemoryAuthSessions(BaseAuthSessions):
199 SESSION_TYPE = 'memory'
236 SESSION_TYPE = 'memory'
200
237
@@ -212,6 +249,7 b' def get_session_handler(session_type):'
212 types = {
249 types = {
213 'file': FileAuthSessions,
250 'file': FileAuthSessions,
214 'ext:memcached': MemcachedAuthSessions,
251 'ext:memcached': MemcachedAuthSessions,
252 'ext:redis': RedisAuthSessions,
215 'ext:database': DbAuthSessions,
253 'ext:database': DbAuthSessions,
216 'memory': MemoryAuthSessions
254 'memory': MemoryAuthSessions
217 }
255 }
@@ -371,7 +371,8 b' def config_data_from_db(clear_session=Tr'
371 config.append((
371 config.append((
372 safe_str(setting.section), safe_str(setting.key), False))
372 safe_str(setting.section), safe_str(setting.key), False))
373 log.debug(
373 log.debug(
374 'settings ui from db: %s',
374 'settings ui from db@repo[%s]: %s',
375 repo,
375 ','.join(map(lambda s: '[{}] {}={}'.format(*s), ui_data)))
376 ','.join(map(lambda s: '[{}] {}={}'.format(*s), ui_data)))
376 if clear_session:
377 if clear_session:
377 meta.Session.remove()
378 meta.Session.remove()
@@ -33,6 +33,8 b' import collections'
33 import warnings
33 import warnings
34
34
35 from zope.cachedescriptors.property import Lazy as LazyProperty
35 from zope.cachedescriptors.property import Lazy as LazyProperty
36 from zope.cachedescriptors.property import CachedProperty
37
36 from pyramid import compat
38 from pyramid import compat
37
39
38 from rhodecode.translation import lazy_ugettext
40 from rhodecode.translation import lazy_ugettext
@@ -53,6 +55,7 b' log = logging.getLogger(__name__)'
53
55
54 FILEMODE_DEFAULT = 0o100644
56 FILEMODE_DEFAULT = 0o100644
55 FILEMODE_EXECUTABLE = 0o100755
57 FILEMODE_EXECUTABLE = 0o100755
58 EMPTY_COMMIT_ID = '0' * 40
56
59
57 Reference = collections.namedtuple('Reference', ('type', 'name', 'commit_id'))
60 Reference = collections.namedtuple('Reference', ('type', 'name', 'commit_id'))
58
61
@@ -161,7 +164,7 b' class MergeResponse(object):'
161 u'This pull request cannot be merged because the source contains '
164 u'This pull request cannot be merged because the source contains '
162 u'more branches than the target.'),
165 u'more branches than the target.'),
163 MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS: lazy_ugettext(
166 MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS: lazy_ugettext(
164 u'This pull request cannot be merged because the target '
167 u'This pull request cannot be merged because the target `{target_ref.name}` '
165 u'has multiple heads: `{heads}`.'),
168 u'has multiple heads: `{heads}`.'),
166 MergeFailureReason.TARGET_IS_LOCKED: lazy_ugettext(
169 MergeFailureReason.TARGET_IS_LOCKED: lazy_ugettext(
167 u'This pull request cannot be merged because the target repository is '
170 u'This pull request cannot be merged because the target repository is '
@@ -261,6 +264,7 b' class BaseRepository(object):'
261 EMPTY_COMMIT_ID = '0' * 40
264 EMPTY_COMMIT_ID = '0' * 40
262
265
263 path = None
266 path = None
267 _commit_ids_ver = 0
264
268
265 def __init__(self, repo_path, config=None, create=False, **kwargs):
269 def __init__(self, repo_path, config=None, create=False, **kwargs):
266 """
270 """
@@ -309,6 +313,9 b' class BaseRepository(object):'
309 def _remote(self):
313 def _remote(self):
310 raise NotImplementedError
314 raise NotImplementedError
311
315
316 def _heads(self, branch=None):
317 return []
318
312 @LazyProperty
319 @LazyProperty
313 def EMPTY_COMMIT(self):
320 def EMPTY_COMMIT(self):
314 return EmptyCommit(self.EMPTY_COMMIT_ID)
321 return EmptyCommit(self.EMPTY_COMMIT_ID)
@@ -380,7 +387,7 b' class BaseRepository(object):'
380 return commit.size
387 return commit.size
381
388
382 def is_empty(self):
389 def is_empty(self):
383 return not bool(self.commit_ids)
390 return self._remote.is_empty()
384
391
385 @staticmethod
392 @staticmethod
386 def check_url(url, config):
393 def check_url(url, config):
@@ -401,6 +408,15 b' class BaseRepository(object):'
401 # COMMITS
408 # COMMITS
402 # ==========================================================================
409 # ==========================================================================
403
410
411 @CachedProperty('_commit_ids_ver')
412 def commit_ids(self):
413 raise NotImplementedError
414
415 def append_commit_id(self, commit_id):
416 if commit_id not in self.commit_ids:
417 self._rebuild_cache(self.commit_ids + [commit_id])
418 self._commit_ids_ver = time.time()
419
404 def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, translate_tag=None):
420 def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, translate_tag=None):
405 """
421 """
406 Returns instance of `BaseCommit` class. If `commit_id` and `commit_idx`
422 Returns instance of `BaseCommit` class. If `commit_id` and `commit_idx`
@@ -1091,12 +1107,12 b' class BaseCommit(object):'
1091 """
1107 """
1092 return None
1108 return None
1093
1109
1094 def archive_repo(self, file_path, kind='tgz', subrepos=None,
1110 def archive_repo(self, archive_dest_path, kind='tgz', subrepos=None,
1095 prefix=None, write_metadata=False, mtime=None):
1111 prefix=None, write_metadata=False, mtime=None, archive_at_path='/'):
1096 """
1112 """
1097 Creates an archive containing the contents of the repository.
1113 Creates an archive containing the contents of the repository.
1098
1114
1099 :param file_path: path to the file which to create the archive.
1115 :param archive_dest_path: path to the file which to create the archive.
1100 :param kind: one of following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
1116 :param kind: one of following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
1101 :param prefix: name of root directory in archive.
1117 :param prefix: name of root directory in archive.
1102 Default is repository name and commit's short_id joined with dash:
1118 Default is repository name and commit's short_id joined with dash:
@@ -1104,10 +1120,11 b' class BaseCommit(object):'
1104 :param write_metadata: write a metadata file into archive.
1120 :param write_metadata: write a metadata file into archive.
1105 :param mtime: custom modification time for archive creation, defaults
1121 :param mtime: custom modification time for archive creation, defaults
1106 to time.time() if not given.
1122 to time.time() if not given.
1123 :param archive_at_path: pack files at this path (default '/')
1107
1124
1108 :raise VCSError: If prefix has a problem.
1125 :raise VCSError: If prefix has a problem.
1109 """
1126 """
1110 allowed_kinds = settings.ARCHIVE_SPECS.keys()
1127 allowed_kinds = [x[0] for x in settings.ARCHIVE_SPECS]
1111 if kind not in allowed_kinds:
1128 if kind not in allowed_kinds:
1112 raise ImproperArchiveTypeError(
1129 raise ImproperArchiveTypeError(
1113 'Archive kind (%s) not supported use one of %s' %
1130 'Archive kind (%s) not supported use one of %s' %
@@ -1115,11 +1132,11 b' class BaseCommit(object):'
1115
1132
1116 prefix = self._validate_archive_prefix(prefix)
1133 prefix = self._validate_archive_prefix(prefix)
1117
1134
1118 mtime = mtime or time.mktime(self.date.timetuple())
1135 mtime = mtime is not None or time.mktime(self.date.timetuple())
1119
1136
1120 file_info = []
1137 file_info = []
1121 cur_rev = self.repository.get_commit(commit_id=self.raw_id)
1138 cur_rev = self.repository.get_commit(commit_id=self.raw_id)
1122 for _r, _d, files in cur_rev.walk('/'):
1139 for _r, _d, files in cur_rev.walk(archive_at_path):
1123 for f in files:
1140 for f in files:
1124 f_path = os.path.join(prefix, f.path)
1141 f_path = os.path.join(prefix, f.path)
1125 file_info.append(
1142 file_info.append(
@@ -1128,15 +1145,15 b' class BaseCommit(object):'
1128 if write_metadata:
1145 if write_metadata:
1129 metadata = [
1146 metadata = [
1130 ('repo_name', self.repository.name),
1147 ('repo_name', self.repository.name),
1131 ('rev', self.raw_id),
1148 ('commit_id', self.raw_id),
1132 ('create_time', mtime),
1149 ('mtime', mtime),
1133 ('branch', self.branch),
1150 ('branch', self.branch),
1134 ('tags', ','.join(self.tags)),
1151 ('tags', ','.join(self.tags)),
1135 ]
1152 ]
1136 meta = ["%s:%s" % (f_name, value) for f_name, value in metadata]
1153 meta = ["%s:%s" % (f_name, value) for f_name, value in metadata]
1137 file_info.append(('.archival.txt', 0o644, False, '\n'.join(meta)))
1154 file_info.append(('.archival.txt', 0o644, False, '\n'.join(meta)))
1138
1155
1139 connection.Hg.archive_repo(file_path, mtime, file_info, kind)
1156 connection.Hg.archive_repo(archive_dest_path, mtime, file_info, kind)
1140
1157
1141 def _validate_archive_prefix(self, prefix):
1158 def _validate_archive_prefix(self, prefix):
1142 if prefix is None:
1159 if prefix is None:
@@ -1505,9 +1522,7 b' class BaseInMemoryCommit(object):'
1505 "Cannot remove node at %s from "
1522 "Cannot remove node at %s from "
1506 "following parents: %s" % (not_removed, parents))
1523 "following parents: %s" % (not_removed, parents))
1507
1524
1508 def commit(
1525 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
1509 self, message, author, parents=None, branch=None, date=None,
1510 **kwargs):
1511 """
1526 """
1512 Performs in-memory commit (doesn't check workdir in any way) and
1527 Performs in-memory commit (doesn't check workdir in any way) and
1513 returns newly created :class:`BaseCommit`. Updates repository's
1528 returns newly created :class:`BaseCommit`. Updates repository's
@@ -1555,7 +1570,7 b' class EmptyCommit(BaseCommit):'
1555 """
1570 """
1556
1571
1557 def __init__(
1572 def __init__(
1558 self, commit_id='0' * 40, repo=None, alias=None, idx=-1,
1573 self, commit_id=EMPTY_COMMIT_ID, repo=None, alias=None, idx=-1,
1559 message='', author='', date=None):
1574 message='', author='', date=None):
1560 self._empty_commit_id = commit_id
1575 self._empty_commit_id = commit_id
1561 # TODO: johbo: Solve idx parameter, default value does not make
1576 # TODO: johbo: Solve idx parameter, default value does not make
@@ -1615,7 +1630,7 b' class EmptyChangeset(EmptyCommit):'
1615 "Use EmptyCommit instead of EmptyChangeset", DeprecationWarning)
1630 "Use EmptyCommit instead of EmptyChangeset", DeprecationWarning)
1616 return super(EmptyCommit, cls).__new__(cls, *args, **kwargs)
1631 return super(EmptyCommit, cls).__new__(cls, *args, **kwargs)
1617
1632
1618 def __init__(self, cs='0' * 40, repo=None, requested_revision=None,
1633 def __init__(self, cs=EMPTY_COMMIT_ID, repo=None, requested_revision=None,
1619 alias=None, revision=-1, message='', author='', date=None):
1634 alias=None, revision=-1, message='', author='', date=None):
1620 if requested_revision is not None:
1635 if requested_revision is not None:
1621 warnings.warn(
1636 warnings.warn(
@@ -234,8 +234,7 b' class GitCommit(base.BaseCommit):'
234 path = self._fix_path(path)
234 path = self._fix_path(path)
235 if self._get_kind(path) != NodeKind.FILE:
235 if self._get_kind(path) != NodeKind.FILE:
236 raise CommitError(
236 raise CommitError(
237 "File does not exist for commit %s at '%s'" %
237 "File does not exist for commit %s at '%s'" % (self.raw_id, path))
238 (self.raw_id, path))
239 return path
238 return path
240
239
241 def _get_file_nodes(self):
240 def _get_file_nodes(self):
@@ -353,8 +352,7 b' class GitCommit(base.BaseCommit):'
353 def get_nodes(self, path):
352 def get_nodes(self, path):
354 if self._get_kind(path) != NodeKind.DIR:
353 if self._get_kind(path) != NodeKind.DIR:
355 raise CommitError(
354 raise CommitError(
356 "Directory does not exist for commit %s at "
355 "Directory does not exist for commit %s at '%s'" % (self.raw_id, path))
357 " '%s'" % (self.raw_id, path))
358 path = self._fix_path(path)
356 path = self._fix_path(path)
359 id_, _ = self._get_id_for_path(path)
357 id_, _ = self._get_id_for_path(path)
360 tree_id = self._remote[id_]['id']
358 tree_id = self._remote[id_]['id']
@@ -29,8 +29,7 b' from rhodecode.lib.vcs.backends import b'
29
29
30 class GitInMemoryCommit(base.BaseInMemoryCommit):
30 class GitInMemoryCommit(base.BaseInMemoryCommit):
31
31
32 def commit(self, message, author, parents=None, branch=None, date=None,
32 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
33 **kwargs):
34 """
33 """
35 Performs in-memory commit (doesn't check workdir in any way) and
34 Performs in-memory commit (doesn't check workdir in any way) and
36 returns newly created `GitCommit`. Updates repository's
35 returns newly created `GitCommit`. Updates repository's
@@ -94,12 +93,12 b' class GitInMemoryCommit(base.BaseInMemor'
94 commit_data, branch, commit_tree, updated, removed)
93 commit_data, branch, commit_tree, updated, removed)
95
94
96 # Update vcs repository object
95 # Update vcs repository object
97 self.repository.commit_ids.append(commit_id)
96 self.repository.append_commit_id(commit_id)
98 self.repository._rebuild_cache(self.repository.commit_ids)
99
97
100 # invalidate parsed refs after commit
98 # invalidate parsed refs after commit
101 self.repository._refs = self.repository._get_refs()
99 self.repository._refs = self.repository._get_refs()
102 self.repository.branches = self.repository._get_branches()
100 self.repository.branches = self.repository._get_branches()
103 tip = self.repository.get_commit()
101 tip = self.repository.get_commit(commit_id)
102
104 self.reset()
103 self.reset()
105 return tip
104 return tip
@@ -25,8 +25,10 b' GIT repository module'
25 import logging
25 import logging
26 import os
26 import os
27 import re
27 import re
28 import time
28
29
29 from zope.cachedescriptors.property import Lazy as LazyProperty
30 from zope.cachedescriptors.property import Lazy as LazyProperty
31 from zope.cachedescriptors.property import CachedProperty
30
32
31 from rhodecode.lib.compat import OrderedDict
33 from rhodecode.lib.compat import OrderedDict
32 from rhodecode.lib.datelib import (
34 from rhodecode.lib.datelib import (
@@ -69,6 +71,9 b' class GitRepository(BaseRepository):'
69 # caches
71 # caches
70 self._commit_ids = {}
72 self._commit_ids = {}
71
73
74 # dependent that trigger re-computation of commit_ids
75 self._commit_ids_ver = 0
76
72 @LazyProperty
77 @LazyProperty
73 def _remote(self):
78 def _remote(self):
74 return connection.Git(self.path, self.config, with_wire=self.with_wire)
79 return connection.Git(self.path, self.config, with_wire=self.with_wire)
@@ -81,7 +86,7 b' class GitRepository(BaseRepository):'
81 def head(self):
86 def head(self):
82 return self._remote.head()
87 return self._remote.head()
83
88
84 @LazyProperty
89 @CachedProperty('_commit_ids_ver')
85 def commit_ids(self):
90 def commit_ids(self):
86 """
91 """
87 Returns list of commit ids, in ascending order. Being lazy
92 Returns list of commit ids, in ascending order. Being lazy
@@ -222,13 +227,10 b' class GitRepository(BaseRepository):'
222 return []
227 return []
223 return output.splitlines()
228 return output.splitlines()
224
229
225 def _get_commit_id(self, commit_id_or_idx):
230 def _lookup_commit(self, commit_id_or_idx, translate_tag=True):
226 def is_null(value):
231 def is_null(value):
227 return len(value) == commit_id_or_idx.count('0')
232 return len(value) == commit_id_or_idx.count('0')
228
233
229 if self.is_empty():
230 raise EmptyRepositoryError("There are no commits yet")
231
232 if commit_id_or_idx in (None, '', 'tip', 'HEAD', 'head', -1):
234 if commit_id_or_idx in (None, '', 'tip', 'HEAD', 'head', -1):
233 return self.commit_ids[-1]
235 return self.commit_ids[-1]
234
236
@@ -238,8 +240,7 b' class GitRepository(BaseRepository):'
238 try:
240 try:
239 commit_id_or_idx = self.commit_ids[int(commit_id_or_idx)]
241 commit_id_or_idx = self.commit_ids[int(commit_id_or_idx)]
240 except Exception:
242 except Exception:
241 msg = "Commit %s does not exist for %s" % (
243 msg = "Commit {} does not exist for `{}`".format(commit_id_or_idx, self.name)
242 commit_id_or_idx, self)
243 raise CommitDoesNotExistError(msg)
244 raise CommitDoesNotExistError(msg)
244
245
245 elif is_bstr:
246 elif is_bstr:
@@ -261,8 +262,7 b' class GitRepository(BaseRepository):'
261
262
262 if (not SHA_PATTERN.match(commit_id_or_idx) or
263 if (not SHA_PATTERN.match(commit_id_or_idx) or
263 commit_id_or_idx not in self.commit_ids):
264 commit_id_or_idx not in self.commit_ids):
264 msg = "Commit %s does not exist for %s" % (
265 msg = "Commit {} does not exist for `{}`".format(commit_id_or_idx, self.name)
265 commit_id_or_idx, self)
266 raise CommitDoesNotExistError(msg)
266 raise CommitDoesNotExistError(msg)
267
267
268 # Ensure we return full id
268 # Ensure we return full id
@@ -431,19 +431,42 b' class GitRepository(BaseRepository):'
431 Returns `GitCommit` object representing commit from git repository
431 Returns `GitCommit` object representing commit from git repository
432 at the given `commit_id` or head (most recent commit) if None given.
432 at the given `commit_id` or head (most recent commit) if None given.
433 """
433 """
434 if self.is_empty():
435 raise EmptyRepositoryError("There are no commits yet")
436
434 if commit_id is not None:
437 if commit_id is not None:
435 self._validate_commit_id(commit_id)
438 self._validate_commit_id(commit_id)
439 try:
440 # we have cached idx, use it without contacting the remote
441 idx = self._commit_ids[commit_id]
442 return GitCommit(self, commit_id, idx, pre_load=pre_load)
443 except KeyError:
444 pass
445
436 elif commit_idx is not None:
446 elif commit_idx is not None:
437 self._validate_commit_idx(commit_idx)
447 self._validate_commit_idx(commit_idx)
448 try:
449 _commit_id = self.commit_ids[commit_idx]
450 if commit_idx < 0:
451 commit_idx = self.commit_ids.index(_commit_id)
452 return GitCommit(self, _commit_id, commit_idx, pre_load=pre_load)
453 except IndexError:
438 commit_id = commit_idx
454 commit_id = commit_idx
439 commit_id = self._get_commit_id(commit_id)
455 else:
440 try:
456 commit_id = "tip"
457
458 commit_id = self._lookup_commit(commit_id)
459 remote_idx = None
441 if translate_tag:
460 if translate_tag:
442 # Need to call remote to translate id for tagging scenario
461 # Need to call remote to translate id for tagging scenario
443 commit_id = self._remote.get_object(commit_id)["commit_id"]
462 remote_data = self._remote.get_object(commit_id)
463 commit_id = remote_data["commit_id"]
464 remote_idx = remote_data["idx"]
465
466 try:
444 idx = self._commit_ids[commit_id]
467 idx = self._commit_ids[commit_id]
445 except KeyError:
468 except KeyError:
446 raise RepositoryError("Cannot get object with id %s" % commit_id)
469 idx = remote_idx or 0
447
470
448 return GitCommit(self, commit_id, idx, pre_load=pre_load)
471 return GitCommit(self, commit_id, idx, pre_load=pre_load)
449
472
@@ -472,6 +495,7 b' class GitRepository(BaseRepository):'
472 """
495 """
473 if self.is_empty():
496 if self.is_empty():
474 raise EmptyRepositoryError("There are no commits yet")
497 raise EmptyRepositoryError("There are no commits yet")
498
475 self._validate_branch_name(branch_name)
499 self._validate_branch_name(branch_name)
476
500
477 if start_id is not None:
501 if start_id is not None:
@@ -479,9 +503,9 b' class GitRepository(BaseRepository):'
479 if end_id is not None:
503 if end_id is not None:
480 self._validate_commit_id(end_id)
504 self._validate_commit_id(end_id)
481
505
482 start_raw_id = self._get_commit_id(start_id)
506 start_raw_id = self._lookup_commit(start_id)
483 start_pos = self._commit_ids[start_raw_id] if start_id else None
507 start_pos = self._commit_ids[start_raw_id] if start_id else None
484 end_raw_id = self._get_commit_id(end_id)
508 end_raw_id = self._lookup_commit(end_id)
485 end_pos = max(0, self._commit_ids[end_raw_id]) if end_id else None
509 end_pos = max(0, self._commit_ids[end_raw_id]) if end_id else None
486
510
487 if None not in [start_id, end_id] and start_pos > end_pos:
511 if None not in [start_id, end_id] and start_pos > end_pos:
@@ -589,8 +613,9 b' class GitRepository(BaseRepository):'
589 commit = commit.parents[0]
613 commit = commit.parents[0]
590 self._remote.set_refs('refs/heads/%s' % branch_name, commit.raw_id)
614 self._remote.set_refs('refs/heads/%s' % branch_name, commit.raw_id)
591
615
592 self.commit_ids = self._get_all_commit_ids()
616 self._commit_ids_ver = time.time()
593 self._rebuild_cache(self.commit_ids)
617 # we updated _commit_ids_ver so accessing self.commit_ids will re-compute it
618 return len(self.commit_ids)
594
619
595 def get_common_ancestor(self, commit_id1, commit_id2, repo2):
620 def get_common_ancestor(self, commit_id1, commit_id2, repo2):
596 if commit_id1 == commit_id2:
621 if commit_id1 == commit_id2:
@@ -193,13 +193,6 b' class MercurialCommit(base.BaseCommit):'
193 children = self._remote.ctx_children(self.idx)
193 children = self._remote.ctx_children(self.idx)
194 return self._make_commits(children)
194 return self._make_commits(children)
195
195
196 def diff(self, ignore_whitespace=True, context=3):
197 result = self._remote.ctx_diff(
198 self.idx,
199 git=True, ignore_whitespace=ignore_whitespace, context=context)
200 diff = ''.join(result)
201 return MercurialDiff(diff)
202
203 def _fix_path(self, path):
196 def _fix_path(self, path):
204 """
197 """
205 Mercurial keeps filenodes as str so we need to encode from unicode
198 Mercurial keeps filenodes as str so we need to encode from unicode
@@ -30,8 +30,7 b' from rhodecode.lib.vcs.exceptions import'
30
30
31 class MercurialInMemoryCommit(BaseInMemoryCommit):
31 class MercurialInMemoryCommit(BaseInMemoryCommit):
32
32
33 def commit(self, message, author, parents=None, branch=None, date=None,
33 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
34 **kwargs):
35 """
34 """
36 Performs in-memory commit (doesn't check workdir in any way) and
35 Performs in-memory commit (doesn't check workdir in any way) and
37 returns newly created `MercurialCommit`. Updates repository's
36 returns newly created `MercurialCommit`. Updates repository's
@@ -83,15 +82,14 b' class MercurialInMemoryCommit(BaseInMemo'
83
82
84 date, tz = date_to_timestamp_plus_offset(date)
83 date, tz = date_to_timestamp_plus_offset(date)
85
84
86 new_id = self.repository._remote.commitctx(
85 commit_id = self.repository._remote.commitctx(
87 message=message, parents=parent_ids,
86 message=message, parents=parent_ids,
88 commit_time=date, commit_timezone=tz, user=author,
87 commit_time=date, commit_timezone=tz, user=author,
89 files=self.get_paths(), extra=kwargs, removed=removed,
88 files=self.get_paths(), extra=kwargs, removed=removed,
90 updated=updated)
89 updated=updated)
90 self.repository.append_commit_id(commit_id)
91
91
92 self.repository.commit_ids.append(new_id)
93 self.repository._rebuild_cache(self.repository.commit_ids)
94 self.repository.branches = self.repository._get_branches()
92 self.repository.branches = self.repository._get_branches()
95 tip = self.repository.get_commit()
93 tip = self.repository.get_commit(commit_id)
96 self.reset()
94 self.reset()
97 return tip
95 return tip
@@ -24,9 +24,11 b' HG repository module'
24 import os
24 import os
25 import logging
25 import logging
26 import binascii
26 import binascii
27 import time
27 import urllib
28 import urllib
28
29
29 from zope.cachedescriptors.property import Lazy as LazyProperty
30 from zope.cachedescriptors.property import Lazy as LazyProperty
31 from zope.cachedescriptors.property import CachedProperty
30
32
31 from rhodecode.lib.compat import OrderedDict
33 from rhodecode.lib.compat import OrderedDict
32 from rhodecode.lib.datelib import (
34 from rhodecode.lib.datelib import (
@@ -85,11 +87,14 b' class MercurialRepository(BaseRepository'
85 # caches
87 # caches
86 self._commit_ids = {}
88 self._commit_ids = {}
87
89
90 # dependent that trigger re-computation of commit_ids
91 self._commit_ids_ver = 0
92
88 @LazyProperty
93 @LazyProperty
89 def _remote(self):
94 def _remote(self):
90 return connection.Hg(self.path, self.config, with_wire=self.with_wire)
95 return connection.Hg(self.path, self.config, with_wire=self.with_wire)
91
96
92 @LazyProperty
97 @CachedProperty('_commit_ids_ver')
93 def commit_ids(self):
98 def commit_ids(self):
94 """
99 """
95 Returns list of commit ids, in ascending order. Being lazy
100 Returns list of commit ids, in ascending order. Being lazy
@@ -157,8 +162,7 b' class MercurialRepository(BaseRepository'
157
162
158 return OrderedDict(sorted(_tags, key=get_name, reverse=True))
163 return OrderedDict(sorted(_tags, key=get_name, reverse=True))
159
164
160 def tag(self, name, user, commit_id=None, message=None, date=None,
165 def tag(self, name, user, commit_id=None, message=None, date=None, **kwargs):
161 **kwargs):
162 """
166 """
163 Creates and returns a tag for the given ``commit_id``.
167 Creates and returns a tag for the given ``commit_id``.
164
168
@@ -172,6 +176,7 b' class MercurialRepository(BaseRepository'
172 """
176 """
173 if name in self.tags:
177 if name in self.tags:
174 raise TagAlreadyExistError("Tag %s already exists" % name)
178 raise TagAlreadyExistError("Tag %s already exists" % name)
179
175 commit = self.get_commit(commit_id=commit_id)
180 commit = self.get_commit(commit_id=commit_id)
176 local = kwargs.setdefault('local', False)
181 local = kwargs.setdefault('local', False)
177
182
@@ -180,8 +185,7 b' class MercurialRepository(BaseRepository'
180
185
181 date, tz = date_to_timestamp_plus_offset(date)
186 date, tz = date_to_timestamp_plus_offset(date)
182
187
183 self._remote.tag(
188 self._remote.tag(name, commit.raw_id, message, local, user, date, tz)
184 name, commit.raw_id, message, local, user, date, tz)
185 self._remote.invalidate_vcs_cache()
189 self._remote.invalidate_vcs_cache()
186
190
187 # Reinitialize tags
191 # Reinitialize tags
@@ -203,6 +207,7 b' class MercurialRepository(BaseRepository'
203 """
207 """
204 if name not in self.tags:
208 if name not in self.tags:
205 raise TagDoesNotExistError("Tag %s does not exist" % name)
209 raise TagDoesNotExistError("Tag %s does not exist" % name)
210
206 if message is None:
211 if message is None:
207 message = "Removed tag %s" % name
212 message = "Removed tag %s" % name
208 local = False
213 local = False
@@ -271,8 +276,9 b' class MercurialRepository(BaseRepository'
271 self._remote.strip(commit_id, update=False, backup="none")
276 self._remote.strip(commit_id, update=False, backup="none")
272
277
273 self._remote.invalidate_vcs_cache()
278 self._remote.invalidate_vcs_cache()
274 self.commit_ids = self._get_all_commit_ids()
279 self._commit_ids_ver = time.time()
275 self._rebuild_cache(self.commit_ids)
280 # we updated _commit_ids_ver so accessing self.commit_ids will re-compute it
281 return len(self.commit_ids)
276
282
277 def verify(self):
283 def verify(self):
278 verify = self._remote.verify()
284 verify = self._remote.verify()
@@ -425,18 +431,20 b' class MercurialRepository(BaseRepository'
425 if commit_id is not None:
431 if commit_id is not None:
426 self._validate_commit_id(commit_id)
432 self._validate_commit_id(commit_id)
427 try:
433 try:
434 # we have cached idx, use it without contacting the remote
428 idx = self._commit_ids[commit_id]
435 idx = self._commit_ids[commit_id]
429 return MercurialCommit(self, commit_id, idx, pre_load=pre_load)
436 return MercurialCommit(self, commit_id, idx, pre_load=pre_load)
430 except KeyError:
437 except KeyError:
431 pass
438 pass
439
432 elif commit_idx is not None:
440 elif commit_idx is not None:
433 self._validate_commit_idx(commit_idx)
441 self._validate_commit_idx(commit_idx)
434 try:
442 try:
435 id_ = self.commit_ids[commit_idx]
443 _commit_id = self.commit_ids[commit_idx]
436 if commit_idx < 0:
444 if commit_idx < 0:
437 commit_idx += len(self.commit_ids)
445 commit_idx = self.commit_ids.index(_commit_id)
438 return MercurialCommit(
446
439 self, id_, commit_idx, pre_load=pre_load)
447 return MercurialCommit(self, _commit_id, commit_idx, pre_load=pre_load)
440 except IndexError:
448 except IndexError:
441 commit_id = commit_idx
449 commit_id = commit_idx
442 else:
450 else:
@@ -448,8 +456,8 b' class MercurialRepository(BaseRepository'
448 try:
456 try:
449 raw_id, idx = self._remote.lookup(commit_id, both=True)
457 raw_id, idx = self._remote.lookup(commit_id, both=True)
450 except CommitDoesNotExistError:
458 except CommitDoesNotExistError:
451 msg = "Commit %s does not exist for %s" % (
459 msg = "Commit {} does not exist for `{}`".format(
452 commit_id, self)
460 *map(safe_str, [commit_id, self.name]))
453 raise CommitDoesNotExistError(msg)
461 raise CommitDoesNotExistError(msg)
454
462
455 return MercurialCommit(self, raw_id, idx, pre_load=pre_load)
463 return MercurialCommit(self, raw_id, idx, pre_load=pre_load)
@@ -477,11 +485,11 b' class MercurialRepository(BaseRepository'
477 ``end`` could not be found.
485 ``end`` could not be found.
478 """
486 """
479 # actually we should check now if it's not an empty repo
487 # actually we should check now if it's not an empty repo
480 branch_ancestors = False
481 if self.is_empty():
488 if self.is_empty():
482 raise EmptyRepositoryError("There are no commits yet")
489 raise EmptyRepositoryError("There are no commits yet")
483 self._validate_branch_name(branch_name)
490 self._validate_branch_name(branch_name)
484
491
492 branch_ancestors = False
485 if start_id is not None:
493 if start_id is not None:
486 self._validate_commit_id(start_id)
494 self._validate_commit_id(start_id)
487 c_start = self.get_commit(commit_id=start_id)
495 c_start = self.get_commit(commit_id=start_id)
@@ -715,11 +723,16 b' class MercurialRepository(BaseRepository'
715
723
716 try:
724 try:
717 if target_ref.type == 'branch' and len(self._heads(target_ref.name)) != 1:
725 if target_ref.type == 'branch' and len(self._heads(target_ref.name)) != 1:
718 heads = ','.join(self._heads(target_ref.name))
726 heads = '\n,'.join(self._heads(target_ref.name))
727 metadata = {
728 'target_ref': target_ref,
729 'source_ref': source_ref,
730 'heads': heads
731 }
719 return MergeResponse(
732 return MergeResponse(
720 False, False, None,
733 False, False, None,
721 MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS,
734 MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS,
722 metadata={'heads': heads})
735 metadata=metadata)
723 except CommitDoesNotExistError:
736 except CommitDoesNotExistError:
724 log.exception('Failure when looking up branch heads on hg target')
737 log.exception('Failure when looking up branch heads on hg target')
725 return MergeResponse(
738 return MergeResponse(
@@ -892,11 +905,15 b' class MercurialRepository(BaseRepository'
892
905
893 def read_patterns(suffix):
906 def read_patterns(suffix):
894 svalue = None
907 svalue = None
908 for section, option in [
909 ('narrowacl', username + suffix),
910 ('narrowacl', 'default' + suffix),
911 ('narrowhgacl', username + suffix),
912 ('narrowhgacl', 'default' + suffix)
913 ]:
895 try:
914 try:
896 svalue = hgacl.get('narrowhgacl', username + suffix)
915 svalue = hgacl.get(section, option)
897 except configparser.NoOptionError:
916 break # stop at the first value we find
898 try:
899 svalue = hgacl.get('narrowhgacl', 'default' + suffix)
900 except configparser.NoOptionError:
917 except configparser.NoOptionError:
901 pass
918 pass
902 if not svalue:
919 if not svalue:
@@ -30,8 +30,7 b' from rhodecode.lib.vcs.backends import b'
30
30
31 class SubversionInMemoryCommit(base.BaseInMemoryCommit):
31 class SubversionInMemoryCommit(base.BaseInMemoryCommit):
32
32
33 def commit(self, message, author, parents=None, branch=None, date=None,
33 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
34 **kwargs):
35 if branch not in (None, self.repository.DEFAULT_BRANCH_NAME):
34 if branch not in (None, self.repository.DEFAULT_BRANCH_NAME):
36 raise NotImplementedError("Branches are not yet supported")
35 raise NotImplementedError("Branches are not yet supported")
37
36
@@ -74,8 +73,7 b' class SubversionInMemoryCommit(base.Base'
74 # we should not add the commit_id, if it is already evaluated, it
73 # we should not add the commit_id, if it is already evaluated, it
75 # will not be evaluated again.
74 # will not be evaluated again.
76 commit_id = str(svn_rev)
75 commit_id = str(svn_rev)
77 if commit_id not in self.repository.commit_ids:
76 self.repository.append_commit_id(commit_id)
78 self.repository.commit_ids.append(commit_id)
79 tip = self.repository.get_commit()
77 tip = self.repository.get_commit()
80 self.reset()
78 self.reset()
81 return tip
79 return tip
@@ -27,6 +27,7 b' import os'
27 import urllib
27 import urllib
28
28
29 from zope.cachedescriptors.property import Lazy as LazyProperty
29 from zope.cachedescriptors.property import Lazy as LazyProperty
30 from zope.cachedescriptors.property import CachedProperty
30
31
31 from rhodecode.lib.compat import OrderedDict
32 from rhodecode.lib.compat import OrderedDict
32 from rhodecode.lib.datelib import date_astimestamp
33 from rhodecode.lib.datelib import date_astimestamp
@@ -75,6 +76,9 b' class SubversionRepository(base.BaseRepo'
75
76
76 self._init_repo(create, src_url)
77 self._init_repo(create, src_url)
77
78
79 # dependent that trigger re-computation of commit_ids
80 self._commit_ids_ver = 0
81
78 @LazyProperty
82 @LazyProperty
79 def _remote(self):
83 def _remote(self):
80 return connection.Svn(self.path, self.config)
84 return connection.Svn(self.path, self.config)
@@ -93,11 +97,31 b' class SubversionRepository(base.BaseRepo'
93 else:
97 else:
94 self._check_path()
98 self._check_path()
95
99
96 @LazyProperty
100 @CachedProperty('_commit_ids_ver')
97 def commit_ids(self):
101 def commit_ids(self):
98 head = self._remote.lookup(None)
102 head = self._remote.lookup(None)
99 return [str(r) for r in xrange(1, head + 1)]
103 return [str(r) for r in xrange(1, head + 1)]
100
104
105 def _rebuild_cache(self, commit_ids):
106 pass
107
108 def run_svn_command(self, cmd, **opts):
109 """
110 Runs given ``cmd`` as svn command and returns tuple
111 (stdout, stderr).
112
113 :param cmd: full svn command to be executed
114 :param opts: env options to pass into Subprocess command
115 """
116 if not isinstance(cmd, list):
117 raise ValueError('cmd must be a list, got %s instead' % type(cmd))
118
119 skip_stderr_log = opts.pop('skip_stderr_log', False)
120 out, err = self._remote.run_svn_command(cmd, **opts)
121 if err and not skip_stderr_log:
122 log.debug('Stderr output of svn command "%s":\n%s', cmd, err)
123 return out, err
124
101 @LazyProperty
125 @LazyProperty
102 def branches(self):
126 def branches(self):
103 return self._tags_or_branches('vcs_svn_branch')
127 return self._tags_or_branches('vcs_svn_branch')
@@ -260,7 +284,7 b' class SubversionRepository(base.BaseRepo'
260 try:
284 try:
261 commit_id = self.commit_ids[commit_idx]
285 commit_id = self.commit_ids[commit_idx]
262 except IndexError:
286 except IndexError:
263 raise CommitDoesNotExistError
287 raise CommitDoesNotExistError('No commit with idx: {}'.format(commit_idx))
264
288
265 commit_id = self._sanitize_commit_id(commit_id)
289 commit_id = self._sanitize_commit_id(commit_id)
266 commit = SubversionCommit(repository=self, commit_id=commit_id)
290 commit = SubversionCommit(repository=self, commit_id=commit_id)
@@ -42,12 +42,16 b' BACKENDS = {'
42 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository',
42 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository',
43 }
43 }
44
44
45 # TODO: Remove once controllers/files.py is adjusted
45
46 ARCHIVE_SPECS = {
46 ARCHIVE_SPECS = [
47 'tbz2': ('application/x-bzip2', '.tar.bz2'),
47 ('tbz2', 'application/x-bzip2', 'tbz2'),
48 'tgz': ('application/x-gzip', '.tar.gz'),
48 ('tbz2', 'application/x-bzip2', '.tar.bz2'),
49 'zip': ('application/zip', '.zip'),
49
50 }
50 ('tgz', 'application/x-gzip', '.tgz'),
51 ('tgz', 'application/x-gzip', '.tar.gz'),
52
53 ('zip', 'application/zip', '.zip'),
54 ]
51
55
52 HOOKS_PROTOCOL = None
56 HOOKS_PROTOCOL = None
53 HOOKS_DIRECT_CALLS = False
57 HOOKS_DIRECT_CALLS = False
@@ -101,23 +101,35 b' def parse_datetime(text):'
101 :param text: string of desired date/datetime or something more verbose,
101 :param text: string of desired date/datetime or something more verbose,
102 like *yesterday*, *2weeks 3days*, etc.
102 like *yesterday*, *2weeks 3days*, etc.
103 """
103 """
104 if not text:
105 raise ValueError('Wrong date: "%s"' % text)
104
106
105 text = text.strip().lower()
107 if isinstance(text, datetime.datetime):
108 return text
106
109
107 INPUT_FORMATS = (
110 # we limit a format to no include microseconds e.g 2017-10-17t17:48:23.XXXX
111 text = text.strip().lower()[:19]
112
113 input_formats = (
108 '%Y-%m-%d %H:%M:%S',
114 '%Y-%m-%d %H:%M:%S',
115 '%Y-%m-%dt%H:%M:%S',
109 '%Y-%m-%d %H:%M',
116 '%Y-%m-%d %H:%M',
117 '%Y-%m-%dt%H:%M',
110 '%Y-%m-%d',
118 '%Y-%m-%d',
111 '%m/%d/%Y %H:%M:%S',
119 '%m/%d/%Y %H:%M:%S',
120 '%m/%d/%Yt%H:%M:%S',
112 '%m/%d/%Y %H:%M',
121 '%m/%d/%Y %H:%M',
122 '%m/%d/%Yt%H:%M',
113 '%m/%d/%Y',
123 '%m/%d/%Y',
114 '%m/%d/%y %H:%M:%S',
124 '%m/%d/%y %H:%M:%S',
125 '%m/%d/%yt%H:%M:%S',
115 '%m/%d/%y %H:%M',
126 '%m/%d/%y %H:%M',
127 '%m/%d/%yt%H:%M',
116 '%m/%d/%y',
128 '%m/%d/%y',
117 )
129 )
118 for format in INPUT_FORMATS:
130 for format_def in input_formats:
119 try:
131 try:
120 return datetime.datetime(*time.strptime(text, format)[:6])
132 return datetime.datetime(*time.strptime(text, format_def)[:6])
121 except ValueError:
133 except ValueError:
122 pass
134 pass
123
135
@@ -25,6 +25,7 b' Database Models for RhodeCode Enterprise'
25 import re
25 import re
26 import os
26 import os
27 import time
27 import time
28 import string
28 import hashlib
29 import hashlib
29 import logging
30 import logging
30 import datetime
31 import datetime
@@ -39,7 +40,7 b' from sqlalchemy import ('
39 Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column,
40 Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column,
40 Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary,
41 Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary,
41 Text, Float, PickleType)
42 Text, Float, PickleType)
42 from sqlalchemy.sql.expression import true, false
43 from sqlalchemy.sql.expression import true, false, case
43 from sqlalchemy.sql.functions import coalesce, count # pragma: no cover
44 from sqlalchemy.sql.functions import coalesce, count # pragma: no cover
44 from sqlalchemy.orm import (
45 from sqlalchemy.orm import (
45 relationship, joinedload, class_mapper, validates, aliased)
46 relationship, joinedload, class_mapper, validates, aliased)
@@ -50,6 +51,7 b' from sqlalchemy.dialects.mysql import LO'
50 from zope.cachedescriptors.property import Lazy as LazyProperty
51 from zope.cachedescriptors.property import Lazy as LazyProperty
51 from pyramid import compat
52 from pyramid import compat
52 from pyramid.threadlocal import get_current_request
53 from pyramid.threadlocal import get_current_request
54 from webhelpers.text import collapse, remove_formatting
53
55
54 from rhodecode.translation import _
56 from rhodecode.translation import _
55 from rhodecode.lib.vcs import get_vcs_instance
57 from rhodecode.lib.vcs import get_vcs_instance
@@ -57,13 +59,13 b' from rhodecode.lib.vcs.backends.base imp'
57 from rhodecode.lib.utils2 import (
59 from rhodecode.lib.utils2 import (
58 str2bool, safe_str, get_commit_safe, safe_unicode, sha1_safe,
60 str2bool, safe_str, get_commit_safe, safe_unicode, sha1_safe,
59 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict,
61 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict,
60 glob2re, StrictAttributeDict, cleaned_uri)
62 glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time, OrderedDefaultDict)
61 from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \
63 from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \
62 JsonRaw
64 JsonRaw
63 from rhodecode.lib.ext_json import json
65 from rhodecode.lib.ext_json import json
64 from rhodecode.lib.caching_query import FromCache
66 from rhodecode.lib.caching_query import FromCache
65 from rhodecode.lib.encrypt import AESCipher
67 from rhodecode.lib.encrypt import AESCipher, validate_and_get_enc_data
66
68 from rhodecode.lib.encrypt2 import Encryptor
67 from rhodecode.model.meta import Base, Session
69 from rhodecode.model.meta import Base, Session
68
70
69 URL_SEP = '/'
71 URL_SEP = '/'
@@ -159,43 +161,45 b' class EncryptedTextValue(TypeDecorator):'
159 impl = Text
161 impl = Text
160
162
161 def process_bind_param(self, value, dialect):
163 def process_bind_param(self, value, dialect):
162 if not value:
164 """
163 return value
165 Setter for storing value
164 if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'):
166 """
165 # protect against double encrypting if someone manually starts
166 # doing
167 raise ValueError('value needs to be in unencrypted format, ie. '
168 'not starting with enc$aes')
169 return 'enc$aes_hmac$%s' % AESCipher(
170 ENCRYPTION_KEY, hmac=True).encrypt(value)
171
172 def process_result_value(self, value, dialect):
173 import rhodecode
167 import rhodecode
174
175 if not value:
168 if not value:
176 return value
169 return value
177
170
178 parts = value.split('$', 3)
171 # protect against double encrypting if values is already encrypted
179 if not len(parts) == 3:
172 if value.startswith('enc$aes$') \
180 # probably not encrypted values
173 or value.startswith('enc$aes_hmac$') \
181 return value
174 or value.startswith('enc2$'):
175 raise ValueError('value needs to be in unencrypted format, '
176 'ie. not starting with enc$ or enc2$')
177
178 algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes'
179 if algo == 'aes':
180 return 'enc$aes_hmac$%s' % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value)
181 elif algo == 'fernet':
182 return Encryptor(ENCRYPTION_KEY).encrypt(value)
182 else:
183 else:
183 if parts[0] != 'enc':
184 ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo))
184 # parts ok but without our header ?
185
186 def process_result_value(self, value, dialect):
187 """
188 Getter for retrieving value
189 """
190
191 import rhodecode
192 if not value:
185 return value
193 return value
186 enc_strict_mode = str2bool(rhodecode.CONFIG.get(
194
187 'rhodecode.encrypted_values.strict') or True)
195 algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes'
188 # at that stage we know it's our encryption
196 enc_strict_mode = str2bool(rhodecode.CONFIG.get('rhodecode.encrypted_values.strict') or True)
189 if parts[1] == 'aes':
197 if algo == 'aes':
190 decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2])
198 decrypted_data = validate_and_get_enc_data(value, ENCRYPTION_KEY, enc_strict_mode)
191 elif parts[1] == 'aes_hmac':
199 elif algo == 'fernet':
192 decrypted_data = AESCipher(
200 return Encryptor(ENCRYPTION_KEY).decrypt(value)
193 ENCRYPTION_KEY, hmac=True,
194 strict_verification=enc_strict_mode).decrypt(parts[2])
195 else:
201 else:
196 raise ValueError(
202 ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo))
197 'Encryption type part is wrong, must be `aes` '
198 'or `aes_hmac`, got `%s` instead' % (parts[1]))
199 return decrypted_data
203 return decrypted_data
200
204
201
205
@@ -407,6 +411,15 b' class RhodeCodeUi(Base, BaseModel):'
407 HOOK_PUSH = 'changegroup.push_logger'
411 HOOK_PUSH = 'changegroup.push_logger'
408 HOOK_PUSH_KEY = 'pushkey.key_push'
412 HOOK_PUSH_KEY = 'pushkey.key_push'
409
413
414 HOOKS_BUILTIN = [
415 HOOK_PRE_PULL,
416 HOOK_PULL,
417 HOOK_PRE_PUSH,
418 HOOK_PRETX_PUSH,
419 HOOK_PUSH,
420 HOOK_PUSH_KEY,
421 ]
422
410 # TODO: johbo: Unify way how hooks are configured for git and hg,
423 # TODO: johbo: Unify way how hooks are configured for git and hg,
411 # git part is currently hardcoded.
424 # git part is currently hardcoded.
412
425
@@ -1665,11 +1678,12 b' class Repository(Base, BaseModel):'
1665 cascade="all, delete, delete-orphan")
1678 cascade="all, delete, delete-orphan")
1666 ui = relationship('RepoRhodeCodeUi', cascade="all")
1679 ui = relationship('RepoRhodeCodeUi', cascade="all")
1667 settings = relationship('RepoRhodeCodeSetting', cascade="all")
1680 settings = relationship('RepoRhodeCodeSetting', cascade="all")
1668 integrations = relationship('Integration',
1681 integrations = relationship('Integration', cascade="all, delete, delete-orphan")
1669 cascade="all, delete, delete-orphan")
1670
1682
1671 scoped_tokens = relationship('UserApiKeys', cascade="all")
1683 scoped_tokens = relationship('UserApiKeys', cascade="all")
1672
1684
1685 artifacts = relationship('FileStore', cascade="all")
1686
1673 def __unicode__(self):
1687 def __unicode__(self):
1674 return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id,
1688 return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id,
1675 safe_unicode(self.repo_name))
1689 safe_unicode(self.repo_name))
@@ -1717,7 +1731,9 b' class Repository(Base, BaseModel):'
1717 from rhodecode.lib.vcs.backends.base import EmptyCommit
1731 from rhodecode.lib.vcs.backends.base import EmptyCommit
1718 dummy = EmptyCommit().__json__()
1732 dummy = EmptyCommit().__json__()
1719 if not self._changeset_cache:
1733 if not self._changeset_cache:
1720 return dummy
1734 dummy['source_repo_id'] = self.repo_id
1735 return json.loads(json.dumps(dummy))
1736
1721 try:
1737 try:
1722 return json.loads(self._changeset_cache)
1738 return json.loads(self._changeset_cache)
1723 except TypeError:
1739 except TypeError:
@@ -2170,6 +2186,20 b' class Repository(Base, BaseModel):'
2170 return make_lock, currently_locked, lock_info
2186 return make_lock, currently_locked, lock_info
2171
2187
2172 @property
2188 @property
2189 def last_commit_cache_update_diff(self):
2190 return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0)
2191
2192 @property
2193 def last_commit_change(self):
2194 from rhodecode.lib.vcs.utils.helpers import parse_datetime
2195 empty_date = datetime.datetime.fromtimestamp(0)
2196 date_latest = self.changeset_cache.get('date', empty_date)
2197 try:
2198 return parse_datetime(date_latest)
2199 except Exception:
2200 return empty_date
2201
2202 @property
2173 def last_db_change(self):
2203 def last_db_change(self):
2174 return self.updated_on
2204 return self.updated_on
2175
2205
@@ -2262,6 +2292,7 b' class Repository(Base, BaseModel):'
2262 """
2292 """
2263 Update cache of last changeset for repository, keys should be::
2293 Update cache of last changeset for repository, keys should be::
2264
2294
2295 source_repo_id
2265 short_id
2296 short_id
2266 raw_id
2297 raw_id
2267 revision
2298 revision
@@ -2269,15 +2300,15 b' class Repository(Base, BaseModel):'
2269 message
2300 message
2270 date
2301 date
2271 author
2302 author
2272
2303 updated_on
2273 :param cs_cache:
2304
2274 """
2305 """
2275 from rhodecode.lib.vcs.backends.base import BaseChangeset
2306 from rhodecode.lib.vcs.backends.base import BaseChangeset
2276 if cs_cache is None:
2307 if cs_cache is None:
2277 # use no-cache version here
2308 # use no-cache version here
2278 scm_repo = self.scm_instance(cache=False, config=config)
2309 scm_repo = self.scm_instance(cache=False, config=config)
2279
2310
2280 empty = not scm_repo or scm_repo.is_empty()
2311 empty = scm_repo is None or scm_repo.is_empty()
2281 if not empty:
2312 if not empty:
2282 cs_cache = scm_repo.get_commit(
2313 cs_cache = scm_repo.get_commit(
2283 pre_load=["author", "date", "message", "parents"])
2314 pre_load=["author", "date", "message", "parents"])
@@ -2297,18 +2328,28 b' class Repository(Base, BaseModel):'
2297 if is_outdated(cs_cache) or not self.changeset_cache:
2328 if is_outdated(cs_cache) or not self.changeset_cache:
2298 _default = datetime.datetime.utcnow()
2329 _default = datetime.datetime.utcnow()
2299 last_change = cs_cache.get('date') or _default
2330 last_change = cs_cache.get('date') or _default
2300 if self.updated_on and self.updated_on > last_change:
2301 # we check if last update is newer than the new value
2331 # we check if last update is newer than the new value
2302 # if yes, we use the current timestamp instead. Imagine you get
2332 # if yes, we use the current timestamp instead. Imagine you get
2303 # old commit pushed 1y ago, we'd set last update 1y to ago.
2333 # old commit pushed 1y ago, we'd set last update 1y to ago.
2304 last_change = _default
2334 last_change_timestamp = datetime_to_time(last_change)
2305 log.debug('updated repo %s with new cs cache %s',
2335 current_timestamp = datetime_to_time(last_change)
2306 self.repo_name, cs_cache)
2336 if last_change_timestamp > current_timestamp:
2307 self.updated_on = last_change
2337 cs_cache['date'] = _default
2338
2339 cs_cache['updated_on'] = time.time()
2308 self.changeset_cache = cs_cache
2340 self.changeset_cache = cs_cache
2309 Session().add(self)
2341 Session().add(self)
2310 Session().commit()
2342 Session().commit()
2343
2344 log.debug('updated repo %s with new commit cache %s',
2345 self.repo_name, cs_cache)
2311 else:
2346 else:
2347 cs_cache = self.changeset_cache
2348 cs_cache['updated_on'] = time.time()
2349 self.changeset_cache = cs_cache
2350 Session().add(self)
2351 Session().commit()
2352
2312 log.debug('Skipping update_commit_cache for repo:`%s` '
2353 log.debug('Skipping update_commit_cache for repo:`%s` '
2313 'commit already with latest changes', self.repo_name)
2354 'commit already with latest changes', self.repo_name)
2314
2355
@@ -2397,6 +2438,7 b' class Repository(Base, BaseModel):'
2397 # control over cache behaviour
2438 # control over cache behaviour
2398 if cache is None and full_cache and not config:
2439 if cache is None and full_cache and not config:
2399 return self._get_instance_cached()
2440 return self._get_instance_cached()
2441 # cache here is sent to the "vcs server"
2400 return self._get_instance(cache=bool(cache), config=config)
2442 return self._get_instance(cache=bool(cache), config=config)
2401
2443
2402 def _get_instance_cached(self):
2444 def _get_instance_cached(self):
@@ -2425,8 +2467,7 b' class Repository(Base, BaseModel):'
2425 else:
2467 else:
2426 instance = get_instance_cached(*args)
2468 instance = get_instance_cached(*args)
2427
2469
2428 log.debug(
2470 log.debug('Repo instance fetched in %.3fs', inv_context_manager.compute_time)
2429 'Repo instance fetched in %.3fs', inv_context_manager.compute_time)
2430 return instance
2471 return instance
2431
2472
2432 def _get_instance(self, cache=True, config=None):
2473 def _get_instance(self, cache=True, config=None):
@@ -2440,7 +2481,8 b' class Repository(Base, BaseModel):'
2440 with_wire=custom_wire,
2481 with_wire=custom_wire,
2441 create=False,
2482 create=False,
2442 _vcs_alias=self.repo_type)
2483 _vcs_alias=self.repo_type)
2443
2484 if repo is not None:
2485 repo.count() # cache rebuild
2444 return repo
2486 return repo
2445
2487
2446 def __json__(self):
2488 def __json__(self):
@@ -2467,7 +2509,8 b' class RepoGroup(Base, BaseModel):'
2467 CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups
2509 CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups
2468
2510
2469 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
2511 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
2470 group_name = Column("group_name", String(255), nullable=False, unique=True, default=None)
2512 _group_name = Column("group_name", String(255), nullable=False, unique=True, default=None)
2513 group_name_hash = Column("repo_group_name_hash", String(1024), nullable=False, unique=False)
2471 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
2514 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
2472 group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None)
2515 group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None)
2473 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
2516 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
@@ -2475,6 +2518,8 b' class RepoGroup(Base, BaseModel):'
2475 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
2518 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
2476 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
2519 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
2477 personal = Column('personal', Boolean(), nullable=True, unique=None, default=None)
2520 personal = Column('personal', Boolean(), nullable=True, unique=None, default=None)
2521 _changeset_cache = Column(
2522 "changeset_cache", LargeBinary(), nullable=True) # JSON data
2478
2523
2479 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
2524 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
2480 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
2525 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
@@ -2490,6 +2535,38 b' class RepoGroup(Base, BaseModel):'
2490 return u"<%s('id:%s:%s')>" % (
2535 return u"<%s('id:%s:%s')>" % (
2491 self.__class__.__name__, self.group_id, self.group_name)
2536 self.__class__.__name__, self.group_id, self.group_name)
2492
2537
2538 @hybrid_property
2539 def group_name(self):
2540 return self._group_name
2541
2542 @group_name.setter
2543 def group_name(self, value):
2544 self._group_name = value
2545 self.group_name_hash = self.hash_repo_group_name(value)
2546
2547 @hybrid_property
2548 def changeset_cache(self):
2549 from rhodecode.lib.vcs.backends.base import EmptyCommit
2550 dummy = EmptyCommit().__json__()
2551 if not self._changeset_cache:
2552 dummy['source_repo_id'] = ''
2553 return json.loads(json.dumps(dummy))
2554
2555 try:
2556 return json.loads(self._changeset_cache)
2557 except TypeError:
2558 return dummy
2559 except Exception:
2560 log.error(traceback.format_exc())
2561 return dummy
2562
2563 @changeset_cache.setter
2564 def changeset_cache(self, val):
2565 try:
2566 self._changeset_cache = json.dumps(val)
2567 except Exception:
2568 log.error(traceback.format_exc())
2569
2493 @validates('group_parent_id')
2570 @validates('group_parent_id')
2494 def validate_group_parent_id(self, key, val):
2571 def validate_group_parent_id(self, key, val):
2495 """
2572 """
@@ -2506,6 +2583,18 b' class RepoGroup(Base, BaseModel):'
2506 return h.escape(self.group_description)
2583 return h.escape(self.group_description)
2507
2584
2508 @classmethod
2585 @classmethod
2586 def hash_repo_group_name(cls, repo_group_name):
2587 val = remove_formatting(repo_group_name)
2588 val = safe_str(val).lower()
2589 chars = []
2590 for c in val:
2591 if c not in string.ascii_letters:
2592 c = str(ord(c))
2593 chars.append(c)
2594
2595 return ''.join(chars)
2596
2597 @classmethod
2509 def _generate_choice(cls, repo_group):
2598 def _generate_choice(cls, repo_group):
2510 from webhelpers.html import literal as _literal
2599 from webhelpers.html import literal as _literal
2511 _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k))
2600 _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k))
@@ -2573,8 +2662,7 b' class RepoGroup(Base, BaseModel):'
2573 return q.all()
2662 return q.all()
2574
2663
2575 @property
2664 @property
2576 def parents(self):
2665 def parents(self, parents_recursion_limit = 10):
2577 parents_recursion_limit = 10
2578 groups = []
2666 groups = []
2579 if self.parent_group is None:
2667 if self.parent_group is None:
2580 return groups
2668 return groups
@@ -2597,6 +2685,20 b' class RepoGroup(Base, BaseModel):'
2597 return groups
2685 return groups
2598
2686
2599 @property
2687 @property
2688 def last_commit_cache_update_diff(self):
2689 return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0)
2690
2691 @property
2692 def last_commit_change(self):
2693 from rhodecode.lib.vcs.utils.helpers import parse_datetime
2694 empty_date = datetime.datetime.fromtimestamp(0)
2695 date_latest = self.changeset_cache.get('date', empty_date)
2696 try:
2697 return parse_datetime(date_latest)
2698 except Exception:
2699 return empty_date
2700
2701 @property
2600 def last_db_change(self):
2702 def last_db_change(self):
2601 return self.updated_on
2703 return self.updated_on
2602
2704
@@ -2635,7 +2737,7 b' class RepoGroup(Base, BaseModel):'
2635
2737
2636 return cnt + children_count(self)
2738 return cnt + children_count(self)
2637
2739
2638 def _recursive_objects(self, include_repos=True):
2740 def _recursive_objects(self, include_repos=True, include_groups=True):
2639 all_ = []
2741 all_ = []
2640
2742
2641 def _get_members(root_gr):
2743 def _get_members(root_gr):
@@ -2645,11 +2747,16 b' class RepoGroup(Base, BaseModel):'
2645 childs = root_gr.children.all()
2747 childs = root_gr.children.all()
2646 if childs:
2748 if childs:
2647 for gr in childs:
2749 for gr in childs:
2750 if include_groups:
2648 all_.append(gr)
2751 all_.append(gr)
2649 _get_members(gr)
2752 _get_members(gr)
2650
2753
2754 root_group = []
2755 if include_groups:
2756 root_group = [self]
2757
2651 _get_members(self)
2758 _get_members(self)
2652 return [self] + all_
2759 return root_group + all_
2653
2760
2654 def recursive_groups_and_repos(self):
2761 def recursive_groups_and_repos(self):
2655 """
2762 """
@@ -2663,6 +2770,12 b' class RepoGroup(Base, BaseModel):'
2663 """
2770 """
2664 return self._recursive_objects(include_repos=False)
2771 return self._recursive_objects(include_repos=False)
2665
2772
2773 def recursive_repos(self):
2774 """
2775 Returns all children repositories for this group
2776 """
2777 return self._recursive_objects(include_groups=False)
2778
2666 def get_new_name(self, group_name):
2779 def get_new_name(self, group_name):
2667 """
2780 """
2668 returns new full group name based on parent and new name
2781 returns new full group name based on parent and new name
@@ -2673,6 +2786,63 b' class RepoGroup(Base, BaseModel):'
2673 self.parent_group else [])
2786 self.parent_group else [])
2674 return RepoGroup.url_sep().join(path_prefix + [group_name])
2787 return RepoGroup.url_sep().join(path_prefix + [group_name])
2675
2788
2789 def update_commit_cache(self, config=None):
2790 """
2791 Update cache of last changeset for newest repository inside this group, keys should be::
2792
2793 source_repo_id
2794 short_id
2795 raw_id
2796 revision
2797 parents
2798 message
2799 date
2800 author
2801
2802 """
2803 from rhodecode.lib.vcs.utils.helpers import parse_datetime
2804
2805 def repo_groups_and_repos():
2806 all_entries = OrderedDefaultDict(list)
2807
2808 def _get_members(root_gr, pos=0):
2809
2810 for repo in root_gr.repositories:
2811 all_entries[root_gr].append(repo)
2812
2813 # fill in all parent positions
2814 for parent_group in root_gr.parents:
2815 all_entries[parent_group].extend(all_entries[root_gr])
2816
2817 children_groups = root_gr.children.all()
2818 if children_groups:
2819 for cnt, gr in enumerate(children_groups, 1):
2820 _get_members(gr, pos=pos+cnt)
2821
2822 _get_members(root_gr=self)
2823 return all_entries
2824
2825 empty_date = datetime.datetime.fromtimestamp(0)
2826 for repo_group, repos in repo_groups_and_repos().items():
2827
2828 latest_repo_cs_cache = {}
2829 for repo in repos:
2830 repo_cs_cache = repo.changeset_cache
2831 date_latest = latest_repo_cs_cache.get('date', empty_date)
2832 date_current = repo_cs_cache.get('date', empty_date)
2833 current_timestamp = datetime_to_time(parse_datetime(date_latest))
2834 if current_timestamp < datetime_to_time(parse_datetime(date_current)):
2835 latest_repo_cs_cache = repo_cs_cache
2836 latest_repo_cs_cache['source_repo_id'] = repo.repo_id
2837
2838 latest_repo_cs_cache['updated_on'] = time.time()
2839 repo_group.changeset_cache = latest_repo_cs_cache
2840 Session().add(repo_group)
2841 Session().commit()
2842
2843 log.debug('updated repo group %s with new commit cache %s',
2844 repo_group.group_name, latest_repo_cs_cache)
2845
2676 def permissions(self, with_admins=True, with_owner=True,
2846 def permissions(self, with_admins=True, with_owner=True,
2677 expand_from_user_groups=False):
2847 expand_from_user_groups=False):
2678 """
2848 """
@@ -2768,6 +2938,13 b' class RepoGroup(Base, BaseModel):'
2768 }
2938 }
2769 return data
2939 return data
2770
2940
2941 def get_dict(self):
2942 # Since we transformed `group_name` to a hybrid property, we need to
2943 # keep compatibility with the code which uses `group_name` field.
2944 result = super(RepoGroup, self).get_dict()
2945 result['group_name'] = result.pop('_group_name', None)
2946 return result
2947
2771
2948
2772 class Permission(Base, BaseModel):
2949 class Permission(Base, BaseModel):
2773 __tablename__ = 'permissions'
2950 __tablename__ = 'permissions'
@@ -4258,9 +4435,16 b' class Gist(Base, BaseModel):'
4258 # SCM functions
4435 # SCM functions
4259
4436
4260 def scm_instance(self, **kwargs):
4437 def scm_instance(self, **kwargs):
4438 """
4439 Get an instance of VCS Repository
4440
4441 :param kwargs:
4442 """
4443 from rhodecode.model.gist import GistModel
4261 full_repo_path = os.path.join(self.base_path(), self.gist_access_id)
4444 full_repo_path = os.path.join(self.base_path(), self.gist_access_id)
4262 return get_vcs_instance(
4445 return get_vcs_instance(
4263 repo_path=safe_str(full_repo_path), create=False)
4446 repo_path=safe_str(full_repo_path), create=False,
4447 _vcs_alias=GistModel.vcs_backend)
4264
4448
4265
4449
4266 class ExternalIdentity(Base, BaseModel):
4450 class ExternalIdentity(Base, BaseModel):
@@ -4904,8 +5088,8 b' class FileStore(Base, BaseModel):'
4904
5088
4905 @classmethod
5089 @classmethod
4906 def create(cls, file_uid, filename, file_hash, file_size, file_display_name='',
5090 def create(cls, file_uid, filename, file_hash, file_size, file_display_name='',
4907 file_description='', enabled=True, check_acl=True,
5091 file_description='', enabled=True, check_acl=True, user_id=None,
4908 user_id=None, scope_repo_id=None, scope_repo_group_id=None):
5092 scope_user_id=None, scope_repo_id=None, scope_repo_group_id=None):
4909
5093
4910 store_entry = FileStore()
5094 store_entry = FileStore()
4911 store_entry.file_uid = file_uid
5095 store_entry.file_uid = file_uid
@@ -4919,6 +5103,7 b' class FileStore(Base, BaseModel):'
4919 store_entry.enabled = enabled
5103 store_entry.enabled = enabled
4920
5104
4921 store_entry.user_id = user_id
5105 store_entry.user_id = user_id
5106 store_entry.scope_user_id = scope_user_id
4922 store_entry.scope_repo_id = scope_repo_id
5107 store_entry.scope_repo_id = scope_repo_id
4923 store_entry.scope_repo_group_id = scope_repo_group_id
5108 store_entry.scope_repo_group_id = scope_repo_group_id
4924 return store_entry
5109 return store_entry
@@ -618,7 +618,7 b' def PullRequestForm(localizer, repo_id):'
618 revisions = All(#v.NotReviewedRevisions(localizer, repo_id)(),
618 revisions = All(#v.NotReviewedRevisions(localizer, repo_id)(),
619 v.UniqueList(localizer)(not_empty=True))
619 v.UniqueList(localizer)(not_empty=True))
620 review_members = formencode.ForEach(ReviewerForm())
620 review_members = formencode.ForEach(ReviewerForm())
621 pullrequest_title = v.UnicodeString(strip=True, required=True, min=3, max=255)
621 pullrequest_title = v.UnicodeString(strip=True, required=True, min=1, max=255)
622 pullrequest_desc = v.UnicodeString(strip=True, required=False)
622 pullrequest_desc = v.UnicodeString(strip=True, required=False)
623 description_renderer = v.UnicodeString(strip=True, required=False)
623 description_renderer = v.UnicodeString(strip=True, required=False)
624
624
@@ -47,6 +47,7 b" GIST_METADATA_FILE = '.rc_gist_metadata'"
47
47
48 class GistModel(BaseModel):
48 class GistModel(BaseModel):
49 cls = Gist
49 cls = Gist
50 vcs_backend = 'hg'
50
51
51 def _get_gist(self, gist):
52 def _get_gist(self, gist):
52 """
53 """
@@ -145,7 +146,7 b' class GistModel(BaseModel):'
145 gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id)
146 gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id)
146 log.debug('Creating new %s GIST repo in %s', gist_type, gist_repo_path)
147 log.debug('Creating new %s GIST repo in %s', gist_type, gist_repo_path)
147 repo = RepoModel()._create_filesystem_repo(
148 repo = RepoModel()._create_filesystem_repo(
148 repo_name=gist_id, repo_type='hg', repo_group=GIST_STORE_LOC,
149 repo_name=gist_id, repo_type=self.vcs_backend, repo_group=GIST_STORE_LOC,
149 use_global_config=True)
150 use_global_config=True)
150
151
151 # now create single multifile commit
152 # now create single multifile commit
@@ -683,6 +683,7 b' class PullRequestModel(BaseModel):'
683
683
684 # source repo
684 # source repo
685 source_repo = pull_request.source_repo.scm_instance()
685 source_repo = pull_request.source_repo.scm_instance()
686
686 try:
687 try:
687 source_commit = source_repo.get_commit(commit_id=source_ref_name)
688 source_commit = source_repo.get_commit(commit_id=source_ref_name)
688 except CommitDoesNotExistError:
689 except CommitDoesNotExistError:
@@ -696,6 +697,7 b' class PullRequestModel(BaseModel):'
696
697
697 # target repo
698 # target repo
698 target_repo = pull_request.target_repo.scm_instance()
699 target_repo = pull_request.target_repo.scm_instance()
700
699 try:
701 try:
700 target_commit = target_repo.get_commit(commit_id=target_ref_name)
702 target_commit = target_repo.get_commit(commit_id=target_ref_name)
701 except CommitDoesNotExistError:
703 except CommitDoesNotExistError:
@@ -752,8 +754,8 b' class PullRequestModel(BaseModel):'
752 target_commit.raw_id, source_commit.raw_id, source_repo, merge=True,
754 target_commit.raw_id, source_commit.raw_id, source_repo, merge=True,
753 pre_load=pre_load)
755 pre_load=pre_load)
754
756
755 ancestor = target_repo.get_common_ancestor(
757 ancestor = source_repo.get_common_ancestor(
756 target_commit.raw_id, source_commit.raw_id, source_repo)
758 source_commit.raw_id, target_commit.raw_id, target_repo)
757
759
758 pull_request.source_ref = '%s:%s:%s' % (
760 pull_request.source_ref = '%s:%s:%s' % (
759 source_ref_type, source_ref_name, source_commit.raw_id)
761 source_ref_type, source_ref_name, source_commit.raw_id)
@@ -1314,10 +1316,21 b' class PullRequestModel(BaseModel):'
1314 merge_state = self._refresh_merge_state(
1316 merge_state = self._refresh_merge_state(
1315 pull_request, target_vcs, target_ref)
1317 pull_request, target_vcs, target_ref)
1316 else:
1318 else:
1317 possible = pull_request.\
1319 possible = pull_request.last_merge_status == MergeFailureReason.NONE
1318 last_merge_status == MergeFailureReason.NONE
1320 metadata = {
1321 'target_ref': pull_request.target_ref_parts,
1322 'source_ref': pull_request.source_ref_parts,
1323 }
1324 if not possible and target_ref.type == 'branch':
1325 # NOTE(marcink): case for mercurial multiple heads on branch
1326 heads = target_vcs._heads(target_ref.name)
1327 if len(heads) != 1:
1328 heads = '\n,'.join(target_vcs._heads(target_ref.name))
1329 metadata.update({
1330 'heads': heads
1331 })
1319 merge_state = MergeResponse(
1332 merge_state = MergeResponse(
1320 possible, False, None, pull_request.last_merge_status)
1333 possible, False, None, pull_request.last_merge_status, metadata=metadata)
1321
1334
1322 return merge_state
1335 return merge_state
1323
1336
@@ -1326,6 +1339,7 b' class PullRequestModel(BaseModel):'
1326 name_or_id = reference.name
1339 name_or_id = reference.name
1327 else:
1340 else:
1328 name_or_id = reference.commit_id
1341 name_or_id = reference.commit_id
1342
1329 refreshed_commit = vcs_repository.get_commit(name_or_id)
1343 refreshed_commit = vcs_repository.get_commit(name_or_id)
1330 refreshed_reference = Reference(
1344 refreshed_reference = Reference(
1331 reference.type, reference.name, refreshed_commit.raw_id)
1345 reference.type, reference.name, refreshed_commit.raw_id)
@@ -192,14 +192,14 b' class RepoModel(BaseModel):'
192 return repo_log
192 return repo_log
193
193
194 @classmethod
194 @classmethod
195 def update_repoinfo(cls, repositories=None):
195 def update_commit_cache(cls, repositories=None):
196 if not repositories:
196 if not repositories:
197 repositories = Repository.getAll()
197 repositories = Repository.getAll()
198 for repo in repositories:
198 for repo in repositories:
199 repo.update_commit_cache()
199 repo.update_commit_cache()
200
200
201 def get_repos_as_dict(self, repo_list=None, admin=False,
201 def get_repos_as_dict(self, repo_list=None, admin=False,
202 super_user_actions=False):
202 super_user_actions=False, short_name=None):
203 _render = get_current_request().get_partial_renderer(
203 _render = get_current_request().get_partial_renderer(
204 'rhodecode:templates/data_table/_dt_elements.mako')
204 'rhodecode:templates/data_table/_dt_elements.mako')
205 c = _render.get_call_context()
205 c = _render.get_call_context()
@@ -208,8 +208,12 b' class RepoModel(BaseModel):'
208 return _render('quick_menu', repo_name)
208 return _render('quick_menu', repo_name)
209
209
210 def repo_lnk(name, rtype, rstate, private, archived, fork_of):
210 def repo_lnk(name, rtype, rstate, private, archived, fork_of):
211 if short_name is not None:
212 short_name_var = short_name
213 else:
214 short_name_var = not admin
211 return _render('repo_name', name, rtype, rstate, private, archived, fork_of,
215 return _render('repo_name', name, rtype, rstate, private, archived, fork_of,
212 short_name=not admin, admin=False)
216 short_name=short_name_var, admin=False)
213
217
214 def last_change(last_change):
218 def last_change(last_change):
215 if admin and isinstance(last_change, datetime.datetime) and not last_change.tzinfo:
219 if admin and isinstance(last_change, datetime.datetime) and not last_change.tzinfo:
@@ -250,8 +254,8 b' class RepoModel(BaseModel):'
250 repo.private, repo.archived, repo.fork),
254 repo.private, repo.archived, repo.fork),
251 "name_raw": repo.repo_name.lower(),
255 "name_raw": repo.repo_name.lower(),
252
256
253 "last_change": last_change(repo.last_db_change),
257 "last_change": last_change(repo.last_commit_change),
254 "last_change_raw": datetime_to_time(repo.last_db_change),
258 "last_change_raw": datetime_to_time(repo.last_commit_change),
255
259
256 "last_changeset": last_rev(repo.repo_name, cs_cache),
260 "last_changeset": last_rev(repo.repo_name, cs_cache),
257 "last_changeset_raw": cs_cache.get('revision'),
261 "last_changeset_raw": cs_cache.get('revision'),
@@ -97,6 +97,8 b' class RepoGroupModel(BaseModel):'
97 return string.Template(template).safe_substitute(
97 return string.Template(template).safe_substitute(
98 username=user.username,
98 username=user.username,
99 user_id=user.user_id,
99 user_id=user.user_id,
100 first_name=user.first_name,
101 last_name=user.last_name,
100 )
102 )
101
103
102 def create_personal_repo_group(self, user, commit_early=True):
104 def create_personal_repo_group(self, user, commit_early=True):
@@ -307,6 +309,10 b' class RepoGroupModel(BaseModel):'
307 # trigger the post hook
309 # trigger the post hook
308 from rhodecode.lib.hooks_base import log_create_repository_group
310 from rhodecode.lib.hooks_base import log_create_repository_group
309 repo_group = RepoGroup.get_by_group_name(group_name)
311 repo_group = RepoGroup.get_by_group_name(group_name)
312
313 # update repo group commit caches initially
314 repo_group.update_commit_cache()
315
310 log_create_repository_group(
316 log_create_repository_group(
311 created_by=user.username, **repo_group.get_dict())
317 created_by=user.username, **repo_group.get_dict())
312
318
@@ -684,6 +690,13 b' class RepoGroupModel(BaseModel):'
684 'revoked permission from usergroup: {} on repogroup: {}'.format(
690 'revoked permission from usergroup: {} on repogroup: {}'.format(
685 group_name, repo_group), namespace='security.repogroup')
691 group_name, repo_group), namespace='security.repogroup')
686
692
693 @classmethod
694 def update_commit_cache(cls, repo_groups=None):
695 if not repo_groups:
696 repo_groups = RepoGroup.getAll()
697 for repo_group in repo_groups:
698 repo_group.update_commit_cache()
699
687 def get_repo_groups_as_dict(self, repo_group_list=None, admin=False,
700 def get_repo_groups_as_dict(self, repo_group_list=None, admin=False,
688 super_user_actions=False):
701 super_user_actions=False):
689
702
@@ -705,6 +718,11 b' class RepoGroupModel(BaseModel):'
705 (datetime.datetime.now() - datetime.datetime.utcnow()).seconds)
718 (datetime.datetime.now() - datetime.datetime.utcnow()).seconds)
706 return _render("last_change", last_change)
719 return _render("last_change", last_change)
707
720
721 def last_rev(repo_name, cs_cache):
722 return _render('revision', repo_name, cs_cache.get('revision'),
723 cs_cache.get('raw_id'), cs_cache.get('author'),
724 cs_cache.get('message'), cs_cache.get('date'))
725
708 def desc(desc, personal):
726 def desc(desc, personal):
709 return _render(
727 return _render(
710 'repo_group_desc', desc, personal, c.visual.stylify_metatags)
728 'repo_group_desc', desc, personal, c.visual.stylify_metatags)
@@ -721,13 +739,19 b' class RepoGroupModel(BaseModel):'
721
739
722 repo_group_data = []
740 repo_group_data = []
723 for group in repo_group_list:
741 for group in repo_group_list:
742 cs_cache = group.changeset_cache
743 last_repo_name = cs_cache.get('source_repo_name')
724
744
725 row = {
745 row = {
726 "menu": quick_menu(group.group_name),
746 "menu": quick_menu(group.group_name),
727 "name": repo_group_lnk(group.group_name),
747 "name": repo_group_lnk(group.group_name),
728 "name_raw": group.group_name,
748 "name_raw": group.group_name,
729 "last_change": last_change(group.last_db_change),
749 "last_change": last_change(group.last_commit_change),
730 "last_change_raw": datetime_to_time(group.last_db_change),
750 "last_change_raw": datetime_to_time(group.last_commit_change),
751
752 "last_changeset": "",
753 "last_changeset_raw": "",
754
731 "desc": desc(group.description_safe, group.personal),
755 "desc": desc(group.description_safe, group.personal),
732 "top_level_repos": 0,
756 "top_level_repos": 0,
733 "owner": user_profile(group.user.username)
757 "owner": user_profile(group.user.username)
@@ -818,6 +818,8 b' class ScmModel(BaseModel):'
818 repo_name=repo.repo_name, repo_alias=scm_instance.alias,
818 repo_name=repo.repo_name, repo_alias=scm_instance.alias,
819 commit_ids=[tip.raw_id])
819 commit_ids=[tip.raw_id])
820
820
821 return tip
822
821 def delete_nodes(self, user, repo, message, nodes, parent_commit=None,
823 def delete_nodes(self, user, repo, message, nodes, parent_commit=None,
822 author=None, trigger_push_hook=True):
824 author=None, trigger_push_hook=True):
823 """
825 """
@@ -119,6 +119,7 b' class SettingsModel(BaseModel):'
119 new_ui.ui_value = val
119 new_ui.ui_value = val
120 new_ui.ui_active = active
120 new_ui.ui_active = active
121
121
122 repository_id = ''
122 if self.repo:
123 if self.repo:
123 repo = self._get_repo(self.repo)
124 repo = self._get_repo(self.repo)
124 repository_id = repo.repo_id
125 repository_id = repo.repo_id
@@ -440,26 +441,39 b' class VcsSettingsModel(object):'
440 HOOKS_SETTINGS = (
441 HOOKS_SETTINGS = (
441 ('hooks', 'changegroup.repo_size'),
442 ('hooks', 'changegroup.repo_size'),
442 ('hooks', 'changegroup.push_logger'),
443 ('hooks', 'changegroup.push_logger'),
443 ('hooks', 'outgoing.pull_logger'),)
444 ('hooks', 'outgoing.pull_logger'),
445 )
444 HG_SETTINGS = (
446 HG_SETTINGS = (
445 ('extensions', 'largefiles'),
447 ('extensions', 'largefiles'),
446 ('phases', 'publish'),
448 ('phases', 'publish'),
447 ('extensions', 'evolve'),)
449 ('extensions', 'evolve'),
450 ('extensions', 'topic'),
451 ('experimental', 'evolution'),
452 ('experimental', 'evolution.exchange'),
453 )
448 GIT_SETTINGS = (
454 GIT_SETTINGS = (
449 ('vcs_git_lfs', 'enabled'),)
455 ('vcs_git_lfs', 'enabled'),
456 )
450 GLOBAL_HG_SETTINGS = (
457 GLOBAL_HG_SETTINGS = (
451 ('extensions', 'largefiles'),
458 ('extensions', 'largefiles'),
452 ('largefiles', 'usercache'),
459 ('largefiles', 'usercache'),
453 ('phases', 'publish'),
460 ('phases', 'publish'),
454 ('extensions', 'hgsubversion'),
461 ('extensions', 'hgsubversion'),
455 ('extensions', 'evolve'),)
462 ('extensions', 'evolve'),
463 ('extensions', 'topic'),
464 ('experimental', 'evolution'),
465 ('experimental', 'evolution.exchange'),
466 )
467
456 GLOBAL_GIT_SETTINGS = (
468 GLOBAL_GIT_SETTINGS = (
457 ('vcs_git_lfs', 'enabled'),
469 ('vcs_git_lfs', 'enabled'),
458 ('vcs_git_lfs', 'store_location'))
470 ('vcs_git_lfs', 'store_location')
471 )
459
472
460 GLOBAL_SVN_SETTINGS = (
473 GLOBAL_SVN_SETTINGS = (
461 ('vcs_svn_proxy', 'http_requests_enabled'),
474 ('vcs_svn_proxy', 'http_requests_enabled'),
462 ('vcs_svn_proxy', 'http_server_url'))
475 ('vcs_svn_proxy', 'http_server_url')
476 )
463
477
464 SVN_BRANCH_SECTION = 'vcs_svn_branch'
478 SVN_BRANCH_SECTION = 'vcs_svn_branch'
465 SVN_TAG_SECTION = 'vcs_svn_tag'
479 SVN_TAG_SECTION = 'vcs_svn_tag'
@@ -574,12 +588,38 b' class VcsSettingsModel(object):'
574 def create_repo_svn_settings(self, data):
588 def create_repo_svn_settings(self, data):
575 return self._create_svn_settings(self.repo_settings, data)
589 return self._create_svn_settings(self.repo_settings, data)
576
590
591 def _set_evolution(self, settings, is_enabled):
592 if is_enabled:
593 # if evolve is active set evolution=all
594
595 self._create_or_update_ui(
596 settings, *('experimental', 'evolution'), value='all',
597 active=True)
598 self._create_or_update_ui(
599 settings, *('experimental', 'evolution.exchange'), value='yes',
600 active=True)
601 # if evolve is active set topics server support
602 self._create_or_update_ui(
603 settings, *('extensions', 'topic'), value='',
604 active=True)
605
606 else:
607 self._create_or_update_ui(
608 settings, *('experimental', 'evolution'), value='',
609 active=False)
610 self._create_or_update_ui(
611 settings, *('experimental', 'evolution.exchange'), value='no',
612 active=False)
613 self._create_or_update_ui(
614 settings, *('extensions', 'topic'), value='',
615 active=False)
616
577 @assert_repo_settings
617 @assert_repo_settings
578 def create_or_update_repo_hg_settings(self, data):
618 def create_or_update_repo_hg_settings(self, data):
579 largefiles, phases, evolve = \
619 largefiles, phases, evolve = \
580 self.HG_SETTINGS
620 self.HG_SETTINGS[:3]
581 largefiles_key, phases_key, evolve_key = \
621 largefiles_key, phases_key, evolve_key = \
582 self._get_settings_keys(self.HG_SETTINGS, data)
622 self._get_settings_keys(self.HG_SETTINGS[:3], data)
583
623
584 self._create_or_update_ui(
624 self._create_or_update_ui(
585 self.repo_settings, *largefiles, value='',
625 self.repo_settings, *largefiles, value='',
@@ -587,21 +627,22 b' class VcsSettingsModel(object):'
587 self._create_or_update_ui(
627 self._create_or_update_ui(
588 self.repo_settings, *evolve, value='',
628 self.repo_settings, *evolve, value='',
589 active=data[evolve_key])
629 active=data[evolve_key])
630 self._set_evolution(self.repo_settings, is_enabled=data[evolve_key])
631
590 self._create_or_update_ui(
632 self._create_or_update_ui(
591 self.repo_settings, *phases, value=safe_str(data[phases_key]))
633 self.repo_settings, *phases, value=safe_str(data[phases_key]))
592
634
593 def create_or_update_global_hg_settings(self, data):
635 def create_or_update_global_hg_settings(self, data):
594 largefiles, largefiles_store, phases, hgsubversion, evolve \
636 largefiles, largefiles_store, phases, hgsubversion, evolve \
595 = self.GLOBAL_HG_SETTINGS
637 = self.GLOBAL_HG_SETTINGS[:5]
596 largefiles_key, largefiles_store_key, phases_key, subversion_key, evolve_key \
638 largefiles_key, largefiles_store_key, phases_key, subversion_key, evolve_key \
597 = self._get_settings_keys(self.GLOBAL_HG_SETTINGS, data)
639 = self._get_settings_keys(self.GLOBAL_HG_SETTINGS[:5], data)
598
640
599 self._create_or_update_ui(
641 self._create_or_update_ui(
600 self.global_settings, *largefiles, value='',
642 self.global_settings, *largefiles, value='',
601 active=data[largefiles_key])
643 active=data[largefiles_key])
602 self._create_or_update_ui(
644 self._create_or_update_ui(
603 self.global_settings, *largefiles_store,
645 self.global_settings, *largefiles_store, value=data[largefiles_store_key])
604 value=data[largefiles_store_key])
605 self._create_or_update_ui(
646 self._create_or_update_ui(
606 self.global_settings, *phases, value=safe_str(data[phases_key]))
647 self.global_settings, *phases, value=safe_str(data[phases_key]))
607 self._create_or_update_ui(
648 self._create_or_update_ui(
@@ -609,9 +650,10 b' class VcsSettingsModel(object):'
609 self._create_or_update_ui(
650 self._create_or_update_ui(
610 self.global_settings, *evolve, value='',
651 self.global_settings, *evolve, value='',
611 active=data[evolve_key])
652 active=data[evolve_key])
653 self._set_evolution(self.global_settings, is_enabled=data[evolve_key])
612
654
613 def create_or_update_repo_git_settings(self, data):
655 def create_or_update_repo_git_settings(self, data):
614 # NOTE(marcink): # comma make unpack work properly
656 # NOTE(marcink): # comma makes unpack work properly
615 lfs_enabled, \
657 lfs_enabled, \
616 = self.GIT_SETTINGS
658 = self.GIT_SETTINGS
617
659
@@ -675,6 +717,7 b' class VcsSettingsModel(object):'
675 def get_repo_ui_settings(self, section=None, key=None):
717 def get_repo_ui_settings(self, section=None, key=None):
676 global_uis = self.global_settings.get_ui(section, key)
718 global_uis = self.global_settings.get_ui(section, key)
677 repo_uis = self.repo_settings.get_ui(section, key)
719 repo_uis = self.repo_settings.get_ui(section, key)
720
678 filtered_repo_uis = self._filter_ui_settings(repo_uis)
721 filtered_repo_uis = self._filter_ui_settings(repo_uis)
679 filtered_repo_uis_keys = [
722 filtered_repo_uis_keys = [
680 (s.section, s.key) for s in filtered_repo_uis]
723 (s.section, s.key) for s in filtered_repo_uis]
@@ -24,10 +24,15 b' import traceback'
24 import sshpubkeys
24 import sshpubkeys
25 import sshpubkeys.exceptions
25 import sshpubkeys.exceptions
26
26
27 from cryptography.hazmat.primitives.asymmetric import rsa
28 from cryptography.hazmat.primitives import serialization as crypto_serialization
29 from cryptography.hazmat.backends import default_backend as crypto_default_backend
30
27 from rhodecode.model import BaseModel
31 from rhodecode.model import BaseModel
28 from rhodecode.model.db import UserSshKeys
32 from rhodecode.model.db import UserSshKeys
29 from rhodecode.model.meta import Session
33 from rhodecode.model.meta import Session
30
34
35
31 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
32
37
33
38
@@ -62,16 +67,24 b' class SshKeyModel(BaseModel):'
62 raise
67 raise
63
68
64 def generate_keypair(self, comment=None):
69 def generate_keypair(self, comment=None):
65 from Crypto.PublicKey import RSA
66
67 key = RSA.generate(2048)
68 private = key.exportKey('PEM')
69
70
70 pubkey = key.publickey()
71 key = rsa.generate_private_key(
71 public = pubkey.exportKey('OpenSSH')
72 backend=crypto_default_backend(),
73 public_exponent=65537,
74 key_size=2048
75 )
76 private_key = key.private_bytes(
77 crypto_serialization.Encoding.PEM,
78 crypto_serialization.PrivateFormat.PKCS8,
79 crypto_serialization.NoEncryption())
80 public_key = key.public_key().public_bytes(
81 crypto_serialization.Encoding.OpenSSH,
82 crypto_serialization.PublicFormat.OpenSSH
83 )
84
72 if comment:
85 if comment:
73 public = public + " " + comment
86 public_key = public_key + " " + comment
74 return private, public
87 return private_key, public_key
75
88
76 def create(self, user, fingerprint, key_data, description):
89 def create(self, user, fingerprint, key_data, description):
77 """
90 """
@@ -14,11 +14,11 b' input[type="button"] {'
14 font-family: @text-light;
14 font-family: @text-light;
15 text-decoration: none;
15 text-decoration: none;
16 text-shadow: none;
16 text-shadow: none;
17 color: @grey4;
17 color: @grey2;
18 background-color: white;
18 background-color: white;
19 background-image: none;
19 background-image: none;
20 border: none;
20 border: none;
21 .border ( @border-thickness-buttons, @grey4 );
21 .border ( @border-thickness-buttons, @grey5 );
22 .border-radius (@border-radius);
22 .border-radius (@border-radius);
23 cursor: pointer;
23 cursor: pointer;
24 white-space: nowrap;
24 white-space: nowrap;
@@ -26,6 +26,10 b' input[type="button"] {'
26 -moz-transition: background .3s,color .3s;
26 -moz-transition: background .3s,color .3s;
27 -o-transition: background .3s,color .3s;
27 -o-transition: background .3s,color .3s;
28 transition: background .3s,color .3s;
28 transition: background .3s,color .3s;
29 box-shadow: @button-shadow;
30 -webkit-box-shadow: @button-shadow;
31
32
29
33
30 a {
34 a {
31 display: block;
35 display: block;
@@ -44,8 +48,9 b' input[type="button"] {'
44 outline:none;
48 outline:none;
45 }
49 }
46 &:hover {
50 &:hover {
47 color: white;
51 color: @rcdarkblue;
48 background-color: @grey4;
52 background-color: @white;
53 .border ( @border-thickness, @grey4 );
49 }
54 }
50
55
51 .icon-remove-sign {
56 .icon-remove-sign {
@@ -70,26 +75,26 b' input[type="button"] {'
70
75
71
76
72 .btn-default {
77 .btn-default {
73 .border ( @border-thickness-buttons, @rcblue );
78 border: @border-thickness solid @grey5;
74 background-image: none;
79 background-image: none;
75 color: @rcblue;
80 color: @grey2;
76
81
77 a {
82 a {
78 color: @rcblue;
83 color: @grey2;
79 }
84 }
80
85
81 &:hover,
86 &:hover,
82 &.active {
87 &.active {
83 color: white;
88 color: @rcdarkblue;
84 background-color: @rcdarkblue;
89 background-color: @white;
85 .border ( @border-thickness, @rcdarkblue );
90 .border ( @border-thickness, @grey4 );
86
91
87 a {
92 a {
88 color: white;
93 color: @grey2;
89 }
94 }
90 }
95 }
91 &:disabled {
96 &:disabled {
92 .border ( @border-thickness-buttons, @grey4 );
97 .border ( @border-thickness-buttons, @grey5 );
93 background-color: transparent;
98 background-color: transparent;
94 }
99 }
95 }
100 }
@@ -326,6 +331,7 b' input[type="submit"] {'
326 .border ( @border-thickness-buttons, @rcblue );
331 .border ( @border-thickness-buttons, @rcblue );
327 background-color: @rcblue;
332 background-color: @rcblue;
328 color: white;
333 color: white;
334 opacity: 0.5;
329 }
335 }
330 }
336 }
331
337
@@ -416,3 +422,23 b' input[type="reset"] {'
416 }
422 }
417 }
423 }
418
424
425
426 .button-links {
427 float: left;
428 display: inline;
429 margin: 0;
430 padding-left: 0;
431 list-style: none;
432 text-align: right;
433
434 li {
435
436
437 }
438
439 li.active {
440 background-color: @grey6;
441 .border ( @border-thickness, @grey4 );
442 }
443
444 }
@@ -404,12 +404,9 b' div.codeblock {'
404
404
405 // TODO: johbo: Added interim to get rid of the margin around
405 // TODO: johbo: Added interim to get rid of the margin around
406 // Select2 widgets. This needs further cleanup.
406 // Select2 widgets. This needs further cleanup.
407 margin-top: @padding;
408
409 overflow: auto;
407 overflow: auto;
410 padding: 0px;
408 padding: 0px;
411 border: @border-thickness solid @grey5;
409 border: @border-thickness solid @grey6;
412 background: @grey6;
413 .border-radius(@border-radius);
410 .border-radius(@border-radius);
414
411
415 #remove_gist {
412 #remove_gist {
@@ -479,7 +476,7 b' div.codeblock {'
479 }
476 }
480
477
481 .code-body {
478 .code-body {
482 padding: @padding;
479 padding: 0.8em 1em;
483 background-color: #ffffff;
480 background-color: #ffffff;
484 min-width: 100%;
481 min-width: 100%;
485 box-sizing: border-box;
482 box-sizing: border-box;
@@ -492,6 +489,21 b' div.codeblock {'
492 height: auto;
489 height: auto;
493 width: 100%;
490 width: 100%;
494 }
491 }
492
493 .markdown-block {
494 padding: 1em 0;
495 }
496 }
497
498 .codeblock-header {
499 background: @grey7;
500 height: 36px;
501 }
502
503 .path {
504 border-bottom: 1px solid @grey6;
505 padding: .65em 1em;
506 height: 18px;
495 }
507 }
496 }
508 }
497
509
@@ -27,7 +27,7 b''
27
27
28 .CodeMirror-gutters {
28 .CodeMirror-gutters {
29 border-right: 1px solid #ddd;
29 border-right: 1px solid #ddd;
30 background-color: @grey6;
30 background-color: white;
31 white-space: nowrap;
31 white-space: nowrap;
32 }
32 }
33 .CodeMirror-linenumbers {}
33 .CodeMirror-linenumbers {}
@@ -426,7 +426,7 b' form.comment-form {'
426
426
427 .comment-form-login {
427 .comment-form-login {
428 .comment-help {
428 .comment-help {
429 padding: 0.9em; //same as the button
429 padding: 0.7em; //same as the button
430 }
430 }
431
431
432 div.clearfix {
432 div.clearfix {
@@ -38,7 +38,7 b''
38
38
39 .form-control {
39 .form-control {
40 width: 100%;
40 width: 100%;
41 padding: 0.9em;
41 padding: 0.7em;
42 border: 1px solid #979797;
42 border: 1px solid #979797;
43 border-radius: 2px;
43 border-radius: 2px;
44 }
44 }
@@ -231,6 +231,11 b' form.rcform {'
231
231
232 .drop-menu {
232 .drop-menu {
233 float: left;
233 float: left;
234
235 & + .last-item {
236 margin: 0;
237 }
238
234 margin: 0 @input-padding 0 0;
239 margin: 0 @input-padding 0 0;
235 }
240 }
236
241
@@ -271,14 +276,15 b' form.rcform {'
271 .badged-field {
276 .badged-field {
272 .user-badge {
277 .user-badge {
273 line-height: 25px;
278 line-height: 25px;
274 padding: 10px 5px;
279 padding: .4em;
275 border-radius: @border-radius;
280 border-radius: @border-radius;
276 border-top: 1px solid @rclightblue;
281 border-top: 1px solid @grey4;
277 border-left: 1px solid @rclightblue;
282 border-left: 1px solid @grey4;
278 border-bottom: 1px solid @rclightblue;
283 border-bottom: 1px solid @grey4;
279 font-size: 14px;
284 font-size: 14px;
280 font-style: normal;
285 font-style: normal;
281 color: @text-light;
286 color: @text-light;
287 background: @grey7;
282 display: inline-block;
288 display: inline-block;
283 vertical-align: top;
289 vertical-align: top;
284 cursor: default;
290 cursor: default;
@@ -212,6 +212,13 b' div.markdown-block strong {'
212 margin: 0;
212 margin: 0;
213 }
213 }
214
214
215 div.markdown-block ul.checkbox,
216 div.markdown-block ol.checkbox {
217 padding-left: 20px !important;
218 margin-top: 0px !important;
219 margin-bottom: 18px !important;
220 }
221
215 div.markdown-block ul,
222 div.markdown-block ul,
216 div.markdown-block ol {
223 div.markdown-block ol {
217 padding-left: 30px !important;
224 padding-left: 30px !important;
@@ -219,6 +226,13 b' div.markdown-block ol {'
219 margin-bottom: 18px !important;
226 margin-bottom: 18px !important;
220 }
227 }
221
228
229 div.markdown-block ul.checkbox li,
230 div.markdown-block ol.checkbox li {
231 list-style: none !important;
232 margin: 6px !important;
233 padding: 0 !important;
234 }
235
222 div.markdown-block ul li,
236 div.markdown-block ul li,
223 div.markdown-block ol li {
237 div.markdown-block ol li {
224 list-style: disc !important;
238 list-style: disc !important;
@@ -198,15 +198,16 b''
198 }
198 }
199
199
200 .user-menu.submenu {
200 .user-menu.submenu {
201 right: 0;
201 right: 0!important;
202 left: auto;
202 left: auto!important;
203 min-width: 290px;
203 min-width: 290px;
204 }
204 }
205
205
206
207 .user-menu {
206 .user-menu {
208 .bookmark-items {
207 .bookmark-items {
209 padding: 4px 2px;
208 border-top: @border-thickness solid @grey6;
209 margin-top: 1em;
210 padding: 1em .5em;
210 color: @grey3;
211 color: @grey3;
211 border-bottom: @grey3;
212 border-bottom: @grey3;
212
213
@@ -227,8 +228,10 b''
227 padding: @menupadding;
228 padding: @menupadding;
228 z-index: 999;
229 z-index: 999;
229 overflow: hidden;
230 overflow: hidden;
230 background-color: @grey6;
231 background-color: @white;
232 border: 1px solid @grey5;
231 color: @grey2;
233 color: @grey2;
234 box-shadow: @dropdown-shadow;
232
235
233 h4 {
236 h4 {
234 margin-bottom: 12px;
237 margin-bottom: 12px;
@@ -289,15 +292,16 b''
289 .big_gravatar {
292 .big_gravatar {
290 float: left;
293 float: left;
291 display: block;
294 display: block;
292 margin-top: .5em;
295 padding: .5em;
293 }
296 }
294
297
295 .full_name,
298 .full_name {
296 .email {
299 margin: 0 0 0 70px;
297 margin: 0 0 0 65px;
300 padding-top: 1em;
298 }
301 }
299
302
300 .email {
303 .email {
304 margin: 0 0 0 70px;
301 font-family: @text-light;
305 font-family: @text-light;
302 }
306 }
303
307
@@ -307,8 +311,6 b''
307 padding: @padding 0 0 0;
311 padding: @padding 0 0 0;
308
312
309 li {
313 li {
310 border-top: @border-thickness solid @grey5;
311
312 input {
314 input {
313 margin: @padding 0 0 0;
315 margin: @padding 0 0 0;
314 }
316 }
@@ -107,6 +107,12 b' input + .action-link, .action-link.first'
107
107
108 .clipboard-action {
108 .clipboard-action {
109 cursor: pointer;
109 cursor: pointer;
110 color: @grey4;
111 margin-left: 5px;
112
113 &:hover {
114 color: @grey2;
115 }
110 }
116 }
111
117
112 ul.simple-list{
118 ul.simple-list{
@@ -237,7 +243,7 b' input.inline[type="file"] {'
237 position: relative;
243 position: relative;
238 vertical-align: bottom;
244 vertical-align: bottom;
239 padding: 0 @header-padding;
245 padding: 0 @header-padding;
240 background-color: @grey2;
246 background-color: @grey1;
241 color: @grey5;
247 color: @grey5;
242
248
243 .title {
249 .title {
@@ -271,7 +277,9 b' input.inline[type="file"] {'
271 // Gists
277 // Gists
272 #files_data {
278 #files_data {
273 clear: both; //for firefox
279 clear: both; //for firefox
274 }
280 padding-top: 10px;
281 }
282
275 #gistid {
283 #gistid {
276 margin-right: @padding;
284 margin-right: @padding;
277 }
285 }
@@ -516,7 +524,7 b' ul.auth_plugins {'
516 text-align: center;
524 text-align: center;
517 vertical-align: middle;
525 vertical-align: middle;
518 color: @grey2;
526 color: @grey2;
519 background-color: @grey6;
527 font-size: 11px;
520
528
521 p {
529 p {
522 margin: 0;
530 margin: 0;
@@ -605,10 +613,20 b' button.close {'
605 }
613 }
606
614
607
615
608 input {
616 input, textarea {
609 &.disabled {
617 &.disabled {
610 opacity: .5;
618 opacity: .5;
611 }
619 }
620
621 &:hover {
622 border-color: @grey3;
623 box-shadow: @button-shadow;
624 }
625
626 &:focus {
627 border-color: @rcblue;
628 box-shadow: @button-shadow;
629 }
612 }
630 }
613
631
614 // remove extra padding in firefox
632 // remove extra padding in firefox
@@ -643,16 +661,20 b' select {'
643 padding: 0 18px 0 8px;
661 padding: 0 18px 0 8px;
644 line-height:1em;
662 line-height:1em;
645 font-size: @basefontsize;
663 font-size: @basefontsize;
646 border: @border-thickness solid @rcblue;
664 border: @border-thickness solid @grey5;
665 border-radius: @border-radius;
647 background:white url("../images/dt-arrow-dn.png") no-repeat 100% 50%;
666 background:white url("../images/dt-arrow-dn.png") no-repeat 100% 50%;
648 color: @rcblue;
667 color: @grey4;
668 box-shadow: @button-shadow;
649
669
650 &:after {
670 &:after {
651 content: "\00A0\25BE";
671 content: "\00A0\25BE";
652 }
672 }
653
673
654 &:focus {
674 &:focus, &:hover {
655 outline: none;
675 outline: none;
676 border-color: @grey4;
677 color: @rcdarkblue;
656 }
678 }
657 }
679 }
658
680
@@ -712,8 +734,8 b' label {'
712 margin: -5px 0;
734 margin: -5px 0;
713 padding: 0;
735 padding: 0;
714 line-height: 1em;
736 line-height: 1em;
715 border: 1px solid @grey4;
716 box-sizing: content-box;
737 box-sizing: content-box;
738 border-radius: 50%;
717
739
718 &.gravatar-large {
740 &.gravatar-large {
719 margin: -0.5em .25em -0.5em 0;
741 margin: -0.5em .25em -0.5em 0;
@@ -938,9 +960,6 b' label {'
938 }
960 }
939
961
940
962
941 #graph_nodes {
942 padding-top: 43px;
943 }
944
963
945 #graph_content{
964 #graph_content{
946
965
@@ -973,13 +992,12 b' label {'
973 }
992 }
974
993
975 .graph-col-wrapper {
994 .graph-col-wrapper {
976 padding-left: 110px;
977
995
978 #graph_nodes {
996 #graph_nodes {
979 width: 100px;
997 width: 100px;
980 margin-left: -110px;
998 position: absolute;
981 float: left;
999 left: 70px;
982 clear: left;
1000 z-index: -1;
983 }
1001 }
984 }
1002 }
985
1003
@@ -996,6 +1014,16 b' label {'
996 }
1014 }
997 }
1015 }
998
1016
1017 .obsolete-toggle {
1018 line-height: 30px;
1019 margin-left: -15px;
1020 }
1021
1022 #rev_range_container, #rev_range_clear, #rev_range_more {
1023 margin-top: -5px;
1024 margin-bottom: -5px;
1025 }
1026
999 #filter_changelog {
1027 #filter_changelog {
1000 float: left;
1028 float: left;
1001 }
1029 }
@@ -1029,6 +1057,10 b' label {'
1029 padding: 9px 2px;
1057 padding: 9px 2px;
1030 line-height: 1em;
1058 line-height: 1em;
1031 font-size: @navigation-fontsize;
1059 font-size: @navigation-fontsize;
1060
1061 a {
1062 color: @grey5
1063 }
1032 }
1064 }
1033
1065
1034 img {
1066 img {
@@ -1047,7 +1079,7 b' label {'
1047 }
1079 }
1048
1080
1049 .flag_status {
1081 .flag_status {
1050 margin: 2px 8px 6px 2px;
1082 margin: 2px;
1051 &.under_review {
1083 &.under_review {
1052 .circle(5px, @alert3);
1084 .circle(5px, @alert3);
1053 }
1085 }
@@ -1218,24 +1250,37 b' table.integrations {'
1218
1250
1219 .autocomplete-suggestions {
1251 .autocomplete-suggestions {
1220 width: auto !important; // overrides autocomplete.js
1252 width: auto !important; // overrides autocomplete.js
1253 min-width: 278px;
1221 margin: 0;
1254 margin: 0;
1222 border: @border-thickness solid @rcblue;
1255 border: @border-thickness solid @grey5;
1223 border-radius: @border-radius;
1256 border-radius: @border-radius;
1224 color: @rcblue;
1257 color: @grey2;
1225 background-color: white;
1258 background-color: white;
1226 }
1259 }
1260
1261 .autocomplete-qfilter-suggestions {
1262 width: auto !important; // overrides autocomplete.js
1263 max-height: 100% !important;
1264 min-width: 376px;
1265 margin: 0;
1266 border: @border-thickness solid @grey5;
1267 color: @grey2;
1268 background-color: white;
1269 }
1270
1227 .autocomplete-selected {
1271 .autocomplete-selected {
1228 background: #F0F0F0;
1272 background: #F0F0F0;
1229 }
1273 }
1274
1230 .ac-container-wrap {
1275 .ac-container-wrap {
1231 margin: 0;
1276 margin: 0;
1232 padding: 8px;
1277 padding: 8px;
1233 border-bottom: @border-thickness solid @rclightblue;
1278 border-bottom: @border-thickness solid @grey5;
1234 list-style-type: none;
1279 list-style-type: none;
1235 cursor: pointer;
1280 cursor: pointer;
1236
1281
1237 &:hover {
1282 &:hover {
1238 background-color: @rclightblue;
1283 background-color: @grey7;
1239 }
1284 }
1240
1285
1241 img {
1286 img {
@@ -1292,7 +1337,7 b' table.integrations {'
1292
1337
1293 #editor_container{
1338 #editor_container {
1294 position: relative;
1339 position: relative;
1295 margin: @padding;
1340 margin: @padding 10px;
1296 }
1341 }
1297 }
1342 }
1298
1343
@@ -1796,7 +1841,6 b' BIN_FILENODE = 7'
1796 }
1841 }
1797
1842
1798 #changeset_compare_view_content {
1843 #changeset_compare_view_content {
1799 margin-bottom: @space;
1800 clear: both;
1844 clear: both;
1801 width: 100%;
1845 width: 100%;
1802 box-sizing: border-box;
1846 box-sizing: border-box;
@@ -2027,15 +2071,15 b' BIN_FILENODE = 7'
2027
2071
2028 // Files
2072 // Files
2029 .edit-file-title {
2073 .edit-file-title {
2030 border-bottom: @border-thickness solid @border-default-color;
2074 font-size: 16px;
2031
2075
2032 .breadcrumbs {
2076 .title-heading {
2033 margin-bottom: 0;
2077 padding: 2px;
2034 }
2078 }
2035 }
2079 }
2036
2080
2037 .edit-file-fieldset {
2081 .edit-file-fieldset {
2038 margin-top: @sidebarpadding;
2082 margin: @sidebarpadding 0;
2039
2083
2040 .fieldset {
2084 .fieldset {
2041 .left-label {
2085 .left-label {
@@ -2080,8 +2124,29 b' BIN_FILENODE = 7'
2080 .new-file,
2124 .new-file,
2081 #filter_activate,
2125 #filter_activate,
2082 #filter_deactivate {
2126 #filter_deactivate {
2083 float: left;
2127 float: right;
2084 margin: 0 0 0 15px;
2128 margin: 0 0 0 10px;
2129 }
2130
2131 .file-upload-transaction-wrapper {
2132 margin-top: 57px;
2133 clear: both;
2134 }
2135
2136 .file-upload-transaction-wrapper .error {
2137 color: @color5;
2138 }
2139
2140 .file-upload-transaction {
2141 min-height: 200px;
2142 padding: 54px;
2143 border: 1px solid @grey5;
2144 text-align: center;
2145 clear: both;
2146 }
2147
2148 .file-upload-transaction i {
2149 font-size: 48px
2085 }
2150 }
2086
2151
2087 h3.files_location{
2152 h3.files_location{
@@ -2089,11 +2154,12 b' h3.files_location{'
2089 }
2154 }
2090
2155
2091 .browser-nav {
2156 .browser-nav {
2157 width: 100%;
2092 display: table;
2158 display: table;
2093 margin-bottom: @space;
2159 margin-bottom: 20px;
2094
2095
2160
2096 .info_box {
2161 .info_box {
2162 float: left;
2097 display: inline-table;
2163 display: inline-table;
2098 height: 2.5em;
2164 height: 2.5em;
2099
2165
@@ -2102,36 +2168,58 b' h3.files_location{'
2102 vertical-align: middle;
2168 vertical-align: middle;
2103 }
2169 }
2104
2170
2171 .drop-menu {
2172 margin: 0 10px;
2173 }
2174
2105 .info_box_elem {
2175 .info_box_elem {
2106 border-top: @border-thickness solid @rcblue;
2176 border-top: @border-thickness solid @grey5;
2107 border-bottom: @border-thickness solid @rcblue;
2177 border-bottom: @border-thickness solid @grey5;
2178 box-shadow: @button-shadow;
2108
2179
2109 #at_rev, a {
2180 #at_rev, a {
2110 padding: 0.6em 0.9em;
2181 padding: 0.6em 0.4em;
2111 margin: 0;
2182 margin: 0;
2112 .box-shadow(none);
2183 .box-shadow(none);
2113 border: 0;
2184 border: 0;
2114 height: 12px;
2185 height: 12px;
2186 color: @grey2;
2115 }
2187 }
2116
2188
2117 input#at_rev {
2189 input#at_rev {
2118 max-width: 50px;
2190 max-width: 50px;
2119 text-align: right;
2191 text-align: center;
2120 }
2192 }
2121
2193
2122 &.previous {
2194 &.previous {
2123 border: @border-thickness solid @rcblue;
2195 border: @border-thickness solid @grey5;
2196 border-top-left-radius: @border-radius;
2197 border-bottom-left-radius: @border-radius;
2198
2199 &:hover {
2200 border-color: @grey4;
2201 }
2202
2124 .disabled {
2203 .disabled {
2125 color: @grey4;
2204 color: @grey5;
2126 cursor: not-allowed;
2205 cursor: not-allowed;
2206 opacity: 0.5;
2127 }
2207 }
2128 }
2208 }
2129
2209
2130 &.next {
2210 &.next {
2131 border: @border-thickness solid @rcblue;
2211 border: @border-thickness solid @grey5;
2212 border-top-right-radius: @border-radius;
2213 border-bottom-right-radius: @border-radius;
2214
2215 &:hover {
2216 border-color: @grey4;
2217 }
2218
2132 .disabled {
2219 .disabled {
2133 color: @grey4;
2220 color: @grey5;
2134 cursor: not-allowed;
2221 cursor: not-allowed;
2222 opacity: 0.5;
2135 }
2223 }
2136 }
2224 }
2137 }
2225 }
@@ -2148,6 +2236,12 b' h3.files_location{'
2148 margin-right: @padding;
2236 margin-right: @padding;
2149 }
2237 }
2150 }
2238 }
2239
2240 }
2241
2242 .select-index-number {
2243 margin: 0 0 0 20px;
2244 color: @grey3;
2151 }
2245 }
2152
2246
2153 .search_activate {
2247 .search_activate {
@@ -2178,25 +2272,53 b' h3.files_location{'
2178 margin: -25px 0px 5px 0px;
2272 margin: -25px 0px 5px 0px;
2179 }
2273 }
2180
2274
2181 .node-filter {
2275 .files-quick-filter {
2182 font-size: @repo-title-fontsize;
2276 float: right;
2183 padding: 4px 0px 0px 0px;
2277 width: 180px;
2184
2278 position: relative;
2185 .node-filter-path {
2279 }
2186 float: left;
2280
2187 color: @grey4;
2281 .files-filter-box {
2188 }
2282 display: flex;
2189 .node-filter-input {
2283 padding: 0px;
2190 float: left;
2284 border-radius: 3px;
2191 margin: -2px 0px 0px 2px;
2285 margin-bottom: 0;
2286
2287 a {
2288 border: none !important;
2289 }
2290
2291 li {
2292 list-style-type: none
2293 }
2294 }
2295
2296 .files-filter-box-path {
2297 line-height: 33px;
2298 padding: 0;
2299 width: 20px;
2300 position: absolute;
2301 z-index: 11;
2302 left: 5px;
2303 }
2304
2305 .files-filter-box-input {
2306 margin-right: 0;
2307
2192 input {
2308 input {
2193 padding: 2px;
2309 border: 1px solid @white;
2194 border: none;
2310 padding-left: 25px;
2195 font-size: @repo-title-fontsize;
2311 width: 145px;
2196 }
2312
2197 }
2313 &:hover {
2198 }
2314 border-color: @grey6;
2199
2315 }
2316
2317 &:focus {
2318 border-color: @grey5;
2319 }
2320 }
2321 }
2200
2322
2201 .browser-result{
2323 .browser-result{
2202 td a{
2324 td a{
@@ -2215,6 +2337,142 b' h3.files_location{'
2215 }
2337 }
2216
2338
2217
2339
2340 .edit-file-fieldset #location,
2341 .edit-file-fieldset #filename {
2342 display: flex;
2343 width: -moz-available; /* WebKit-based browsers will ignore this. */
2344 width: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
2345 width: fill-available;
2346 border: 0;
2347 }
2348
2349 .path-items {
2350 display: flex;
2351 padding: 0;
2352 border: 1px solid #eeeeee;
2353 width: 100%;
2354 float: left;
2355
2356 .breadcrumb-path {
2357 line-height: 30px;
2358 padding: 0 4px;
2359 white-space: nowrap;
2360 }
2361
2362 .location-path {
2363 width: -moz-available; /* WebKit-based browsers will ignore this. */
2364 width: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
2365 width: fill-available;
2366
2367 .file-name-input {
2368 padding: 0.5em 0;
2369 }
2370
2371 }
2372
2373 ul {
2374 display: flex;
2375 margin: 0;
2376 padding: 0;
2377 width: 100%;
2378 }
2379
2380 li {
2381 list-style-type: none;
2382 }
2383
2384 }
2385
2386 .editor-items {
2387 height: 40px;
2388 margin: 10px 0 -17px 10px;
2389
2390 .editor-action {
2391 cursor: pointer;
2392 }
2393
2394 .editor-action.active {
2395 border-bottom: 2px solid #5C5C5C;
2396 }
2397
2398 li {
2399 list-style-type: none;
2400 }
2401 }
2402
2403 .edit-file-fieldset .message textarea {
2404 border: 1px solid #eeeeee;
2405 }
2406
2407 #files_data .codeblock {
2408 background-color: #F5F5F5;
2409 }
2410
2411 #editor_preview {
2412 background: white;
2413 }
2414
2415 .show-editor {
2416 padding: 10px;
2417 background-color: white;
2418
2419 }
2420
2421 .show-preview {
2422 padding: 10px;
2423 background-color: white;
2424 border-left: 1px solid #eeeeee;
2425 }
2426 // quick filter
2427 .grid-quick-filter {
2428 float: right;
2429 position: relative;
2430 }
2431
2432 .grid-filter-box {
2433 display: flex;
2434 padding: 0px;
2435 border-radius: 3px;
2436 margin-bottom: 0;
2437
2438 a {
2439 border: none !important;
2440 }
2441
2442 li {
2443 list-style-type: none
2444 }
2445 }
2446
2447 .grid-filter-box-icon {
2448 line-height: 33px;
2449 padding: 0;
2450 width: 20px;
2451 position: absolute;
2452 z-index: 11;
2453 left: 5px;
2454 }
2455
2456 .grid-filter-box-input {
2457 margin-right: 0;
2458
2459 input {
2460 border: 1px solid @white;
2461 padding-left: 25px;
2462 width: 145px;
2463
2464 &:hover {
2465 border-color: @grey6;
2466 }
2467
2468 &:focus {
2469 border-color: @grey5;
2470 }
2471 }
2472 }
2473
2474
2475
2218 // Search
2476 // Search
2219
2477
2220 .search-form{
2478 .search-form{
@@ -2277,7 +2535,7 b' div.search-code-body {'
2277 }
2535 }
2278
2536
2279 .code-body {
2537 .code-body {
2280 border: @border-thickness solid @border-default-color;
2538 border: @border-thickness solid @grey6;
2281 .border-radius(@border-radius);
2539 .border-radius(@border-radius);
2282 }
2540 }
2283
2541
@@ -2297,6 +2555,11 b' div.search-code-body {'
2297 .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; }
2555 .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; }
2298 }
2556 }
2299
2557
2558 .path {
2559 border-bottom: none !important;
2560 border-left: 1px solid @grey6 !important;
2561 border-right: 1px solid @grey6 !important;
2562 }
2300 }
2563 }
2301
2564
2302 table.rctable td.td-search-results div {
2565 table.rctable td.td-search-results div {
@@ -2472,3 +2735,56 b' form.markup-form {'
2472 padding: 20px;
2735 padding: 20px;
2473 background-color: white;
2736 background-color: white;
2474 }
2737 }
2738
2739
2740 .dropzone-wrapper {
2741 border: 1px solid @grey5;
2742 padding: 20px;
2743 }
2744
2745 .dropzone,
2746 .dropzone-pure {
2747 border: 2px dashed @grey5;
2748 border-radius: 5px;
2749 background: white;
2750 min-height: 200px;
2751 padding: 54px;
2752
2753 .dz-message {
2754 font-weight: 700;
2755 text-align: center;
2756 margin: 2em 0;
2757 }
2758
2759 }
2760
2761 .dz-preview {
2762 margin: 10px 0 !important;
2763 position: relative;
2764 vertical-align: top;
2765 padding: 10px;
2766 border-bottom: 1px solid @grey5;
2767 }
2768
2769 .dz-filename {
2770 font-weight: 700;
2771 float:left;
2772 }
2773
2774 .dz-sending {
2775 float: right;
2776 }
2777
2778 .dz-response {
2779 clear:both
2780 }
2781
2782 .dz-filename-size {
2783 float:right
2784 }
2785
2786 .dz-error-message {
2787 color: @alert2;
2788 padding-top: 10px;
2789 clear: both;
2790 }
@@ -2,10 +2,21 b''
2 // For use in RhodeCode applications;
2 // For use in RhodeCode applications;
3 // see style guide documentation for guidelines.
3 // see style guide documentation for guidelines.
4
4
5 // TOP MAIN DARK NAVIGATION
6
7 .header .main_nav.horizontal-list {
8 float: right;
9 color: @grey4;
10 > li {
11 a {
12 color: @grey4;
13 }
14 }
15 }
16
5 // HEADER NAVIGATION
17 // HEADER NAVIGATION
6
18
7 .horizontal-list {
19 .horizontal-list {
8 float: right;
9 display: block;
20 display: block;
10 margin: 0;
21 margin: 0;
11 padding: 0;
22 padding: 0;
@@ -18,6 +29,7 b''
18 li {
29 li {
19 line-height: 1em;
30 line-height: 1em;
20 list-style-type: none;
31 list-style-type: none;
32 margin: 0 20px 0 0;
21
33
22 a {
34 a {
23 padding: 0 .5em;
35 padding: 0 .5em;
@@ -55,12 +67,6 b''
55 .user {
67 .user {
56 padding-bottom: 10px;
68 padding-bottom: 10px;
57 }
69 }
58
59 &.open {
60 .user {
61 border-bottom: 5px solid @rcblue;
62 }
63 }
64 }
70 }
65
71
66 &:before { content: none; }
72 &:before { content: none; }
@@ -80,10 +86,6 b''
80 }
86 }
81 }
87 }
82
88
83 &.active {
84 border-bottom: 5px solid @rcblue;
85 }
86
87 &.open {
89 &.open {
88
90
89 a {
91 a {
@@ -118,14 +120,12 b''
118 > a,
120 > a,
119 &.has_select2 a {
121 &.has_select2 a {
120 display: block;
122 display: block;
121 padding: 10px 0 2px;
123 padding: 10px 0;
122 }
124 }
123
125
124 .menulabel {
126 .menulabel {
125 padding: 0 .5em;
126 line-height: 1em;
127 line-height: 1em;
127 // for this specifically we do not use a variable
128 // for this specifically we do not use a variable
128 border-right: 1px solid @grey4;
129 }
129 }
130
130
131 .pr_notifications {
131 .pr_notifications {
@@ -141,7 +141,7 b''
141 &.open,
141 &.open,
142 &.active {
142 &.active {
143 a {
143 a {
144 color: @grey1;
144 color: @rcblue;
145 }
145 }
146 }
146 }
147 }
147 }
@@ -156,6 +156,14 b''
156 position: relative;
156 position: relative;
157 }
157 }
158
158
159 .menulink {
160 &.disabled {
161 color: @grey3;
162 cursor: default;
163 opacity: 0.5;
164 }
165 }
166
159 #quick_login {
167 #quick_login {
160
168
161 li a {
169 li a {
@@ -281,16 +289,19 b''
281 }
289 }
282
290
283 .navigation li:last-child .submenu {
291 .navigation li:last-child .submenu {
284 right: -20px;
292 right: auto;
285 left: auto;
293 left: 0;
294 border: 1px solid @grey5;
295 background: @white;
296 box-shadow: @dropdown-shadow;
286 }
297 }
287
298
288 .submenu {
299 .submenu {
289 position: absolute;
300 position: absolute;
290 top: 100%;
301 top: 100%;
291 left: 0;
302 left: 0;
292 min-width: 150px;
303 min-width: 180px;
293 margin: 6px 0 0;
304 margin: 2px 0 0;
294 padding: 0;
305 padding: 0;
295 text-align: left;
306 text-align: left;
296 font-family: @text-light;
307 font-family: @text-light;
@@ -303,7 +314,7 b''
303 padding: 0 .5em;
314 padding: 0 .5em;
304 line-height: 1em;
315 line-height: 1em;
305 color: @grey3;
316 color: @grey3;
306 background-color: @grey6;
317 background-color: @white;
307 list-style-type: none;
318 list-style-type: none;
308
319
309 a {
320 a {
@@ -324,7 +335,7 b''
324 z-index: 30;
335 z-index: 30;
325 }
336 }
326 &:hover {
337 &:hover {
327 background-color: @grey5;
338 background-color: @grey7;
328 -webkit-transition: background .3s;
339 -webkit-transition: background .3s;
329 -moz-transition: background .3s;
340 -moz-transition: background .3s;
330 -o-transition: background .3s;
341 -o-transition: background .3s;
@@ -501,10 +512,10 b''
501
512
502 #context-bar {
513 #context-bar {
503 display: block;
514 display: block;
504 margin: 0 auto;
515 margin: 0 auto 20px 0;
505 padding: 0 @header-padding;
516 padding: 0 @header-padding;
506 background-color: @grey6;
517 background-color: @grey7;
507 border-bottom: @border-thickness solid @grey5;
518 border-bottom: 1px solid @grey5;
508
519
509 .clear {
520 .clear {
510 clear: both;
521 clear: both;
@@ -513,19 +524,22 b''
513
524
514 ul#context-pages {
525 ul#context-pages {
515 li {
526 li {
516 line-height: 1em;
517 list-style-type: none;
527 list-style-type: none;
518
528
519 a {
529 a {
520 color: @grey3;
530 color: @grey2;
531
532 &:hover {
533 color: @grey1;
534 }
521 }
535 }
522
536
523 &.active {
537 &.active {
524 // special case, non-variable color
538 // special case, non-variable color
525 border-bottom: 4px solid @nav-grey;
539 border-bottom: 2px solid @rcblue;
526
540
527 a {
541 a {
528 color: @grey1;
542 color: @rcblue;
529 }
543 }
530 }
544 }
531 }
545 }
@@ -534,8 +548,9 b' ul#context-pages {'
534 // PAGINATION
548 // PAGINATION
535
549
536 .pagination {
550 .pagination {
537 border: @border-thickness solid @rcblue;
551 border: @border-thickness solid @grey5;
538 color: @rcblue;
552 color: @grey2;
553 box-shadow: @button-shadow;
539
554
540 .current {
555 .current {
541 color: @grey4;
556 color: @grey4;
@@ -552,33 +567,44 b' ul#context-pages {'
552 .dataTables_paginate, .pagination-wh {
567 .dataTables_paginate, .pagination-wh {
553 text-align: left;
568 text-align: left;
554 display: inline-block;
569 display: inline-block;
555 border-left: 1px solid @rcblue;
570 border-left: 1px solid @grey5;
556 float: none;
571 float: none;
557 overflow: hidden;
572 overflow: hidden;
573 box-shadow: @button-shadow;
558
574
559 .paginate_button, .pager_curpage,
575 .paginate_button, .pager_curpage,
560 .pager_link, .pg-previous, .pg-next, .pager_dotdot {
576 .pager_link, .pg-previous, .pg-next, .pager_dotdot {
561 display: inline-block;
577 display: inline-block;
562 padding: @menupadding/4 @menupadding;
578 padding: @menupadding/4 @menupadding;
563 border: 1px solid @rcblue;
579 border: 1px solid @grey5;
564 border-left: 0;
580 border-left: 0;
565 color: @rcblue;
581 color: @grey2;
566 cursor: pointer;
582 cursor: pointer;
567 float: left;
583 float: left;
584
585 &:hover {
586 color: @rcdarkblue;
587 }
568 }
588 }
569
589
570 .pager_curpage, .pager_dotdot,
590 .paginate_button.disabled,
571 .paginate_button.current, .paginate_button.disabled,
572 .disabled {
591 .disabled {
573 color: @grey3;
592 color: @grey3;
574 cursor: default;
593 cursor: default;
594 opacity: 0.5;
595 }
596
597 .paginate_button.current, .pager_curpage {
598 background: @rcblue;
599 border-color: @rcblue;
600 color: @white;
575 }
601 }
576
602
577 .ellipsis {
603 .ellipsis {
578 display: inline-block;
604 display: inline-block;
579 text-align: left;
605 text-align: left;
580 padding: @menupadding/4 @menupadding;
606 padding: @menupadding/4 @menupadding;
581 border: 1px solid @rcblue;
607 border: 1px solid @grey5;
582 border-left: 0;
608 border-left: 0;
583 float: left;
609 float: left;
584 }
610 }
@@ -595,14 +621,6 b' ul#context-pages {'
595 font-family: @text-regular;
621 font-family: @text-regular;
596 color: @grey1;
622 color: @grey1;
597
623
598 &#graph_nodes {
599 clear:both;
600 width: auto;
601 margin-left: -100px;
602 padding: 0;
603 border: none;
604 }
605
606 .nav-pills {
624 .nav-pills {
607 margin: 0;
625 margin: 0;
608 }
626 }
@@ -631,19 +649,56 b' ul#context-pages {'
631
649
632 .main_filter_help_box {
650 .main_filter_help_box {
633 padding: 7px 7px;
651 padding: 7px 7px;
634 border-top: 1px solid @grey4;
635 border-right: 1px solid @grey4;
636 border-bottom: 1px solid @grey4;
637 display: inline-block;
652 display: inline-block;
638 vertical-align: top;
653 vertical-align: top;
639 background: inherit;
654 background: inherit;
640 position: absolute;
655 position: absolute;
641 right: 8px;
656 right: 0;
642 top: 9px;
657 top: 9px;
643 }
658 }
644
659
645 .main_filter_input_box {
660 .main_filter_input_box {
646 display: inline-block;
661 display: inline-block;
662
663 .searchItems {
664 display:flex;
665 background: @black;
666 padding: 0px;
667 border-radius: 3px;
668 border: 1px solid @black;
669
670 a {
671 border: none !important;
672 }
673 }
674
675 .searchTag {
676 line-height: 28px;
677 padding: 0 5px;
678
679 .tag {
680 color: @grey5;
681 border-color: @grey2;
682 background: @grey1;
683 }
684 }
685
686 .searchTagFilter {
687 background-color: @black !important;
688 margin-right: 0;
689 }
690
691 .searchTagHelp {
692 background-color: @grey1 !important;
693 margin: 0;
694 }
695 .searchTagHelp:hover {
696 background-color: @grey1 !important;
697 }
698 .searchTagInput {
699 background-color: @grey1 !important;
700 margin-right: 0;
701 }
647 }
702 }
648
703
649 .main_filter_box {
704 .main_filter_box {
@@ -651,23 +706,24 b' ul#context-pages {'
651 }
706 }
652
707
653 #main_filter_help {
708 #main_filter_help {
654 background: @grey3;
709 background: @grey1;
655 border: 1px solid black;
710 border: 1px solid black;
656 position: absolute;
711 position: absolute;
657 white-space: pre;
712 white-space: pre;
658 z-index: 9999;
713 z-index: 9999;
659 color: @nav-grey;
714 color: @nav-grey;
660 margin: 1px 7px;
661 padding: 0 10px;
715 padding: 0 10px;
662 }
716 }
663
717
664 .main_filter_input {
718 input {
665 padding: 5px;
719
666 min-width: 260px;
720 &.main_filter_input {
667 color: @nav-grey;
721 padding: 5px 10px;
668 background: @grey3;
722 min-width: 340px;
723 color: @grey7;
724 background: @black;
669 min-height: 18px;
725 min-height: 18px;
670
726 border: 0;
671
727
672 &:active {
728 &:active {
673 color: @grey2 !important;
729 color: @grey2 !important;
@@ -678,6 +734,7 b' ul#context-pages {'
678 background: white !important;
734 background: white !important;
679 }
735 }
680 }
736 }
737 }
681
738
682
739
683
740
@@ -63,10 +63,6 b''
63 &.user-profile {
63 &.user-profile {
64 float: left;
64 float: left;
65
65
66 .panel-heading {
67 margin-bottom: @padding;
68 }
69
70 .panel-body {
66 .panel-body {
71 &:extend(.clearfix);
67 &:extend(.clearfix);
72 }
68 }
@@ -1,11 +1,13 b''
1 @font-face {
1 @font-face {
2 font-family: 'rcicons';
2 font-family: 'rcicons';
3 src: url('../fonts/RCIcons/rcicons.eot?74666722');
3
4 src: url('../fonts/RCIcons/rcicons.eot?74666722#iefix') format('embedded-opentype'),
4 src: url('../fonts/RCIcons/rcicons.eot?92789106');
5 url('../fonts/RCIcons/rcicons.woff2?74666722') format('woff2'),
5 src: url('../fonts/RCIcons/rcicons.eot?92789106#iefix') format('embedded-opentype'),
6 url('../fonts/RCIcons/rcicons.woff?74666722') format('woff'),
6 url('../fonts/RCIcons/rcicons.woff2?92789106') format('woff2'),
7 url('../fonts/RCIcons/rcicons.ttf?74666722') format('truetype'),
7 url('../fonts/RCIcons/rcicons.woff?92789106') format('woff'),
8 url('../fonts/RCIcons/rcicons.svg?74666722#rcicons') format('svg');
8 url('../fonts/RCIcons/rcicons.ttf?92789106') format('truetype'),
9 url('../fonts/RCIcons/rcicons.svg?92789106#rcicons') format('svg');
10
9 font-weight: normal;
11 font-weight: normal;
10 font-style: normal;
12 font-style: normal;
11 }
13 }
@@ -55,78 +57,164 b''
55 /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
57 /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
56 }
58 }
57
59
60 .animate-spin {
61 -moz-animation: spin 2s infinite linear;
62 -o-animation: spin 2s infinite linear;
63 -webkit-animation: spin 2s infinite linear;
64 animation: spin 2s infinite linear;
65 display: inline-block;
66 }
67 @-moz-keyframes spin {
68 0% {
69 -moz-transform: rotate(0deg);
70 -o-transform: rotate(0deg);
71 -webkit-transform: rotate(0deg);
72 transform: rotate(0deg);
73 }
74
75 100% {
76 -moz-transform: rotate(359deg);
77 -o-transform: rotate(359deg);
78 -webkit-transform: rotate(359deg);
79 transform: rotate(359deg);
80 }
81 }
82 @-webkit-keyframes spin {
83 0% {
84 -moz-transform: rotate(0deg);
85 -o-transform: rotate(0deg);
86 -webkit-transform: rotate(0deg);
87 transform: rotate(0deg);
88 }
89
90 100% {
91 -moz-transform: rotate(359deg);
92 -o-transform: rotate(359deg);
93 -webkit-transform: rotate(359deg);
94 transform: rotate(359deg);
95 }
96 }
97 @-o-keyframes spin {
98 0% {
99 -moz-transform: rotate(0deg);
100 -o-transform: rotate(0deg);
101 -webkit-transform: rotate(0deg);
102 transform: rotate(0deg);
103 }
104
105 100% {
106 -moz-transform: rotate(359deg);
107 -o-transform: rotate(359deg);
108 -webkit-transform: rotate(359deg);
109 transform: rotate(359deg);
110 }
111 }
112 @-ms-keyframes spin {
113 0% {
114 -moz-transform: rotate(0deg);
115 -o-transform: rotate(0deg);
116 -webkit-transform: rotate(0deg);
117 transform: rotate(0deg);
118 }
119
120 100% {
121 -moz-transform: rotate(359deg);
122 -o-transform: rotate(359deg);
123 -webkit-transform: rotate(359deg);
124 transform: rotate(359deg);
125 }
126 }
127 @keyframes spin {
128 0% {
129 -moz-transform: rotate(0deg);
130 -o-transform: rotate(0deg);
131 -webkit-transform: rotate(0deg);
132 transform: rotate(0deg);
133 }
134
135 100% {
136 -moz-transform: rotate(359deg);
137 -o-transform: rotate(359deg);
138 -webkit-transform: rotate(359deg);
139 transform: rotate(359deg);
140 }
141 }
142
143
144
58 .icon-no-margin::before {
145 .icon-no-margin::before {
59 margin: 0;
146 margin: 0;
60
147
61 }
148 }
62 // -- ICON CLASSES -- //
149 // -- ICON CLASSES -- //
150 // sorter = lambda s: '\n'.join(sorted(s.splitlines()))
63
151
152 .icon-delete:before { content: '\e800'; } /* '' */
153 .icon-ok:before { content: '\e801'; } /* '' */
154 .icon-comment:before { content: '\e802'; } /* '' */
64 .icon-bookmark:before { content: '\e803'; } /* '' */
155 .icon-bookmark:before { content: '\e803'; } /* '' */
65 .icon-branch:before { content: '\e804'; } /* '' */
156 .icon-branch:before { content: '\e804'; } /* '' */
157 .icon-tag:before { content: '\e805'; } /* '' */
66 .icon-lock:before { content: '\e806'; } /* '' */
158 .icon-lock:before { content: '\e806'; } /* '' */
67 .icon-unlock:before { content: '\e807'; } /* '' */
159 .icon-unlock:before { content: '\e807'; } /* '' */
68 .icon-delete:before { content: '\e808'; } /* '' */
160 .icon-feed:before { content: '\e808'; } /* '' */
69 .icon-false:before { content: '\e808'; } /* '' */
161 .icon-left:before { content: '\e809'; } /* '' */
70
162 .icon-right:before { content: '\e80a'; } /* '' */
71 .icon-ok:before { content: '\e809'; } /* '' */
163 .icon-down:before { content: '\e80b'; } /* '' */
72 .icon-true:before { content: '\e809'; } /* '' */
164 .icon-folder:before { content: '\e80c'; } /* '' */
73
165 .icon-folder-open:before { content: '\e80d'; } /* '' */
74 .icon-comment:before { content: '\e80a'; } /* '' */
166 .icon-folder-empty:before { content: '\f114'; } /* '' */
75 .icon-comment-add:before { content: '\e816'; } /* '' */
167 .icon-folder-open-empty:before { content: '\f115'; } /* '' */
76 .icon-comment_toggle:before { content: '\e818'; } /* '' */
168 .icon-trash-empty:before { content: '\e80e'; } /* '' */
77
169 .icon-group:before { content: '\e80f'; } /* '' */
78 .icon-feed:before { content: '\e80b'; } /* '' */
170 .icon-remove:before { content: '\e810'; } /* '' */
79
171 .icon-fork:before { content: '\e811'; } /* '' */
80 .icon-right:before { content: '\e80c'; } /* '' */
172 .icon-more:before { content: '\e812'; } /* '' */
81 .icon-left:before { content: '\e80d'; } /* '' */
173 .icon-search:before { content: '\e813'; } /* '' */
82
174 .icon-scissors:before { content: '\e814'; } /* '' */
83 .icon-arrow_down:before { content: '\e80e'; } /* '' */
175 .icon-download:before { content: '\e815'; } /* '' */
84 .icon-arrow_up:before { content: '\e80e'; } /* '' */
176 .icon-doc:before { content: '\e816'; } /* '' */
85
177 .icon-cog:before { content: '\e817'; } /* '' */
86 .icon-group:before { content: '\e812'; } /* '' */
178 .icon-cog-alt:before { content: '\e818'; } /* '' */
87
179 .icon-eye:before { content: '\e819'; } /* '' */
88 .icon-fork:before { content: '\e814'; } /* '' */
180 .icon-eye-off:before { content: '\e81a'; } /* '' */
89 .icon-merge:before { content: '\e814'; } /* '' */
181 .icon-cancel-circled2:before { content: '\e81b'; } /* '' */
90
182 .icon-cancel-circled:before { content: '\e81c'; } /* '' */
91 .icon-more:before { content: '\e815'; } /* '' */
92
93 .icon-more-linked { cursor: pointer; color: @grey3 }
94 .icon-more-linked:before { content: '\e815'; } /* '' */
95
96 .icon-expand-linked { cursor: pointer; color: @grey3; font-size: 8px }
97 .icon-expand-linked:before { content: '\e80e'; } /* '' */
98
99 .icon-git-inv:before { content: '\e80f'; } /* '' */
100 .icon-hg-inv:before { content: '\e810'; } /* '' */
101 .icon-svn-inv:before { content: '\e811'; } /* '' */
102
103 .icon-git:before { content: '\e81a'; } /* '' */
104 .icon-hg:before { content: '\e81b'; } /* '' */
105 .icon-svn:before { content: '\e820'; } /* '' */
106
107 .icon-minus:before { content: '\e81c'; } /* '' */
108 .icon-plus:before { content: '\e81d'; } /* '' */
183 .icon-plus:before { content: '\e81d'; } /* '' */
109 .icon-remove:before { content: '\e81e'; } /* '' */
184 .icon-plus-circled:before { content: '\e81e'; } /* '' */
110 .icon-remove-sign:before { content: '\e81e'; } /* '' */
185 .icon-minus-circled:before { content: '\e81f'; } /* '' */
111
186 .icon-minus:before { content: '\e820'; } /* '' */
112 .icon-rhodecode:before { content: '\e81f'; } /* '' */
187 .icon-info-circled:before { content: '\e821'; } /* '' */
113
188 .icon-upload:before { content: '\e822'; } /* '' */
114 .icon-tag:before { content: '\e821'; } /* '' */
189 .icon-home:before { content: '\e823'; } /* '' */
115 .icon-copy:before { content: '\f0c5'; } /* '' */
190 .icon-git:before { content: '\e82a'; } /* '' */
116 .icon-clipboard:before { content: '\f0c5'; } /* '' */
191 .icon-hg:before { content: '\e82d'; } /* '' */
192 .icon-svn:before { content: '\e82e'; } /* '' */
193 .icon-comment-add:before { content: '\e82f'; } /* '' */
194 .icon-comment-toggle:before { content: '\e830'; } /* '' */
195 .icon-rhodecode:before { content: '\e831'; } /* '' */
196 .icon-up:before { content: '\e832'; } /* '' */
197 .icon-merge:before { content: '\e833'; } /* '' */
198 .icon-docs:before { content: '\f0c5'; } /* '' */
199 .icon-menu:before { content: '\f0c9'; } /* '' */
200 .icon-paste:before { content: '\f0ea'; } /* '' */
201 .icon-doc-text:before { content: '\f0f6'; } /* '' */
202 .icon-plus-squared:before { content: '\f0fe'; } /* '' */
203 .icon-minus-squared:before { content: '\f146'; } /* '' */
204 .icon-minus-squared-alt:before { content: '\f147'; } /* '' */
205 .icon-doc-inv:before { content: '\f15b'; } /* '' */
206 .icon-doc-text-inv:before { content: '\f15c'; } /* '' */
207 .icon-plus-squared-alt:before { content: '\f196'; } /* '' */
208 .icon-file-code:before { content: '\f1c9'; } /* '' */
209 .icon-history:before { content: '\f1da'; } /* '' */
210 .icon-sliders:before { content: '\f1de'; } /* '' */
211 .icon-trash:before { content: '\f1f8'; } /* '' */
212 .icon-spin-alt:before { content: '\e834'; } /* '' */
213 .icon-spin:before { content: '\e838'; } /* '' */
117
214
118
215
119 .icon-folder:before { content: '\e813'; } /* '' */
216 // MERGED ICONS BASED ON CURRENT ONES
120 .icon-folder-close:before { content: '\e813'; } /* '' */
217 .icon-repo-group:before { &:extend(.icon-folder-open:before); }
121
122 .icon-directory:before { content: '\e800'; } /* '' */
123 .icon-directory-empty:before { content: '\f114'; } /* '' */
124 .icon-file-text:before { content: '\f0f6'; } /* '' */
125 .icon-file-text-inv:before { content: '\f15c'; } /* '' */
126 .icon-file-code:before { content: '\f1c9'; } /* '' */
127
128 // MERGED ICONS
129
130 .icon-repo-private:before { &:extend(.icon-lock:before); }
218 .icon-repo-private:before { &:extend(.icon-lock:before); }
131 .icon-repo-lock:before { &:extend(.icon-lock:before); }
219 .icon-repo-lock:before { &:extend(.icon-lock:before); }
132 .icon-unlock-alt:before { &:extend(.icon-unlock:before); }
220 .icon-unlock-alt:before { &:extend(.icon-unlock:before); }
@@ -134,9 +222,20 b''
134 .icon-repo-public:before { &:extend(.icon-unlock:before); }
222 .icon-repo-public:before { &:extend(.icon-unlock:before); }
135 .icon-rss-sign:before { &:extend(.icon-feed:before); }
223 .icon-rss-sign:before { &:extend(.icon-feed:before); }
136 .icon-code-fork:before { &:extend(.icon-fork:before); }
224 .icon-code-fork:before { &:extend(.icon-fork:before); }
225 .icon-arrow_up:before { &:extend(.icon-up:before); }
226 .icon-file:before { &:extend(.icon-file-code:before); }
227 .icon-file-text:before { &:extend(.icon-file-code:before); }
228 .icon-directory:before { &:extend(.icon-folder:before); }
229 .icon-more-linked:before { &:extend(.icon-more:before); }
230 .icon-clipboard:before { &:extend(.icon-docs:before); }
231 .icon-copy:before { &:extend(.icon-docs:before); }
232 .icon-true:before { &:extend(.icon-ok:before); }
233 .icon-false:before { &:extend(.icon-delete:before); }
234 .icon-expand-linked:before { &:extend(.icon-down:before); }
235 .icon-pr-merge-fail:before { &:extend(.icon-delete:before); }
137
236
138 // TRANSFORM
237 // TRANSFORM
139 .icon-arrow_up:before {transform: rotate(180deg);}
238
140 .icon-merge:before {transform: rotate(180deg);}
239 .icon-merge:before {transform: rotate(180deg);}
141
240
142 // -- END ICON CLASSES -- //
241 // -- END ICON CLASSES -- //
@@ -152,6 +251,9 b''
152 .icon-svn-inv { color: @color1 !important; }
251 .icon-svn-inv { color: @color1 !important; }
153 .icon-repo-lock { color: #FF0000; }
252 .icon-repo-lock { color: #FF0000; }
154 .icon-repo-unlock { color: #FF0000; }
253 .icon-repo-unlock { color: #FF0000; }
254 .icon-false { color: @grey5 }
255 .icon-expand-linked { cursor: pointer; color: @grey3; font-size: 14px }
256 .icon-more-linked { cursor: pointer; color: @grey3 }
155
257
156 .repo-switcher-dropdown .select2-result-label {
258 .repo-switcher-dropdown .select2-result-label {
157 .icon-git:before {
259 .icon-git:before {
@@ -88,7 +88,6 b' div.readme_box pre {'
88 font-size: 13px !important;
88 font-size: 13px !important;
89 overflow: visible !important;
89 overflow: visible !important;
90 line-height: 140% !important;
90 line-height: 140% !important;
91 background-color: @grey7;
92 }
91 }
93
92
94 div.readme_box img {
93 div.readme_box img {
@@ -156,10 +155,10 b' div.readme_box code {'
156 }
155 }
157
156
158 div.readme_box pre {
157 div.readme_box pre {
159 border: @border-thickness solid @grey5;
158 border: @border-thickness solid #CBDBEB;
160 overflow: auto;
159 overflow: auto;
161 padding: .5em;
160 padding: .5em;
162 background-color: @grey7;
161 background-color: #FCFEFF;
163 }
162 }
164
163
165 div.readme_box pre > code {
164 div.readme_box pre > code {
@@ -17,7 +17,7 b''
17 .select2-search,
17 .select2-search,
18 .select2-search input {.box-sizing(border-box);}
18 .select2-search input {.box-sizing(border-box);}
19 .select2-container .select2-choice{display:block; line-height:1em; -webkit-touch-callout:none;-moz-user-select:none;-ms-user-select:none;user-select:none; }
19 .select2-container .select2-choice{display:block; line-height:1em; -webkit-touch-callout:none;-moz-user-select:none;-ms-user-select:none;user-select:none; }
20 .main .select2-container .select2-choice { background-color: white; }
20 .main .select2-container .select2-choice { background-color: white; box-shadow: @button-shadow;}
21 .select2-container .select2-choice abbr { display: none; width: 12px; height: 12px; position: absolute; right: 24px; top: 8px; font-size: 1px; text-decoration: none; border: 0; background: url('../images/select2.png') right top no-repeat; cursor: pointer; outline: 0; }
21 .select2-container .select2-choice abbr { display: none; width: 12px; height: 12px; position: absolute; right: 24px; top: 8px; font-size: 1px; text-decoration: none; border: 0; background: url('../images/select2.png') right top no-repeat; cursor: pointer; outline: 0; }
22 .select2-container.select2-allowclear .select2-choice abbr {display: inline-block;}
22 .select2-container.select2-allowclear .select2-choice abbr {display: inline-block;}
23 .select2-container .select2-choice abbr:hover { background-position: right -11px; cursor: pointer; }
23 .select2-container .select2-choice abbr:hover { background-position: right -11px; cursor: pointer; }
@@ -92,10 +92,18 b' select.select2{height:28px;visibility:hi'
92 min-width: 160px;
92 min-width: 160px;
93 margin: 0 @padding 0 0;
93 margin: 0 @padding 0 0;
94 padding: 0;
94 padding: 0;
95 border: @border-thickness solid @rcblue;
95 border: @border-thickness solid @grey5;
96 border-radius: @border-radius;
96 border-radius: @border-radius;
97 color: @rcblue;
97 color: @grey2;
98 background-color: white;
98 background-color: white;
99
100 a {
101 color: @grey2;
102
103 &:hover {
104 color: @rcdarkblue;
105 }
106 }
99 }
107 }
100
108
101 .drop-menu-dropdown {
109 .drop-menu-dropdown {
@@ -120,7 +128,7 b' select.select2{height:28px;visibility:hi'
120
128
121 a {
129 a {
122 display:block;
130 display:block;
123 padding: .9em;
131 padding: .7em;
124 padding-right: 2em;
132 padding-right: 2em;
125 position: relative;
133 position: relative;
126
134
@@ -129,7 +137,7 b' select.select2{height:28px;visibility:hi'
129 content: "\00A0\25BE";
137 content: "\00A0\25BE";
130 right: .1em;
138 right: .1em;
131 line-height: 1em;
139 line-height: 1em;
132 top: 0.4em;
140 top: 0.2em;
133 width: 1em;
141 width: 1em;
134 font-size: 20px;
142 font-size: 20px;
135 }
143 }
@@ -157,6 +165,12 b' select.select2{height:28px;visibility:hi'
157 width: 100%;
165 width: 100%;
158 margin: .5em 0;
166 margin: .5em 0;
159 padding: .5em;
167 padding: .5em;
168 border-color: @grey4;
169
170 &:focus, &:hover {
171 border-color: @rcblue;
172 box-shadow: @button-shadow;
173 }
160 }
174 }
161
175
162 .select2-no-results {
176 .select2-no-results {
@@ -176,7 +190,13 b' select.select2{height:28px;visibility:hi'
176
190
177 &:hover,
191 &:hover,
178 &.select2-highlighted {
192 &.select2-highlighted {
179 background-color: @rclightblue;
193 background-color: @grey7;
194
195 .select2-result-label {
196 &:hover {
197 color: @grey1!important;
198 }
199 }
180 }
200 }
181
201
182 &.select2-result-with-children {
202 &.select2-result-with-children {
@@ -189,8 +209,7 b' select.select2{height:28px;visibility:hi'
189 display:block;
209 display:block;
190 padding: 8px;
210 padding: 8px;
191 font-family: @text-regular;
211 font-family: @text-regular;
192 border-bottom: @border-thickness solid @rclightblue;
212 color: @grey2;
193 color: @rcblue;
194 cursor: pointer;
213 cursor: pointer;
195 }
214 }
196 &.select2-result-with-children {
215 &.select2-result-with-children {
@@ -205,7 +224,7 b' select.select2{height:28px;visibility:hi'
205 ul.select2-result-sub li .select2-result-label {
224 ul.select2-result-sub li .select2-result-label {
206 padding-left: 16px;
225 padding-left: 16px;
207 font-family: @text-regular;
226 font-family: @text-regular;
208 color: @rcblue;
227 color: @grey2;
209 cursor: pointer;
228 cursor: pointer;
210 }
229 }
211 }
230 }
@@ -3,30 +3,33 b''
3 // Used for headers and file detail summary screens.
3 // Used for headers and file detail summary screens.
4
4
5 .summary {
5 .summary {
6 float: left;
6 clear: both;
7 float: none;
7 position: relative;
8 position: relative;
8 width: 100%;
9 width: 100%;
9 margin: 0;
10 margin: 0;
10 padding: 0;
11 padding: 0;
12 background: #FCFCFC;
13 border: 1px solid #EAEAEA;
14 border-radius: @border-radius;
15 margin-bottom: 20px;
11
16
12 .summary-detail-header {
17 .summary-detail-header {
13 float: left;
14 display: block;
18 display: block;
15 width: 100%;
19 width: 100%;
16 margin-bottom: @textmargin;
20 margin-bottom: 10px;
17 padding: 0 0 .5em 0;
21 padding: 0 0 .5em 0;
18 border-bottom: @border-thickness solid @border-default-color;
22 border-bottom: @border-thickness solid @border-default-color;
19
23
20 .breadcrumbs {
24 .breadcrumbs {
21 float: left;
22 display: inline;
25 display: inline;
23 margin: 0;
26 margin: 0;
24 padding: 0;
27 padding: 0;
25 }
28 }
29
26 h4 {
30 h4 {
27 float: left;
28 margin: 0 1em 0 0;
31 margin: 0 1em 0 0;
29 padding: 0;
32 padding: 10px 0 5px 20px;
30 line-height: 1.2em;
33 line-height: 1.2em;
31 font-size: @basefontsize;
34 font-size: @basefontsize;
32 }
35 }
@@ -42,11 +45,11 b''
42 }
45 }
43
46
44 .summary-detail {
47 .summary-detail {
45 float: left;
48 float: none;
46 position: relative;
49 position: relative;
47 width: 73%;
50 width: 100%;
48 margin: 0 3% @space 0;
51 margin: 0;
49 padding: 0;
52 padding: 0 0 20px 0;
50
53
51 .file_diff_buttons {
54 .file_diff_buttons {
52 margin-top: @space;
55 margin-top: @space;
@@ -62,18 +65,37 b''
62 height: 30px;
65 height: 30px;
63 margin: 0;
66 margin: 0;
64 padding: 0;
67 padding: 0;
68 width: 130px;
65 font-weight: @text-semibold-weight;
69 font-weight: @text-semibold-weight;
66 font-family: @text-semibold;
70 font-family: @text-semibold;
67 }
71 }
72 .left-clone select {
73 width: 130px;
74 margin-right: 0;
75 background-color: @grey7;
76 border-color: @grey4;
77 color: #5C5C5C;
78 border-top-right-radius: 0;
79 border-bottom-right-radius: 0;
80 }
68
81
69 .right-clone {
82 .right-clone {
70 float: right;
83 float: left;
71 width: 83%;
84 width: ~"calc(100% - 170px)";
85
86 .clipboard-action {
87 margin-left: -30px;
88 }
72 }
89 }
73
90
74 .clone_url_input {
91 .clone_url_input {
75 width: ~"calc(100% - 35px)";
92 width: ~"calc(100% - 90px)";
76 padding: 5px;
93 padding: 6px 30px 6px 10px;
94 height: 14px;
95 box-shadow: 0 1px 1px 0 rgba(0,0,0,0.07);
96 border-top-left-radius: 0;
97 border-bottom-left-radius: 0;
98 margin-left: -1px;
77 }
99 }
78
100
79 &.directory {
101 &.directory {
@@ -123,18 +145,32 b''
123 border: @border-thickness solid @border-default-color;
145 border: @border-thickness solid @border-default-color;
124 .border-radius(@border-radius);
146 .border-radius(@border-radius);
125 }
147 }
148
149 .btn-collapse {
150 clear: both;
151 float: none;
152 background: #F7F7F7;
153 text-align: center;
154 color: #949494;
155 font-size: 11px;
156
157 &:hover {
158 background: #f1f1f1;
159 color: #2B2B2D;
160 }
161 }
126 }
162 }
127
163
128 // this is used outside of just the summary
164 // this is used outside of just the summary
129 .fieldset, // similar to form fieldset
165 .fieldset, // similar to form fieldset
130 .summary .sidebar-right-content { // these have to match
166 .summary .sidebar-right-content { // these have to match
131 clear: both;
167 clear: both;
132 float: left;
168 float: none;
133 position: relative;
169 position: relative;
134 display:block;
170 display:block;
135 width: 100%;
171 width: 100%;
136 min-height: 1em;
172 min-height: 20px;
137 margin-bottom: @textmargin;
173 margin-bottom: 10px;
138 padding: 0;
174 padding: 0;
139 line-height: 1.2em;
175 line-height: 1.2em;
140
176
@@ -147,19 +183,28 b''
147 }
183 }
148
184
149 .summary .sidebar-right-content {
185 .summary .sidebar-right-content {
150 margin-bottom: @space;
186 margin-bottom: 0;
151
187
152 .rc-user {
188 .rc-user {
153 min-width: 0;
189 min-width: 0;
154 }
190 }
191
192 li {
193 list-style: none;
194 line-height: normal;
195 }
196 }
197
198 .summary {
199 .fieldset {
200 margin-bottom: 0;
201 }
155 }
202 }
156
203
157 .fieldset {
204 .fieldset {
158
205
159 .left-label { // similar to form legend
206 .left-label { // similar to form legend
160 float: left;
161 display: block;
207 display: block;
162 width: 25%;
163 margin: 0;
208 margin: 0;
164 padding: 0;
209 padding: 0;
165 font-weight: @text-semibold-weight;
210 font-weight: @text-semibold-weight;
@@ -167,16 +212,78 b''
167 }
212 }
168
213
169 .left-label-summary {
214 .left-label-summary {
170 .left-label;
215 padding-left: 20px;
171 width: 150px;
216 margin-bottom: 5px;
217
218 p {
219 margin-bottom: 5px;
220 color: @grey1;
221 float: left;
222 width: 130px;
223
224 &.spacing {
225 margin-top: 10px;
226 }
227 }
228
229 .right-label-summary {
230 float: left;
231 margin-top: 7px;
232 width: ~"calc(100% - 160px)";
233 }
234 }
235
236 .left-label-summary-files {
237 padding-left: 45px;
238 margin-top: 5px;
239
240 p {
241 margin-bottom: 5px;
242 color: @grey1;
243 float: left;
244 width: 130px;
245
246 &.spacing {
247 margin-top: 10px;
248 }
249 }
250
251 .right-label-summary {
252 float: left;
253 margin-top: 7px;
254 }
255 }
256
257 .left-content {
258 width: ~"calc(60% - 20px)";
259 float: left;
260 margin: 15px 0 15px 20px;
261
262 .rc-user {
263 min-width: auto;
264 max-width: none;
265 min-height: auto;
266 padding-right: 5px;
267 }
268
269 .left-content-avatar {
270 width: 45px;
271 float: left;
272 margin-top: 8px;
273 }
274
275 .left-content-message {
276 float: left;
277 width: ~"calc(100% - 45px)";
278 }
172 }
279 }
173
280
174 .right-content { // similar to form fields
281 .right-content { // similar to form fields
175 float: left;
282 float: left;
176 display: block;
283 display: block;
177 width: 75%;
284 width: ~"calc(40% - 20px)";
178 margin: 0 0 0 -15%;
285 text-align: right;
179 padding: 0 0 0 15%;
286 margin: 15px 20px 15px 0;
180
287
181 .truncate-wrap,
288 .truncate-wrap,
182 .truncate {
289 .truncate {
@@ -187,11 +294,49 b''
187 .commit-long {
294 .commit-long {
188 overflow-x: auto;
295 overflow-x: auto;
189 }
296 }
297
298 .commit-info {
299 margin-top: 7px;
300 }
301
302 .summary-tag,
303 .summary-tagtag,
304 .summary-branchtag,
305 .summary-booktag,
306 .summary-metatag,
307 .summary-perm_tag {
308 background:transparent;
309 border: none;
310 box-shadow: none;
311 margin-left: 10px;
312 font-size: 13px;
313 }
314
315 .summary-tag span,
316 .summary-tag i,
317 .summary-tag a {
318 color: @grey1;
319 }
320
321 }
322 .commit {
323 color: @grey1;
324 margin-bottom: 5px;
325 white-space: pre;
190 }
326 }
191 .commit.truncate-wrap {
327 .commit.truncate-wrap {
192 overflow:hidden;
328 overflow:hidden;
193 text-overflow: ellipsis;
329 text-overflow: ellipsis;
194 }
330 }
331 .commit-author {
332 color: @grey1;
333 }
334 .commit-date {
335 color: @grey4;
336 }
337 .fieldset-text-line {
338 line-height: 36px;
339 }
195 }
340 }
196
341
197 // expand commit message
342 // expand commit message
@@ -222,11 +367,38 b''
222 }
367 }
223
368
224 // Quick Start section
369 // Quick Start section
370
371 .empty-repo {
372 border: 1px solid #EAEAEA;
373 border-bottom: 0;
374 border-radius: @border-radius;
375 padding: 0 20px;
376 }
377
378 .empty-repo h3, .quick_start p {
379 margin-bottom: 10px;
380 }
381
382 .quick_start pre {
383 background: #FCFEFF;
384 border: 1px solid #CBDBEB;
385 box-shadow: @button-shadow;
386 padding: 10px 15px;
387 border-radius: 4px;
388 color: @grey2;
389 }
390
391 .clear-fix {
392 clear: both;
393 }
394
225 .quick_start {
395 .quick_start {
226 float: left;
227 display: block;
396 display: block;
228 position: relative;
397 position: relative;
229 width: 100%;
398 border: 1px solid #EAEAEA;
399 border-top: 0;
400 border-radius: @border-radius;
401 padding: 0 20px;
230
402
231 // adds some space to make copy and paste easier
403 // adds some space to make copy and paste easier
232 .left-label,
404 .left-label,
@@ -235,6 +407,7 b''
235 }
407 }
236 }
408 }
237
409
410
238 .submodule {
411 .submodule {
239 .summary-detail {
412 .summary-detail {
240 width: 100%;
413 width: 100%;
@@ -250,23 +423,32 b''
250 display: block;
423 display: block;
251 width: 100%;
424 width: 100%;
252 margin: 0;
425 margin: 0;
253 padding: @space 0 10px 0;
254 border-top: @border-thickness solid @border-default-color;
255
426
256 .stats {
427 .file-filename {
257 float: left;
428 float:left;
429 padding: 10px;
258 }
430 }
259 .stats-filename {
431
260 font-size: 120%;
432 .file-stats {
433 padding: 10px;
434 float:right;
261 }
435 }
436
437
262 .stats-first-item {
438 .stats-first-item {
263 padding: 0px 0px 0px 3px;
439 padding: 0px 0px 0px 3px;
264 }
440 }
265
441
442 .stats-info {
443 font-size: 11px;
444 color: @grey4;
445 }
446
266 .buttons {
447 .buttons {
267 float: right;
448 float: right;
268 text-align: right;
449 text-align: right;
269 color: @grey4;
450 color: @grey4;
451 padding: 10px;
270 }
452 }
271
453
272 .file-container {
454 .file-container {
@@ -289,3 +471,22 b''
289
471
290 }
472 }
291
473
474 .rctable.repo_summary {
475 border: 1px solid #eaeaea;
476 border-radius: 2px;
477 border-collapse: inherit;
478 border-bottom: 0;
479
480 th {
481 background: @grey7;
482 border-bottom: 0;
483 }
484
485 td {
486 border-color: #eaeaea;
487 }
488
489 td.td-status {
490 padding: 0 0 0 10px;
491 }
492 }
@@ -33,7 +33,7 b' table.dataTable {'
33 td {
33 td {
34 height: auto;
34 height: auto;
35 max-width: 20%;
35 max-width: 20%;
36 padding: .65em 1em .65em 0;
36 padding: .65em 0 .65em 1em;
37 vertical-align: middle;
37 vertical-align: middle;
38 border-bottom: @border-thickness solid @grey5;
38 border-bottom: @border-thickness solid @grey5;
39 white-space: normal;
39 white-space: normal;
@@ -103,6 +103,11 b' table.dataTable {'
103 }
103 }
104 }
104 }
105
105
106 &.td-icon {
107 min-width: 20px;
108 width: 20px;
109 }
110
106 &.td-hash {
111 &.td-hash {
107 min-width: 80px;
112 min-width: 80px;
108 width: 200px;
113 width: 200px;
@@ -113,6 +118,12 b' table.dataTable {'
113 }
118 }
114 }
119 }
115
120
121 &.td-graphbox {
122 width: 100px;
123 max-width: 100px;
124 min-width: 100px;
125 }
126
116 &.td-time {
127 &.td-time {
117 width: 160px;
128 width: 160px;
118 white-space: nowrap;
129 white-space: nowrap;
@@ -141,6 +152,11 b' table.dataTable {'
141 }
152 }
142 }
153 }
143
154
155 &.td-grid-name {
156 white-space: nowrap;
157 min-width: 300px;
158 }
159
144 &.td-componentname {
160 &.td-componentname {
145 white-space: nowrap;
161 white-space: nowrap;
146 }
162 }
@@ -403,29 +419,11 b' table.trending_language_tbl {'
403
419
404 .trending_language {
420 .trending_language {
405 position: relative;
421 position: relative;
406 width: 100%;
407 height: 19px;
408 overflow: hidden;
422 overflow: hidden;
409 background-color: @grey6;
423 color: @text-color;
424 width: 400px;
410
425
411 span, b{
426 .lang-bar {
412 position: absolute;
413 display: block;
414 height: 12px;
415 margin-bottom: 0px;
416 white-space: pre;
417 padding: floor(@basefontsize/4);
418 top: 0;
419 left: 0;
420 }
421
422 span{
423 color: @text-color;
424 z-index: 0;
425 min-width: 20px;
426 }
427
428 b {
429 z-index: 1;
427 z-index: 1;
430 overflow: hidden;
428 overflow: hidden;
431 background-color: @rcblue;
429 background-color: @rcblue;
@@ -437,6 +435,9 b' table.trending_language_tbl {'
437
435
438 // Changesets
436 // Changesets
439 #changesets.rctable {
437 #changesets.rctable {
438 th {
439 padding: 0 1em 0.65em 0;
440 }
440
441
441 // td must be fixed height for graph
442 // td must be fixed height for graph
442 td {
443 td {
@@ -13,15 +13,19 b''
13 font-size: (-1 + @basefontsize); //fit in tables
13 font-size: (-1 + @basefontsize); //fit in tables
14 line-height: .9em;
14 line-height: .9em;
15 border: none;
15 border: none;
16 box-shadow: @button-shadow;
16 .border-radius(@border-radius);
17 .border-radius(@border-radius);
17 font-family: @text-regular;
18 font-family: @text-regular;
18 background-image: none;
19 background-image: none;
19 color: @grey4;
20 color: @grey4;
20 .border ( @border-thickness-tags, @grey4 );
21 .border ( @border-thickness-tags, @grey5 );
21 white-space: nowrap;
22 white-space: nowrap;
22 a {
23 a {
23 color: inherit;
24 color: inherit;
24 text-decoration: underline;
25
26 &:hover {
27 color: @grey2;
28 }
25
29
26 i,
30 i,
27 [class^="icon-"]:before,
31 [class^="icon-"]:before,
@@ -29,6 +33,10 b''
29 text-decoration: none;
33 text-decoration: none;
30 }
34 }
31 }
35 }
36
37 &:hover {
38 border-color: @grey4;
39 }
32 }
40 }
33
41
34 .tag0 { .border ( @border-thickness-tags, @grey4 ); color:@grey4; }
42 .tag0 { .border ( @border-thickness-tags, @grey4 ); color:@grey4; }
@@ -46,6 +46,13 b' h6, .h6 { font-size: 1em; font-weight'
46 .breadcrumbs {
46 .breadcrumbs {
47 font-size: @repo-title-fontsize;
47 font-size: @repo-title-fontsize;
48 margin: 0;
48 margin: 0;
49 width: ~"calc(100% - 180px)";
50 float: left;
51
52 h4 {
53 font-size: @basefontsize;
54 margin-bottom: 15px;
55 }
49 }
56 }
50
57
51 .breadcrumbs_light {
58 .breadcrumbs_light {
@@ -156,6 +163,19 b' pre {'
156
163
157 // Emphasis & misc
164 // Emphasis & misc
158 // -------------------------
165 // -------------------------
166 .discreet {
167 color: @grey4;
168 font-size: 85%;
169 font-weight: normal;
170
171 a {
172 color: @grey4;
173
174 &:hover {
175 color: @rcdarkblue;
176 }
177 }
178 }
159
179
160 small,
180 small,
161 .small {
181 .small {
@@ -231,7 +251,8 b' mark,'
231 clear: both;
251 clear: both;
232 float: left;
252 float: left;
233 width: 100%;
253 width: 100%;
234 margin: @pagepadding/2 0 @pagepadding;
254 margin: @pagepadding/2 0 @pagepadding/4;
255 min-height: 25px;
235
256
236 .breadcrumbs {
257 .breadcrumbs {
237 float: left;
258 float: left;
@@ -285,6 +306,11 b' mark,'
285 }
306 }
286
307
287 .title-content {
308 .title-content {
309
310 &.repo-title {
311 float: none
312 }
313
288 float: left;
314 float: left;
289 margin: 0;
315 margin: 0;
290 padding: 0;
316 padding: 0;
@@ -8,13 +8,15 b''
8 @rchighlightblue: lighten(@rcblue, 35%);
8 @rchighlightblue: lighten(@rcblue, 35%);
9
9
10 // Secondary Colors (greyscale)
10 // Secondary Colors (greyscale)
11 @grey1: #202020; //midnight
11 @black: #000;
12 @grey2: #323232; //charcoal
12 @white: #fff;
13 @grey3: #666666; //tungsten
13 @grey1: #2B2B2D; //midnight
14 @grey4: #979797; //light grey
14 @grey2: #5C5C5C; //charcoal
15 @grey3: #7E7F7F; //tungsten
16 @grey4: #949494; //light grey
15 @grey5: #dbd9da; //greyish
17 @grey5: #dbd9da; //greyish
16 @grey6: #eeeeee; //silver
18 @grey6: #eeeeee; //silver
17 @grey7: #f9f9f9; //light silver
19 @grey7: #F5F5F5; //light silver
18
20
19 // special for navigation
21 // special for navigation
20 @nav-grey: #CDCCCD;
22 @nav-grey: #CDCCCD;
@@ -102,7 +104,7 b''
102
104
103 // FORMS (new)
105 // FORMS (new)
104 @border-thickness-inputs: 1px;
106 @border-thickness-inputs: 1px;
105 @input-padding: @button-padding; //needs to match button padding
107 @input-padding: .6em; //needs to match button padding
106 // TODO: johbo: Needed for working computation of paddings around labels etc.
108 // TODO: johbo: Needed for working computation of paddings around labels etc.
107 // Expected to be replaced once we are done with the form refactoring.
109 // Expected to be replaced once we are done with the form refactoring.
108 @input-padding-px: 12px;
110 @input-padding-px: 12px;
@@ -128,10 +130,14 b''
128 @fields-input-l: 720px;
130 @fields-input-l: 720px;
129
131
130 // BUTTONS
132 // BUTTONS
131 @button-padding: .9em;
133 @button-padding: .7em;
134 @button-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.07);
135
136 // DROPDOWNS
137 @dropdown-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.07);
132
138
133 // DEFAULT WIDTHS
139 // DEFAULT WIDTHS
134 @wrapper-maxwidth: 1200px;
140 @wrapper-maxwidth: 1600px;
135 @sidebar-width: 145px;
141 @sidebar-width: 145px;
136 @sidebar-all-width: @sidebar-width + 2 * @sidebarpadding;
142 @sidebar-all-width: @sidebar-width + 2 * @sidebarpadding;
137 @sidebar-small-width: 100px;
143 @sidebar-small-width: 100px;
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,78 +1,134 b''
1 <?xml version="1.0" standalone="no"?>
1 <?xml version="1.0" standalone="no"?>
2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3 <svg xmlns="http://www.w3.org/2000/svg">
3 <svg xmlns="http://www.w3.org/2000/svg">
4 <metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
4 <metadata>Copyright (C) 2019 by original authors @ fontello.com</metadata>
5 <defs>
5 <defs>
6 <font id="rcicons" horiz-adv-x="1000" >
6 <font id="rcicons" horiz-adv-x="1000" >
7 <font-face font-family="rcicons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
7 <font-face font-family="rcicons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
8 <missing-glyph horiz-adv-x="1000" />
8 <missing-glyph horiz-adv-x="1000" />
9 <glyph glyph-name="directory" unicode="&#xe800;" 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" />
9 <glyph glyph-name="delete" unicode="&#xe800;" d="M515 758c-211 0-384-173-384-385 0-211 173-385 384-385s385 174 385 385c0 212-173 385-385 385z m227-416c0-15-11-27-30-27h-397c-15 0-30 12-30 27v62c0 15 11 27 30 27h397c15 0 30-12 30-27v-62z" horiz-adv-x="1000" />
10
10
11 <glyph glyph-name="bookmark" unicode="&#xe803;" d="M767-96l-234 267c-8 12-25 12-33 0l-233-267c-17-17-42-4-42 25v842c0 17 13 33 25 33h533c13 0 25-16 25-33v-838c0-29-25-46-41-29z" horiz-adv-x="1000" />
11 <glyph glyph-name="ok" unicode="&#xe801;" d="M515 735c-211 0-384-173-384-385 0-211 173-385 384-385s385 174 385 385c0 212-173 385-385 385z m239-296l-304-304c-11-12-27-12-38 0l-139 138c-11 12-11 27 0 39l42 42c12 11 27 11 39 0l58-58c11-11 27-11 38 0l219 219c12 12 27 12 39 0l42-42c15-8 15-23 4-34z" horiz-adv-x="1000" />
12
13 <glyph glyph-name="comment" unicode="&#xe802;" d="M131 65v504c0 73 58 131 131 131h507c73 0 131-58 131-131v-288c0-73-58-131-131-131h-496c-4 0-11-4-15-8l-93-92c-11-15-34-4-34 15z m131 574c-39 0-73-31-73-74v-411l46 46c4 4 7 8 15 8h519c39 0 73 31 73 73v288c0 39-30 73-73 73h-507z" horiz-adv-x="1000" />
12
14
13 <glyph glyph-name="branch" unicode="&#xe804;" d="M829 579c0 67-54 121-121 121s-125-54-125-121c0-41 21-79 59-104-17-129-125-167-192-179v287c38 21 63 59 63 105 0 66-55 120-125 120s-121-54-121-120c0-46 25-84 62-105v-458c-37-25-62-62-62-108 0-67 54-121 121-121s120 54 120 121c0 46-25 83-62 104v50c58 8 154 29 225 100 50 50 79 117 87 196 46 25 71 66 71 112z m-441 150c20 0 41-16 41-41s-16-42-41-42c-21 0-42 17-42 42s21 41 42 41z m0-750c-21 0-42 17-42 42 0 21 17 42 42 42 20 0 41-17 41-42 0-25-16-42-41-42z m320 642c21 0 42-17 42-42s-17-41-42-41c-20 0-41 16-41 41s16 42 41 42z" horiz-adv-x="1000" />
15 <glyph glyph-name="bookmark" unicode="&#xe803;" d="M780-140l-260 290c-10 10-25 10-35 0l-260-295c-20-20-45-5-45 30v930c-5 20 10 35 25 35h590c15 0 30-15 30-35v-925c0-35-30-50-45-30z" horiz-adv-x="1000" />
16
17 <glyph glyph-name="branch" unicode="&#xe804;" d="M875 600c0 76-58 134-134 134s-134-58-134-134c0-49 27-89 63-112-18-142-139-183-210-196v313c45 22 71 62 71 111 0 76-58 134-134 134s-134-58-134-134c0-49 27-94 67-116v-500c-40-22-67-67-67-116 0-76 58-134 134-134s134 58 134 134c0 49-26 94-67 116v58c63 9 166 31 246 112 58 58 89 129 98 214 40 22 67 67 67 116z m-478 161c27 0 45-18 45-45s-18-45-45-45-44 18-44 45 18 45 44 45z m0-822c-26 0-44 18-44 45s18 45 44 45 45-18 45-45-22-45-45-45z m344 706c27 0 45-18 45-45s-18-45-45-45-45 18-45 45 23 45 45 45z" horiz-adv-x="1000" />
14
18
15 <glyph glyph-name="lock" unicode="&#xe806;" d="M817 429h-50v109c0 8 0 12 0 20 0 5 0 9 0 13 0 4 0 4 0 8 0 9-4 17-4 25 0 4 0 9-5 9-4 8-4 16-8 25 0 0 0 0 0 4-4 8-8 21-12 29 0 4-5 4-5 4-4 8-8 13-12 21 0 4-4 4-4 8-4 4-9 13-13 17 0 4-4 4-4 8-8 9-12 13-21 21 0 0-4 0-4 4-8 4-12 13-21 17-4 0-4 4-8 4-8 4-13 8-21 13-4 0-4 4-8 4-9 4-17 8-29 12 0 0 0 0 0 0-9 4-21 4-30 9-4 0-4 0-8 0-4 0-8 0-8 0 0 0-4 0-4 0 0 0-5 0-5 0 0 0 0 0 0 0 0 0 0 0 0 0-4 0-8 0-8 0-4 0-4 0-8 0-4 0-4 0-9 0 0 0 0 0 0 0-4 0-8 0-8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-4 0-4 0 0 0-4 0-4 0-4 0-9 0-9 0-4 0-8 0-8 0-8 0-21-5-29-9 0 0 0 0 0 0-38-12-50-16-58-21-5 0-5-4-9-4-4 0-12-4-16-8-5-4-9-4-9-4-8-4-16-13-25-17 0 0-4 0-4-4-4-4-12-13-21-21 0 0-4-4-4-8-4 0-12-9-17-13 0-4-4-4-4-8-4-8-8-13-12-21 0 0-4-4-4-4-5-13-9-21-13-29 0-4 0-4-4-9-4-8-4-12-8-20 0-5 0-9-5-9 0-8-4-16-4-25 0-4 0-4 0-8 0-4 0-8 0-13 0-8 0-12 0-20v-109h-46c-16 0-29-12-29-29v-475c0-17 13-29 29-29h638c17 0 29 12 29 29v475c-4 17-17 29-33 29z m-459 109c0 66 50 125 113 137 0 0 4 0 4 0 8 0 17 0 21 4 0 0 4 0 4 0 0 0 0 0 0 0 8 0 17 0 21-4 0 0 4 0 4 0 63-12 113-71 113-137v-109h-280v109z" horiz-adv-x="1000" />
19 <glyph glyph-name="tag" unicode="&#xe805;" d="M460 788l-366 8c-18 0-31-13-31-31l13-366c0-9 4-13 9-22l464-465c14-13 31-13 45 0l352 353c14 14 14 31 0 45l-468 469c-5 4-14 9-18 9z m-103-224c0-35-31-67-67-67-35 0-67 32-67 67 0 36 32 67 67 67s67-26 67-67z" horiz-adv-x="1000" />
20
21 <glyph glyph-name="lock" unicode="&#xe806;" d="M813 426h-54v107c0 9 0 13 0 18 0 4 0 9 0 13 0 5 0 5 0 9 0 9 0 14-4 23 0 4 0 4-5 9 0 8-4 13-9 22 0 0 0 4-4 4-5 9-9 18-14 27 0 0-4 5-4 5 4 8 0 17-5 22 0 4-4 4-4 9-5 4-9 13-14 18 0 0-4 4-4 4-9 9-13 14-22 22 0 0-5 0-5 5-4 4-13 9-22 13-5 0-5 5-9 5-4 4-13 9-18 9-4 0-4 4-9 4-9 5-18 9-27 9 0 0 0 0 0 0-9 5-17 5-31 9-4 0-4 0-9 0-4 0-4 0-9 0 0 0-4 0-4 0 0 0-5 0-5 0 0 0 0 0 0 0 0 0 0 0 0 0-4 0-9 0-9 0 0 0-4 0-4 0-4 0-4 0-9 0 0 0 0 0 0 0-4 0-9 0-9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-4 0-4 0 0 0-5 0-5 0-4 0-4 0-9 0-4 0-4 0-9 0-9 0-22-4-31-9 0 0 0 0 0 0-22 0-36-4-45-9-4 0-4-4-8-4-5-5-9-5-18-9 0-5-5-5-5-5-9-4-18-9-22-18 0 0-5 0-5-4-9-4-13-9-22-18 0 0-4-4-4-4-5-5-9-14-14-18 0-5-4-5-4-9-9-5-14-14-14-18-4 0-4-4-4-4-5-9-9-18-13-27 0 0 0-5-5-5 0-13-4-18-4-26 0-5 0-5-5-9 0-9-4-14-4-23 0-4 0-4 0-9 0-4 0-9 0-13 0-5 0-13 0-18v-107h-49c-18 0-27-13-27-27v-464c0-18 13-27 27-27h620c18 0 27 13 27 27v464c4 18-9 27-22 27z m-451 107c0 67 49 121 111 134 0 0 0 0 5 0 9 0 13 0 22 0 0 0 5 0 5 0 0 0 0 0 0 0 8 0 13 0 22 0 0 0 0 0 4 0 63-13 112-67 112-134v-107h-281v107z" horiz-adv-x="1000" />
16
22
17 <glyph glyph-name="unlock" unicode="&#xe807;" d="M817 429h-459v109c0 66 50 125 113 137 0 0 4 0 4 0 8 0 17 0 21 4 0 0 4 0 4 0 0 0 0 0 4 0 9 0 17 0 25-4 0 0 0 0 0 0 9 0 17-4 25-8 0 0 4 0 4-4 9-5 13-9 21-13 0 0 0 0 0 0 9-4 13-8 17-17 0 0 4-4 4-4 4-4 8-8 13-16 0 0 0-5 4-5 4-8 8-12 12-20 0 0 0-5 4-5 5-8 5-12 5-20 0 0 0-5 0-5 0 0 0 0 0-4 4-12 16-25 29-25h66c17 0 30 17 30 34 0 0 0 0 0 0 0 4 0 4 0 4 0 8-5 16-5 25 0 4 0 8-4 8-4 8-4 17-8 21 4 17 4 17 4 21-4 8-8 16-12 29 0 4-5 4-5 4-4 8-8 13-12 21 0 4-4 4-4 8-4 4-9 13-13 17 0 4-4 4-4 8-8 9-12 13-21 21 0 0-4 0-4 4-8 4-12 13-21 17-12-4-16-4-16-4-9 4-13 8-21 12-4 0-4 4-9 4-8 5-16 9-29 13 0 0 0 0 0 0-8 4-21 4-29 8-4 0-4 0-8 0-9 0-17 0-25 4-4 0-9 0-9 0-8 0-16 0-29 0 0 0-4 0-4 0-8 0-21-4-29-4-8 0-13-4-21-4 0 0-4 0-4 0-113-42-188-142-188-262v-109h-50c-16 0-29-12-29-29v-475c0-17 13-29 29-29h634c16 0 29 12 29 29v475c0 17-13 29-29 29z" horiz-adv-x="1000" />
23 <glyph glyph-name="unlock" unicode="&#xe807;" d="M781 415h-385v93c0 57 43 104 96 115 0 0 0 0 4 0 8 0 12 0 19 0 0 0 4 0 4 0 0 0 0 0 4 0 8 0 16 0 23-4 0 0 0 0 0 0 8 0 12-4 19-7 0 0 4 0 4-4 4-4 12-4 16-8 0 0 0 0 0 0 4-4 11-8 15-11 0 0 4-4 4-4 4-4 8-8 11-12 0 0 0 0 4-4 4-4 8-11 12-19 0 0 0-4 0-4 4-4 4-11 4-15 0 0 0-4 0-4 0 0 0 0 0-4 4-11 11-19 23-19h57c16 0 27 11 24 27 0 0 0 0 0 0 0 0 0 4 0 4 0 7-4 11-4 19 0 4 0 4-4 8 0 15 0 19-4 27 0 0 0 3-4 3-4 8-8 16-11 23 0 0-4 4-4 4-4 8-8 12-12 16 0 4-4 4-4 7-3 4-7 12-11 16 0 0-4 4-4 4-8 7-12 11-19 19 0 0-4 0-4 4-4 4-12 7-19 11-4 0-4 4-8 4-4 4-12 8-15 8-4 0-4 4-8 4-8 3-15 7-23 7 0 0 0 0 0 0-8 4-16 4-27 8-4 0-4 0-8 0-7 0-11 0-19 4-4 0-8 0-8 0-7 0-15 0-23 0 0 0-4 0-4 0-7 0-15-4-27-4-3 0-11-4-15-4 0 0-4 0-4 0-92-27-157-115-157-215v-93h-43c-15 0-23-11-23-23v-400c0-15 12-23 23-23h535c15 0 23 12 23 23v400c4 12-8 23-23 23z" horiz-adv-x="1000" />
18
24
19 <glyph glyph-name="delete" unicode="&#xe808;" d="M500 804c-254 0-454-204-454-454 0-250 204-454 454-454s454 204 454 454c0 250-204 454-454 454z m267-491c0-17-17-34-34-34h-466c-21 0-34 13-34 34v75c0 16 17 33 34 33h466c21 0 34-13 34-33v-75z" horiz-adv-x="1000" />
25 <glyph glyph-name="feed" unicode="&#xe808;" d="M842 739h-653c-35 0-58-27-58-58v-658c0-31 27-58 58-58h657c31 0 58 27 58 58v658c-4 31-31 58-62 58z m-534-666c-39 0-73 31-73 73s30 73 73 73c38 0 73-30 73-73s-35-73-73-73z m246-11c-35 0-58 27-58 57 0 112-88 200-200 200-31 0-65 27-65 58 0 35 23 62 54 62l11 0c177 0 319-143 319-320-3-30-30-57-61-57z m196 0c-35 0-58 27-58 57 0 220-180 400-400 400-30 0-65 27-65 62 0 34 23 61 54 61l11 0c285 0 520-230 520-519 0-34-27-61-62-61z" horiz-adv-x="1000" />
26
27 <glyph glyph-name="left" unicode="&#xe809;" d="M692 773l70-69c11-12 11-27 0-39l-289-288c-11-12-11-27 0-38l296-297c12-11 12-27 0-38l-69-69c-11-12-27-12-38 0l-404 404c-12 11-12 26 0 38l396 396c11 12 27 12 38 0z" horiz-adv-x="1000" />
20
28
21 <glyph glyph-name="ok" unicode="&#xe809;" d="M500 804c-250 0-454-204-454-454 0-250 204-454 454-454s454 204 454 454c0 250-204 454-454 454z m283-346l-358-358c-12-12-33-12-46 0l-162 163c-13 12-13 33 0 45l50 50c12 13 33 13 46 0l66-66c13-13 34-13 46 0l263 262c12 13 33 13 45 0l50-50c13-16 13-37 0-46z" horiz-adv-x="1000" />
29 <glyph glyph-name="right" unicode="&#xe80a;" d="M339-65l-74 69c-11 11-11 27 0 38l289 289c11 11 11 27 0 38l-296 296c-12 12-12 27 0 39l69 69c12 12 27 12 38 0l404-404c12-11 12-27 0-38l-392-396c-12-12-31-12-38 0z" horiz-adv-x="1000" />
30
31 <glyph glyph-name="down" unicode="&#xe80b;" d="M704 454l-173-219c-8-8-23-8-27 0l-173 219c-8 11 0 31 15 31h346c12 0 20-20 12-31z" horiz-adv-x="1000" />
22
32
23 <glyph glyph-name="comment" unicode="&#xe80a;" d="M42-13v601c0 87 71 154 154 154h600c87 0 154-71 154-154v-342c0-88-71-154-154-154h-583c-9 0-13-4-17-9l-113-112c-12-17-41-4-41 16z m158 684c-46 0-87-38-87-88v-487l54 54c4 4 12 8 16 8h617c46 0 88 38 88 88v342c0 45-38 87-88 87h-600z" horiz-adv-x="1000" />
33 <glyph glyph-name="folder" unicode="&#xe80c;" 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" />
34
35 <glyph glyph-name="folder-open" unicode="&#xe80d;" d="M1049 319q0-17-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-18h303q52 0 88-37t37-88z" horiz-adv-x="1071.4" />
24
36
25 <glyph glyph-name="feed" unicode="&#xe80b;" d="M888 804h-780c-37 0-66-29-66-66v-780c0-37 29-66 66-66h780c37 0 66 29 66 66v780c0 37-29 66-66 66z m-638-787c-46 0-83 37-83 83 0 46 37 88 87 88 46 0 88-38 88-88-4-46-46-83-92-83z m292-13c-38 0-71 34-71 71 0 133-108 238-238 238-37 0-75 29-75 66 0 38 25 71 63 71l12 0c209 0 380-171 380-379 0-33-30-67-71-67z m237 0c-37 0-71 34-71 71 0 263-212 475-475 475-37 0-75 29-75 67 0 37 25 71 63 71l12 0c338 0 613-275 613-613 4-37-29-71-67-71z" horiz-adv-x="1000" />
37 <glyph glyph-name="trash-empty" unicode="&#xe80e;" d="M286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15 6-5h464q2 0 6 5t8 15 4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q23 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
26
38
27 <glyph glyph-name="right" unicode="&#xe80c;" d="M308-96l-75 75c-12 13-12 29 0 42l309 308c12 13 12 29 0 42l-317 312c-12 13-12 30 0 42l75 75c13 13 29 13 42 0l433-433c13-13 13-29 0-42l-425-421c-8-12-29-12-42 0z" horiz-adv-x="1000" />
39 <glyph glyph-name="group" unicode="&#xe80f;" d="M962 219v-15c0-4-4-12-12-12h-161-4c-16 20-39 39-77 43-35 7-54 15-69 23 7 7 19 11 30 15 46 8 58 23 66 35 7 11 7 23 0 38-8 16-31 43-31 81 0 38 0 104 73 104h8 7c73-4 77-66 73-104 0-38-23-69-30-81-8-15-8-27 0-38 7-12 23-27 65-35 54-4 62-46 62-54 0 0 0 0 0 0z m-708-15c15 15 38 31 69 35 39 7 62 15 73 26-7 8-19 16-34 20-47 7-58 23-66 34-7 12-7 23 0 39 8 15 31 42 31 81 0 38 0 103-73 103h-8-11c-73-3-77-65-73-103 0-39 23-70 30-81 8-16 8-27 0-39-7-11-23-27-65-34-46-8-54-50-54-54 0 0 0 0 0 0v-16c0-3 4-11 12-11h161 8z m454 11c-73 12-96 35-108 54-11 20-11 39 0 62 12 23 50 69 54 131 4 61 0 165-119 169h-16-15c-119-4-123-104-119-166 4-61 38-107 54-130 11-23 11-43 0-62-12-19-35-42-108-54-73-11-85-80-85-88 0 0 0 0 0 0v-23c0-8 8-16 16-16h257 258c8 0 15 8 15 16v23c0 0 0 0 0 0-3 4-11 73-84 84z" horiz-adv-x="1000" />
40
41 <glyph glyph-name="remove" unicode="&#xe810;" 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" />
28
42
29 <glyph glyph-name="left" unicode="&#xe80d;" d="M683 800l75-75c13-12 13-29 0-42l-308-308c-12-12-12-29 0-42l317-316c12-13 12-30 0-42l-75-75c-13-13-29-13-42 0l-433 433c-13 13-13 30 0 42l425 425c12 13 29 13 41 0z" horiz-adv-x="1000" />
43 <glyph glyph-name="fork" unicode="&#xe811;" d="M792 654c0 58-46 100-100 100-57 0-100-46-100-100 0-35 20-65 47-85-12-84-70-123-127-142-58 15-116 54-127 142 27 20 46 50 46 85 0 58-46 100-100 100s-108-42-108-100c0-39 23-73 54-89 12-107 77-188 181-226v-162c-31-19-50-50-50-88 0-58 46-101 100-101s100 47 100 101c0 38-19 69-50 88v162c104 38 169 119 181 226 30 20 53 50 53 89z m-465 35c19 0 35-16 35-35s-16-31-35-31-35 12-35 31 16 35 35 35z m181-635c-19 0-35 15-35 35s16 34 35 34c19 0 34-15 34-34s-15-35-34-35z m184 635c20 0 35-16 35-35s-15-31-35-31-34 16-34 35 15 31 34 31z" horiz-adv-x="1000" />
44
45 <glyph glyph-name="more" unicode="&#xe812;" d="M546 435h-100c-15 0-27-12-27-27v-100c0-16 12-27 27-27h100c16 0 27 11 27 27v100c0 15-11 27-27 27z m0 307h-100c-15 0-27-11-27-27v-100c0-15 12-26 27-26h100c16 0 27 11 27 26v100c0 16-11 27-27 27z m0-615h-100c-15 0-27-12-27-27v-100c0-15 12-27 27-27h100c16 0 27 12 27 27v100c0 15-11 27-27 27z" horiz-adv-x="1000" />
30
46
31 <glyph glyph-name="arrow_down" unicode="&#xe80e;" d="M950 542l-412-521c-17-21-50-21-67 0l-417 521c-21 25-4 71 34 71h829c37 0 58-46 33-71z" horiz-adv-x="1000" />
47 <glyph glyph-name="search" unicode="&#xe813;" d="M643 386q0 103-73 176t-177 74-177-74-73-176 73-177 177-73 177 73 73 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 153-31 125-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
48
49 <glyph glyph-name="scissors" unicode="&#xe814;" d="M536 350q14 0 25-11t10-25-10-25-25-10-25 10-11 25 11 25 25 11z m167-36l283-222q16-11 14-31-3-20-19-28l-72-36q-7-4-16-4-10 0-17 4l-385 216-62-36q-4-3-7-3 8-28 6-54-4-43-31-83t-74-69q-74-47-154-47-76 0-124 44-51 47-44 116 4 42 31 82t73 69q74 47 155 47 46 0 84-18 5 8 13 13l68 40-68 41q-8 5-13 12-38-17-84-17-81 0-155 47-46 30-73 69t-31 82q-3 33 8 63t36 52q47 44 124 44 80 0 154-47 46-29 74-68t31-83q2-27-6-54 3-1 7-3l62-37 385 216q7 5 17 5 9 0 16-4l72-36q16-9 19-28 2-20-14-32z m-380 145q26 24 12 61t-59 65q-52 33-107 33-42 0-63-20-26-24-12-60t59-66q51-33 107-33 41 0 63 20z m-47-415q45 28 59 65t-12 60q-22 20-63 20-56 0-107-33-45-28-59-65t12-60q21-20 63-20 55 0 107 33z m99 342l54-33v7q0 20 18 31l8 4-44 26-15-14q-1-2-5-6t-7-7q-1-1-2-2t-2-1z m125-125l54-18 410 321-71 36-429-240v-64l-89-53 5-5q1-1 4-3 2-2 6-7t6-6l15-15z m393-232l71 35-290 228-99-77q-1-2-7-4z" horiz-adv-x="1000" />
32
50
33 <glyph glyph-name="git" unicode="&#xe80f;" d="M896 808h-792c-33 0-62-29-62-62v-792c0-33 29-62 62-62h792c33 0 62 29 62 62v792c0 33-29 62-62 62z m-4-850h-788v788h788v-788z m-667 338c-4 12-8 25-8 42 0 12 0 25 4 37 4 13 8 21 12 33s13 21 21 30 17 16 25 20c13 0 21 5 34 9 8 4 20 4 33 4 8 0 21 0 29-4 8 0 17-4 21-9 8-4 12-8 17-12 4-4 8-8 12-13l-17-20c-4-5-4-5-8-9-4 0-8 0-12 4-5 5-9 5-13 9-4 0-8 4-8 4-4 0-9 4-13 4-4 0-8 0-12 0-9 0-21-4-29-8-9-4-17-13-21-17-4-8-13-17-13-29-4-13-4-25-4-38 0-8 0-20 4-29 4-8 4-16 13-21 4-4 8-8 16-12 9-4 13-4 21-4 9 0 13 0 17 0 4 0 8 4 17 4l4 37h-25c-4 0-4 0-9 5s0 8 0 12l5 29h79l-13-100c-4-4-12-8-16-12-9-4-13-4-21-9-9 0-13-4-21-4-8 0-17 0-25 0-13 0-29 4-42 9-12 4-21 12-29 20-12 13-21 21-25 38z m300-63h-54l29 234h54l-29-234z m146 192h-58l4 42h171l-5-42h-58l-25-192h-54l25 192z" horiz-adv-x="1000" />
51 <glyph glyph-name="download" unicode="&#xe815;" d="M714 100q0 15-10 25t-25 11-25-11-11-25 11-25 25-11 25 11 10 25z m143 0q0 15-10 25t-26 11-25-11-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-37t-38-16h-821q-23 0-38 16t-16 37v179q0 22 16 38t38 16h259l75-76q33-32 76-32t76 32l76 76h259q22 0 38-16t16-38z m-182 318q10-23-8-39l-250-250q-10-11-25-11t-25 11l-250 250q-17 16-8 39 10 21 33 21h143v250q0 15 11 25t25 11h143q14 0 25-11t10-25v-250h143q24 0 33-21z" horiz-adv-x="928.6" />
52
53 <glyph glyph-name="doc" unicode="&#xe816;" 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 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z" horiz-adv-x="857.1" />
34
54
35 <glyph glyph-name="hg" unicode="&#xe810;" d="M896 808h-792c-33 0-62-29-62-62v-792c0-33 29-62 62-62h792c33 0 62 29 62 62v792c-4 33-29 62-62 62z m-4-850h-788v788h788v-788z m-571 275h-54l29 234h54l-12-100h83l12 100h55l-30-234h-54l13 100h-84l-12-100z m217 63c-5 12-9 25-9 42 0 12 0 25 4 37 5 13 9 21 13 33 4 9 12 21 21 25s16 17 25 21c8 4 21 9 29 13 12 4 21 4 33 4 9 0 21 0 29-4s17-4 21-9c9-4 13-8 17-12 4-4 8-8 12-13l-16-20c-4-5-4-5-9-9-4 0-8 0-12 4-4 5-8 5-13 9-4 0-8 4-8 4-4 0-8 4-12 4-5 0-9 0-13 0-8 0-21-4-29-8-8-4-17-13-21-17s-12-17-12-29c-5-13-5-25-5-38 0-8 0-20 5-29 4-8 4-16 12-21 4-4 8-8 17-12 8-4 12-4 21-4 8 0 12 0 16 0 4 0 9 4 17 4l4 37h-21c-4 0-4 0-8 5s-4 4 0 8l4 29h79l-12-100c-4-4-13-8-17-12-8-5-12-5-21-9-8 0-12-4-21-4-8 0-16 0-25 0-12 0-29 4-41 8-13 5-21 13-29 21-13 17-21 29-25 42z" horiz-adv-x="1000" />
55 <glyph glyph-name="cog" unicode="&#xe817;" d="M571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 16 20 16h124q7 0 13-5t7-12l15-103q28-9 51-20l79 59q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-12 0-7-4-13-9-12-29-37t-30-40q15-28 23-54l102-16q7-1 12-7t4-13z" horiz-adv-x="857.1" />
56
57 <glyph glyph-name="cog-alt" unicode="&#xe818;" 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-8-6l-87-14q-6-19-18-42 19-27 50-64 4-6 4-11 0-7-4-11-12-17-46-50t-43-33q-7 0-12 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 11v104q0 5 4 10t9 6l86 14q7 19 18 42-19 27-50 64-4 6-4 11 0 7 4 12 12 16 46 49t44 33q6 0 12-4l64-50q19 10 43 18 6 60 13 86 3 13 16 13h104q6 0 11-4t6-10l13-85q19-6 42-17l65 49q5 4 12 4 6 0 11-4 81-75 81-90 0-4-4-10-7-9-24-30t-25-34q13-27 19-46l85-12q6-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-37q12 1 17 1t17-1q28 39 51 62l4 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" />
36
58
37 <glyph glyph-name="svn" unicode="&#xe811;" d="M896 808h-792c-33 0-62-29-62-62v-796c0-29 29-58 62-58h796c33 0 63 29 63 62v792c-5 33-34 62-67 62z m0-854h-792v792h788v-792z m-717 296c-4 4-8 8-12 13l21 25c0 0 4 4 4 4 4 0 4 0 8 0 4 0 4 0 8-4 5 0 5-5 9-9 4-4 8-4 12-8 4 0 9-4 17-4 8 0 17 4 21 8 4 4 8 13 8 25 0 4 0 8-4 13-4 4-4 4-8 8-5 4-9 4-13 4-4 0-8 4-17 4-4 0-12 4-16 9-4 4-9 8-13 12-4 4-8 8-8 17-4 4-4 12-4 21 0 12 0 20 4 29 4 8 8 16 17 25 8 8 16 12 25 16 12 9 25 13 37 13 8 0 13 0 21 0 8 0 12-4 17-4 4-4 12-4 16-9 4-8 9-12 9-16l-17-21c0-4-4-4-4-4 0 0-4 0-9 0-4 0-4 0-8 4-4 0-4 4-8 4-4 0-9 4-13 4-4 0-8 4-12 4-4 0-9 0-13 0-4 0-8-4-8-4-4-4-4-4-4-8 0-4 0-8 0-13 0-4 0-8 4-12 4-4 4-4 8-8 4-5 9-5 13-5 4 0 8-4 16-4 5-4 13-4 17-8 4-4 8-8 13-13s8-8 8-16c4-4 4-13 4-21 0-13 0-25-4-33-4-13-8-21-17-30-8-8-16-12-29-16-12-4-25-9-37-9-9 0-13 0-21 5s-13 4-21 8c-4-4-13 0-17 4z m250-17l-54 234h42c4 0 8 0 12-4 4-5 4-5 4-9l25-129c0-4 5-12 5-17 0-8 4-12 4-20 4 8 4 12 8 20 4 9 4 13 8 17l55 129c0 0 0 4 4 4 0 0 4 5 4 5 0 0 4 0 4 4 0 0 4 0 4 0h42l-117-238h-50z m221 0h-46l29 238h30c4 0 4 0 4 0 0 0 4 0 4 0 0 0 4 0 4-4 0 0 0-4 4-4l84-146c0 4 0 8 0 12 0 4 0 9 0 9l16 133h46l-29-238h-29c-4 0-9 0-9 0-4 0-4 5-8 9l-83 146c0-5 0-5 0-9 0-4 0-4 0-8l-17-138z" horiz-adv-x="1000" />
59 <glyph glyph-name="eye" unicode="&#xe819;" d="M929 314q-85 132-213 197 34-58 34-125 0-103-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 243 68 186 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 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" />
60
61 <glyph glyph-name="eye-off" unicode="&#xe81a;" 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-11 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-91l157 280q4-25 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-85t81-103q11-19 11-39z" horiz-adv-x="1000" />
38
62
39 <glyph glyph-name="group" unicode="&#xe812;" d="M958 221v-17c0-4-4-8-8-8h-167-4c-16 21-41 37-79 46-37 4-58 16-71 25 9 8 17 12 34 16 45 9 62 21 66 38s9 25 0 37c-8 13-33 46-33 84 0 41 0 104 75 108h8 13c75-4 79-71 75-108 0-42-25-71-34-84-8-16-8-25 0-37s21-29 67-38c54-12 58-58 58-62 0 0 0 0 0 0z m-725-17c17 17 38 34 71 38 42 8 63 16 75 25-8 8-21 16-37 21-46 8-63 20-67 37-8 13-8 25 0 38 8 12 33 45 33 83 0 42 0 104-75 108h-12-8c-75-4-80-71-80-108 0-42 25-71 34-83 8-17 8-25 0-38-9-12-21-29-67-37-50-9-54-50-54-59 0 0 0 0 0 0v-16c0-5 4-9 8-9h167 12z m463 13c-75 12-96 37-108 58-13 21-13 42 0 63 12 25 50 70 54 133 4 62 0 167-121 175h-21-17c-116-4-120-113-120-175 4-63 41-113 54-133 12-25 12-42 0-63-13-21-38-46-109-58-75-13-87-84-87-92 0 0 0 0 0 0v-25c0-8 8-17 17-17h262 267c8 0 16 9 16 17v25c0 0 0 0 0 0 0 8-8 79-87 92z" horiz-adv-x="1000" />
63 <glyph glyph-name="cancel-circled2" unicode="&#xe81b;" d="M612 248l-81-82q-6-5-13-5t-13 5l-76 77-77-77q-5-5-13-5t-12 5l-82 82q-6 6-6 13t6 13l76 76-76 77q-6 5-6 12t6 13l82 82q5 5 12 5t13-5l77-77 76 77q6 5 13 5t13-5l81-82q6-5 6-13t-6-12l-76-77 76-76q6-6 6-13t-6-13z m120 102q0 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" />
64
65 <glyph glyph-name="cancel-circled" unicode="&#xe81c;" 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-25 11-16 0-26-11l-50-50q-11-11-11-26 0-14 11-25l101-101-101-101q-11-11-11-25 0-15 11-26l50-50q10-11 26-11 14 0 25 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" />
40
66
41 <glyph glyph-name="folder" unicode="&#xe813;" d="M742 17h-659c-12 0-25 8-33 16-8 13-8 25 0 38l179 342c4 12 17 20 34 20h658c12 0 25-8 33-16 9-13 9-25 0-38l-179-341c-8-13-21-21-33-21z m-596 75h575l142 266h-580l-137-266z m-29-38h-75v550c0 21 16 38 37 38h246c8 0 21-4 25-13l54-54h325c21 0 38-17 38-37v-105h-75v67h-300c-9 0-17 4-25 8l-59 59h-191v-513z" horiz-adv-x="1000" />
67 <glyph glyph-name="plus" unicode="&#xe81d;" 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-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" />
42
68
43 <glyph glyph-name="fork" unicode="&#xe814;" d="M838 688c0 66-55 120-121 120-67 0-121-54-121-120 0-42 21-80 54-100-12-100-83-146-150-167-71 21-137 67-150 167 33 20 54 58 54 100 0 66-54 120-121 120s-120-54-120-120c0-46 29-88 66-109 13-129 88-225 213-271v-191c-38-21-63-59-63-100 0-67 54-121 121-121s121 54 121 121c0 46-25 83-58 104v192c120 45 200 137 212 270 33 17 63 59 63 105z m-555 37c21 0 42-17 42-42s-17-41-42-41-41 16-41 41 21 42 41 42z m217-750c-21 0-42 17-42 42 0 21 17 41 42 41s42-16 42-41c0-25-21-42-42-42z m217 750c21 0 41-17 41-42s-16-41-41-41-42 16-42 41 21 42 42 42z" horiz-adv-x="1000" />
69 <glyph glyph-name="plus-circled" unicode="&#xe81e;" 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-10h143v-143q0-15 11-25t25-11h71q15 0 25 11t11 25v143h143q14 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" />
70
71 <glyph glyph-name="minus-circled" unicode="&#xe81f;" 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" />
44
72
45 <glyph glyph-name="more" unicode="&#xe815;" d="M592 408v-120c0-17-13-34-34-34h-120c-17 0-34 13-34 34v120c0 17 13 34 34 34h120c21 0 34-17 34-34z m-34 400h-120c-17 0-34-12-34-33v-121c0-16 13-33 34-33h120c17 0 34 12 34 33v121c0 21-13 33-34 33z m0-733h-120c-17 0-34-12-34-33v-121c0-17 13-34 34-34h120c17 0 34 13 34 34v121c0 16-13 33-34 33z" horiz-adv-x="1000" />
73 <glyph glyph-name="minus" unicode="&#xe820;" d="M786 439v-107q0-22-16-38t-38-15h-678q-23 0-38 15t-16 38v107q0 23 16 38t38 16h678q23 0 38-16t16-38z" horiz-adv-x="785.7" />
74
75 <glyph glyph-name="info-circled" unicode="&#xe821;" d="M571 82v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h250q7 0 12 5t5 13z m-71 500v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h107q8 0 13 5t5 13z m357-232q0-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" />
46
76
47 <glyph glyph-name="comment-add" unicode="&#xe816;" d="M48-12v593c0 86 69 155 154 155h596c85 0 154-69 154-155v-338c0-86-69-155-154-155h-584c-7 0-12-2-16-7l-110-110c-14-14-40-4-40 17z m154 679c-47 0-85-38-85-86v-486l52 53c5 4 10 7 17 7h612c47 0 85 38 85 86v340c0 48-38 86-85 86h-596z m479-284l0 48c0 5-5 10-10 10l-114 0c-5 0-9 4-9 9v114c0 5-5 10-10 10h-47c-5 0-10-5-10-10v-114c0-5-5-9-10-9h-114c-5 0-9-5-9-10v-48c0-4 4-9 9-9h114c5 0 10-5 10-10l0-114c0-5 5-9 10-9l47 0c5 0 10 4 10 9v114c0 5 4 10 9 10h114c5-3 10 2 10 9z" horiz-adv-x="1000" />
77 <glyph glyph-name="upload" unicode="&#xe822;" d="M714 29q0 14-10 25t-25 10-25-10-11-25 11-25 25-11 25 11 10 25z m143 0q0 14-10 25t-26 10-25-10-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-38t-38-16h-821q-23 0-38 16t-16 38v179q0 22 16 38t38 15h238q12-31 39-51t62-20h143q34 0 61 20t40 51h238q22 0 38-15t16-38z m-182 361q-9-22-33-22h-143v-250q0-15-10-25t-25-11h-143q-15 0-25 11t-11 25v250h-143q-23 0-33 22-9 22 8 39l250 250q10 10 25 10t25-10l250-250q18-17 8-39z" horiz-adv-x="928.6" />
78
79 <glyph glyph-name="home" unicode="&#xe823;" d="M888 336q16-16 11-27t-27-11l-84 0 0-310q0-14-1-21t-8-13-23-6l-204 0 0 310-204 0 0-310-194 0q-28 0-35 10t-7 30l0 310-84 0q-22 0-27 11t11 27l400 402q16 16 38 16t38-16z" horiz-adv-x="900" />
48
80
49 <glyph glyph-name="comment_toggle" unicode="&#xe818;" d="M798 736h-596c-85 0-154-69-154-155v-593c0-19 22-29 36-20 2 1 5 3 7 5l109 109c2 2 5 4 8 5 2 1 4 1 6 1h584c85 0 154 69 154 155v338c0 86-69 155-154 155z m-680-639v484c0 47 38 85 86 85h476c-86-84-504-511-509-515l-53-54z" horiz-adv-x="1000" />
81 <glyph glyph-name="git" unicode="&#xe82a;" d="M929 844h-858c-36 0-65-30-65-65v-857c0-36 30-65 65-65h857c36 0 65 30 65 65v857c1 35-29 65-64 65z m-729-549c4-11 9-20 14-27 6-8 14-14 22-18 9-4 19-6 29-6 9 0 16 1 24 2 7 2 14 4 20 7l6 51h-27c-4 0-8 1-10 4-2 1-3 5-3 7l5 39h105l-16-131c-8-7-16-12-25-15-9-4-18-8-28-10-10-3-18-5-30-7-10-1-21-2-33-2-20 0-38 4-54 11-16 8-30 18-41 30-12 13-20 28-27 45-6 18-10 36-10 56 0 18 3 34 7 50 3 17 10 30 17 44 8 14 16 25 26 36 10 12 22 20 34 28 13 7 26 14 41 17 15 4 30 7 47 7 13 0 25-2 36-4 11-3 21-6 29-10 8-4 16-9 22-14 6-5 13-11 18-16l-20-31c-4-5-9-8-14-9-5-1-10 0-16 4-5 3-10 6-14 8-5 3-9 5-14 7-5 1-10 2-15 3-5 2-11 2-17 2-14 0-27-3-38-9-11-6-21-14-29-25-8-10-15-24-18-38-5-15-7-31-7-48-1-14 2-27 4-38z m336-102h-71l39 315h71l-39-315z m343 258h-80l-33-258h-70l32 258h-80l7 57h231l-7-57z" horiz-adv-x="1000" />
50
82
51 <glyph glyph-name="git-inv" unicode="&#xe81a;" d="M929 844h-858c-36 0-65-30-65-65v-857c0-36 30-65 65-65h857c36 0 65 30 65 65v857c1 35-29 65-64 65z m-729-549c4-11 9-20 14-27 6-8 14-14 22-18 9-4 19-6 29-6 9 0 16 1 24 2 7 2 14 4 20 7l6 51h-27c-4 0-8 1-10 4-2 1-3 5-3 7l5 39h105l-16-131c-8-7-16-12-25-15-9-4-18-8-28-10-10-3-18-5-30-7-10-1-21-2-33-2-20 0-38 4-54 11-16 8-30 18-41 30-12 13-20 28-27 45-6 18-10 36-10 56 0 18 3 34 7 50 3 17 10 30 17 44 8 14 16 25 26 36 10 12 22 20 34 28 13 7 26 14 41 17 15 4 30 7 47 7 13 0 25-2 36-4 11-3 21-6 29-10 8-4 16-9 22-14 6-5 13-11 18-16l-20-31c-4-5-9-8-14-9-5-1-10 0-16 4-5 3-10 6-14 8-5 3-9 5-14 7-5 1-10 2-15 3-5 2-11 2-17 2-14 0-27-3-38-9-11-6-21-14-29-25-8-10-15-24-18-38-5-15-7-31-7-48-1-14 2-27 4-38z m336-102h-71l39 315h71l-39-315z m343 258h-80l-33-258h-70l32 258h-80l7 57h231l-7-57z" horiz-adv-x="1000" />
83 <glyph glyph-name="hg" unicode="&#xe82d;" d="M927 841h-853c-36 0-65-29-65-65v-853c0-36 29-65 65-65h853c36 0 65 29 65 65v853c0 36-29 65-65 65z m-483-648h-70l16 133h-113l-17-133h-70l39 313h70l-16-132h113l16 132h71l-39-313z m177 101c3-11 8-20 14-27 7-8 14-14 23-18 8-4 18-6 28-6 9 0 16 1 23 3 7 1 14 3 20 6l6 51h-27c-4 0-7 1-9 3-3 3-3 6-3 9l5 39h104l-16-131c-8-6-16-11-25-15-9-5-18-8-27-11-9-2-19-4-30-6-10-1-21-2-33-2-19 0-37 4-53 11-16 7-30 17-41 29-11 13-20 28-26 45-7 17-10 35-10 55 0 17 2 34 6 50 4 15 10 30 17 43 7 14 16 26 26 36 10 11 22 20 34 28 13 7 27 13 41 17 14 4 30 7 46 7 13 0 25-2 36-4 11-3 20-6 29-10 8-4 16-9 23-14 7-5 13-11 18-17l-23-28c-4-5-8-8-13-9-5-1-11 0-16 3-5 4-10 7-14 9-5 3-9 5-14 6-4 2-9 3-14 4-5 1-11 1-17 1-14 0-27-3-38-8-11-6-21-14-29-25-8-10-15-23-19-38-5-15-7-31-7-49 0-13 2-26 5-37z" horiz-adv-x="1000" />
84
85 <glyph glyph-name="svn" unicode="&#xe82e;" d="M933 841h-852c-36 0-65-29-65-65v-853c0-36 29-65 65-65h852c36 0 66 29 66 65v853c0 36-30 65-66 65z m-765-438c3-4 7-7 13-10 5-3 11-6 18-8 7-3 14-5 21-8 7-3 14-6 21-10 7-4 13-9 18-14 5-6 10-13 13-20 3-8 5-18 5-29 0-16-3-30-8-44-6-14-14-26-24-37-10-10-22-18-37-24-15-7-31-10-49-10-9 0-18 1-27 3s-18 5-27 9c-8 4-16 8-23 13-7 5-13 10-18 17l25 32c2 3 4 5 7 6 3 2 6 3 9 3 4 0 8-2 12-4 3-3 8-6 12-10 5-3 10-6 16-9 6-3 14-4 23-4 13 0 23 3 30 10 7 7 10 18 10 32 0 6-1 12-4 16-4 4-8 7-13 10-5 3-11 6-18 8-7 2-14 5-21 7-7 3-14 6-21 9-6 4-12 8-18 14-5 6-9 13-12 21-3 8-5 18-5 30 0 14 3 28 8 40 5 13 12 25 22 35 10 9 22 17 36 23 14 6 29 9 47 9 9 0 17-1 26-3s16-4 23-8c7-3 14-7 20-11 6-5 11-10 15-15l-21-29c-2-3-5-6-7-7-3-2-6-3-9-3-3 0-7 1-10 3-3 3-7 5-11 8-4 2-9 4-14 7-5 2-12 3-19 3-6 0-12-1-17-3-5-2-9-4-12-8-4-3-6-7-8-11-1-5-2-10-2-15 0-5 2-10 5-14z m312-210h-64l-77 313h57c6 0 10-1 14-4 4-3 6-6 7-11l32-173c2-7 4-14 6-23 1-8 3-17 4-26 3 9 6 18 9 26 4 9 7 16 11 23l73 173c1 2 2 4 4 6 2 2 4 3 6 5 2 1 4 2 7 3 3 1 5 1 8 1h57l-154-313z m423 0h-37c-5 0-10 1-13 2-4 2-7 5-10 9l-109 194c-1-4-1-8-1-12-1-4-1-7-1-10l-22-183h-62l39 313h37c3 0 6 0 8 0 2 0 4-1 5-1 2-1 3-2 4-4s3-3 5-5l110-194c0 5 0 10 1 14 0 5 1 9 1 13l21 177h62l-38-313z" horiz-adv-x="1000" />
52
86
53 <glyph glyph-name="hg-inv" unicode="&#xe81b;" d="M927 841h-853c-36 0-65-29-65-65v-853c0-36 29-65 65-65h853c36 0 65 29 65 65v853c0 36-29 65-65 65z m-483-648h-70l16 133h-113l-17-133h-70l39 313h70l-16-132h113l16 132h71l-39-313z m177 101c3-11 8-20 14-27 7-8 14-14 23-18 8-4 18-6 28-6 9 0 16 1 23 3 7 1 14 3 20 6l6 51h-27c-4 0-7 1-9 3-3 3-3 6-3 9l5 39h104l-16-131c-8-6-16-11-25-15-9-5-18-8-27-11-9-2-19-4-30-6-10-1-21-2-33-2-19 0-37 4-53 11-16 7-30 17-41 29-11 13-20 28-26 45-7 17-10 35-10 55 0 17 2 34 6 50 4 15 10 30 17 43 7 14 16 26 26 36 10 11 22 20 34 28 13 7 27 13 41 17 14 4 30 7 46 7 13 0 25-2 36-4 11-3 20-6 29-10 8-4 16-9 23-14 7-5 13-11 18-17l-23-28c-4-5-8-8-13-9-5-1-11 0-16 3-5 4-10 7-14 9-5 3-9 5-14 6-4 2-9 3-14 4-5 1-11 1-17 1-14 0-27-3-38-8-11-6-21-14-29-25-8-10-15-23-19-38-5-15-7-31-7-49 0-13 2-26 5-37z" horiz-adv-x="1000" />
87 <glyph glyph-name="comment-add" unicode="&#xe82f;" d="M952 258v317c0 7 0 13 0 20-1 12-4 24-8 36-7 22-20 43-37 59-16 17-36 30-58 37-12 4-25 7-37 8-7 1-13 1-19 1h-576c-13 0-26 0-38-2-13-2-25-5-36-10-22-9-41-23-57-40-15-18-27-39-33-62-3-12-5-25-5-38-1-13 0-26 0-39v-557c0-9 5-17 13-21 6-3 15-3 21 0 3 1 5 3 7 5 2 2 4 5 7 7 4 5 9 9 14 14l28 28c9 10 19 19 28 29 9 9 19 18 28 27 4 5 8 9 14 10 2 1 5 1 8 1h567c13 0 25 0 38 2 24 4 47 13 66 27 19 13 35 31 46 51 12 22 19 46 19 71 1 6 0 13 0 19z m-69 307v-317c0-7 0-13 0-19-1-6-3-13-5-18-4-10-9-20-16-28-15-17-37-27-59-28-7 0-13 0-19 0h-576c-7 0-13 0-20 0-3 0-6 0-9-1-3-1-5-2-7-4-2-2-4-4-6-6-3-2-5-4-7-7-5-4-10-9-14-14-10-9-19-18-28-28v485c0 12 2 24 7 35 4 10 10 19 18 27 16 16 38 25 60 25h590c6 0 12 0 18-1 22-3 42-15 56-33 7-9 12-20 15-31 1-5 2-12 2-18 1-6 0-13 0-19z m-214-117h-131c-4 0-11 8-11 12v126c0 8-8 16-12 16h-50c-7 0-15-8-15-12v-130c0-4-8-12-12-12h-126c-8 0-16-8-16-11v-50c0-8 8-16 12-16h127c7 0 15-7 15-11v-127c0-8 8-15 11-15h50c8 0 16 7 16 11v127c0 8 7 15 11 15h127c8 0 15 8 15 12v50c0 7-7 15-11 15z" horiz-adv-x="1000" />
88
89 <glyph glyph-name="comment-toggle" unicode="&#xe830;" d="M798 736h-596c-85 0-154-69-154-155v-593c0-19 22-29 36-20 2 1 5 3 7 5l109 109c2 2 5 4 8 5 2 1 4 1 6 1h584c85 0 154 69 154 155v338c0 86-69 155-154 155z m-680-639v484c0 47 38 85 86 85h476c-86-84-504-511-509-515l-53-54z" horiz-adv-x="1000" />
54
90
55 <glyph glyph-name="minus" unicode="&#xe81c;" d="M895 269h-790c-5 0-10 5-10 10v142c0 5 5 10 10 10h793c5 0 9-5 9-10v-142c-2-5-7-10-12-10z" horiz-adv-x="1000" />
91 <glyph glyph-name="rhodecode" unicode="&#xe831;" d="M175 633c-2-4-3-8-4-12-3-10-6-20-9-30-3-13-7-25-11-38-3-11-6-23-10-35-2-7-4-15-6-22-1-1-1-2-1-4 0 0 0 0 0 0 0-1 1-2 1-2 2-7 5-14 7-21 4-11 8-22 12-33 4-12 9-25 13-37 4-11 8-23 12-34 3-7 5-14 7-21 1-1 1-2 2-3 0-1 1-1 1-2 4-6 8-12 11-17 7-10 13-19 19-29 7-11 14-22 22-33 6-10 13-21 20-31 5-7 9-15 14-22 1-2 3-4 4-5 0-1 1-1 1-2 3-3 6-5 8-8 7-6 13-12 19-19 9-8 17-16 25-24 10-10 19-19 29-28 9-9 18-18 27-27 8-8 16-15 23-23 5-5 11-10 16-15 1-1 3-3 5-5 7-5 14-10 21-15 11-8 21-15 31-23 4-2 7-5 11-7 0-1 1-2 2-2 0 0 0-1 1 0 7 3 14 7 21 11 11 6 23 11 34 17 6 4 12 7 19 10 0 0 0 1 1 1 1 2 2 3 3 5 4 5 8 10 13 15 6 8 12 16 18 24 8 9 15 19 23 28 8 11 16 21 24 31 8 11 16 21 24 31 8 10 15 19 23 28 6 8 12 16 18 24 4 5 8 10 12 15 2 2 3 3 4 5 0 0 0 0 0 0-1 1-2 1-3 1-3 0-6 1-9 2-5 1-10 2-15 3-6 2-13 4-20 5-8 3-16 5-24 7-9 3-19 6-28 9-10 3-21 7-31 11-12 4-23 8-34 13-12 5-24 10-36 15-13 6-26 12-38 18-13 7-26 14-39 21-13 7-27 15-39 23-14 9-27 17-40 27-13 9-26 19-39 29-13 11-25 22-37 33-13 11-25 23-36 36-12 13-23 26-34 40-11 14-21 28-31 43-9 15-19 31-27 47 0 1 0 1 0 1z m-3 3c-1-5-3-9-4-14-3-10-7-21-10-32-4-12-8-25-12-37-3-10-6-20-9-30-1-3-2-6-3-8 0-1 0-2 0-2 1-5 3-10 5-15 3-10 6-20 10-30 4-12 8-24 12-37 4-12 8-24 12-36 3-9 6-18 9-26 1-3 1-5 2-8 0 0 1-1 1-2 2-4 5-8 7-12 5-10 10-19 15-28 6-11 12-23 19-34 6-11 12-22 18-33 4-8 8-15 12-23 1-2 2-4 4-6 4-5 8-9 13-14 7-8 15-16 23-24 9-10 18-20 26-29 9-9 17-18 25-26 5-6 10-11 15-17 2-1 3-3 5-5 5-5 11-11 17-17 9-8 17-17 26-26 9-9 18-18 27-27 7-7 14-14 21-21 2-2 3-3 5-5 0 0 1-1 1-1 0 0 1 0 1 0 11 2 22 3 32 5 9 1 17 2 26 3 0 0 1 1 1 1 1 1 2 3 4 4 4 5 9 10 13 15 7 8 14 15 20 22 9 9 17 18 25 27 9 10 18 20 27 30 8 9 17 19 26 29 8 9 16 17 24 26 7 7 13 15 20 22 4 5 8 9 13 14 1 1 2 2 3 3 0 1 1 1 1 1 0 1-3 1-3 1-3 1-7 2-10 3-4 2-9 3-14 5-6 2-13 4-19 6-8 3-16 6-24 9-9 3-18 7-27 11-10 4-20 8-30 13-11 5-22 10-33 16-12 5-23 11-35 18-12 6-24 13-36 20-12 8-25 16-37 24-13 8-25 17-37 26-13 10-25 19-38 29-12 11-24 21-36 33-12 11-24 23-35 35-11 13-22 25-33 39-10 13-21 27-30 42-10 15-19 30-27 45-9 16-17 32-24 48z m-2 10c-1-4-2-8-3-11-1-10-3-19-5-29-2-12-5-25-7-37-3-13-5-26-8-39-1-10-3-20-5-30-1-5-2-10-3-15 0-1 0-1 0-2 1-3 2-5 3-8 3-9 7-19 10-29 4-12 9-25 13-37 4-11 8-22 11-33 2-5 4-11 6-16 0-1 1-2 1-2 1-3 2-5 4-7 4-9 8-18 13-27 6-12 11-23 17-35 6-11 11-22 17-33 3-7 7-14 11-21 0-2 1-3 1-4 1-1 2-1 2-2 5-6 9-11 14-17 8-9 15-18 22-27 9-10 17-20 26-30 7-9 15-18 22-27 5-6 10-11 15-17 0-1 1-2 2-3 0 0 0 0 0 0 1-1 2-1 3-2 7-4 14-9 21-14 10-7 21-14 31-22 11-7 21-14 31-20 6-4 12-9 18-13 3-2 7-5 10-8 10-8 19-16 29-24 7-5 13-11 20-17 1 0 1 0 1 1 1 1 2 2 3 3 4 4 8 8 12 13 6 6 12 13 18 20 8 8 16 17 23 25 9 10 18 19 26 29 9 9 18 19 27 29 9 9 18 19 26 28 8 9 16 17 23 26 6 6 13 13 19 20 4 4 7 8 11 12 1 2 3 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0-3 1-3 1-3 1-6 2-9 2-5 2-10 4-15 5-6 2-12 5-18 7-8 3-16 6-24 9-8 4-17 8-26 12-10 4-20 9-30 13-11 6-22 11-32 16-12 6-23 13-35 19-12 7-23 14-35 21-13 8-25 16-37 24-12 8-25 17-37 26-12 9-24 19-36 29-13 10-25 21-36 32-12 11-24 22-35 34-12 12-22 25-33 38-11 13-21 26-30 40-10 14-19 29-28 44-9 15-17 30-24 46-4 10-8 20-12 30z m696 21c-2 4-5 7-9 9-5 3-11 5-16 8-11 4-23 9-34 13-23 8-47 14-71 20-24 6-49 12-74 17-25 6-50 10-76 15-25 4-50 8-75 10-13 1-26 1-39 0-6-1-13-2-19-3-6-1-13-2-19-3-26-4-51-9-77-14-25-5-50-10-75-16-25-5-49-12-74-20-12-4-24-9-36-13-6-3-11-5-17-8-3-1-6-2-9-3-3-1-5-2-8-4-4-2-7-5-10-9-1-2-2-4-3-7-1-3-2-6-3-9-4-11-7-24-9-36-5-24-7-49-6-74 0-13 1-25 3-38 1-12 3-25 5-37 5-25 12-50 20-74 4-12 8-24 13-36 4-11 10-22 15-33 10-21 21-42 34-62 12-20 25-39 39-58 14-19 28-37 43-55 16-18 33-36 50-54 17-18 34-35 52-52 18-17 36-33 55-49 10-7 19-15 28-22 10-8 19-15 28-23 2-2 5-4 7-7 0 0 1-1 1-1 0 0 1 0 1 0 0 0 1 0 2 0 4 4 9 8 14 11 9 8 19 15 28 23 18 15 36 31 54 47 18 16 35 32 52 49 17 16 33 34 49 51 16 18 32 37 47 56 14 18 28 38 41 57 13 20 25 40 36 61 11 21 21 43 30 65 9 22 17 45 23 68 6 23 11 47 13 70 3 24 3 49 2 73 0 3-1 6-2 9 0 3-1 6-2 9-1 6-2 12-3 18-3 11-5 22-8 33-4 9-7 19-11 28-2 5 13-29 0 0z m-51-210c-7-25-15-49-26-73-9-22-19-44-30-64-12-21-24-40-37-59-13-19-27-38-42-56-15-18-31-36-47-54-17-18-34-36-52-53-18-17-37-34-56-50-9-7-19-15-28-23-1 0-2-1-2-1-1 0-2 0-2 0-1 0-2 1-2 1 0 0-1 1-1 1-2 1-3 3-4 4-4 3-9 7-14 11-2 1-4 3-7 5-2 2-4 4-6 6-5 4-9 8-14 13-9 8-18 17-27 25-10 9-18 18-27 27-4 4-8 9-13 13-4 4-8 9-12 13-17 17-33 35-49 53-15 18-30 37-44 57-14 20-27 40-38 61-12 21-23 42-32 64-10 22-18 45-25 67-2 6-4 12-5 19-1 6-2 12-3 19-2 13-4 26-4 39-1 13-2 26-1 39 0 12 1 25 3 37 0 4 0 7 1 10 0 1 0 3 0 5 1 1 1 3 1 4 0 3 1 5 2 7 0 2 0 3 0 4 0 1 1 2 2 3 1 0 2 1 3 2 0 0 1 0 1 1 1 0 2 0 3 1 3 1 6 2 9 3 6 2 12 5 18 7 23 8 47 16 72 23 12 3 24 6 37 9 6 1 12 2 18 4 7 1 13 2 19 4 26 5 51 9 77 13 13 1 26 3 39 5 3 0 7 1 10 1 1 1 3 1 4 1 2 0 3 0 4 0 6 0 12 0 17-1 1 0 2-1 4-1 1 0 3-1 4-1 3 0 6-1 9-1 7-1 13-2 19-3 13-2 25-4 38-6 25-4 51-8 76-13 25-6 50-12 75-19 12-4 24-8 37-12 6-2 12-4 18-6 3-1 6-2 9-3 1-1 3-1 4-2 1 0 1 0 2 0 1-1 2-1 2-1 2-2 3-2 4-4 1-1 1-1 1-2 0-1 0-2 0-2 1-1 1-2 1-3 2-6 3-13 4-19 1-7 2-13 3-20 0-3 0-6 0-9 0-1 0-2 0-2 0-1 0-2 0-3 1-1 1-3 1-5 5-23 7-48 5-72-1-13-3-26-6-38-8-29 8 35 0 0z m-197 0c-2 4-3 9-5 13 0 1 0 1 0 2-1 0 0 1-1 1 0 1 0 2 0 2 0 1-1 2-1 3-1 2-3 4-4 5-2 2-5 4-7 4 2 2 4 3 7 5 1 1 2 2 3 2 1 1 2 1 2 2 0 1 0 1 0 2 1 0 1 1 2 1 0 1 1 2 1 4 0 2 0 4 0 6 0 3 0 5 0 7 0 3 0 5-1 7-1 6-4 10-8 14-1 2-3 3-5 4-3 2-5 4-8 5-3 1-6 2-9 3-3 0-5 0-7 0-3 0-6 0-8 0-13 0-25 0-37 0-5 0-10 0-14 0-1 0-2 0-3 0 0 0 0-4 0-5 0-3 0-6 0-9 0-1 0-2 0-3 0-1 0-1 1-1 1 0 12 0 12 0 0-8 0-16 0-24 0-13 0-25 0-38 0-4 0-7 0-11 0 0 0-1 0-1-3 0-5 0-8 0-1 0-2 0-4 0 0 0-1 0-1-1 0-2 0-4 0-6 0-1 0-14 0-14 10 0 19 0 29 0 5 0 11 0 16 0 1 0 3 0 4 0 0 0 0 3 0 3 0 6 0 11 0 17 0 1 0 1-1 1-1 0-2 0-4 0-1 0-3 0-4 0 0 0-1-1-1 0 0 5 0 10 0 15 0 2 0 5 0 8 0 1 0 1 0 2 0 0 0 0 1 0 2 0 5 0 8 0 2 0 4 0 6 0 1 0 3 0 4 0 1 0 2-1 3-2 1-1 2-2 3-3 0-1 0-1 0-2 0-2 1-3 1-4 1-1 1-2 2-3 0-1 0-1 0-1 0-1 0-2 0-2 1-6 2-12 3-17 1-3 1-5 2-8 0 0 0-1 0-1 0 0 0 0 0 0 11 0 21 0 32 0 0 0 1 0 1 0 0 0 0 0 0 0 0 3 0 5 0 8 0 5 0 10 0 15 0 0 0 0 0 0-1-2-1-4-2-5z m-26 53c0-2-3-3-4-4-1 0-1-1-1-1 0 0-1 0-1 0 0 0-1 0-1 0-1-1-1-2-2-2-1 0-2 0-3 0-2 0-4 0-5 0-1 0-2 0-2 0-3 0-7 0-10 0 0 0-4 0-4 0 0 9 0 19 0 28 0 0 13 0 14 0 4 0 8 0 12-1 1 0 3-1 4-2 1 0 2-1 3-2 1-2 2-4 3-6 0-1 0-1 0-2-1-1-1-1-1-2-1-1-1-1-1-2-1-1-1-2-1-4z m131-53c0 9 0 18 0 27 0 9-2 18-8 24-7 7-19 8-28 7-2 0-4 0-6-1-1 0-1-1-2-2-1 0-2 0-2-1-3-1-6-3-8-6 0 9 0 18 0 27 0 6 0 12 0 18 0 2 0 3 0 5 0 1 0 1 0 1-11 0-22 0-32 0-1 0-3 0-4 0 0 0 0-4 0-4 0-5 0-11 0-16 0 0 1 0 1 0 1 0 3 0 4 0 3 0 5 0 8 0 0 0 0-5 0-6 0-11 0-23 0-34 0-11 0-22 0-33 0-1 0-2 0-3 0-1 0-1-1-1-3 0-6 0-9 0-1 0-2 0-3 0 0 0 0-1 0-1 0-6 0-11 0-17 0-1 0-1 0-2 0 0 0 0 0 0 2 0 3 0 4 0 12 0 24 0 36 0 0 0 9 0 9 0 0 5 0 10 0 15 0 1 0 3 0 5 0 0-6 0-7 0 0 0-6 0-6 0 0 1 0 3 0 4 0 6 0 12 0 18 0 3 0 5 0 7 0 1 0 1 0 2 0 0 1 1 2 2 1 1 2 2 3 2 1 1 1 1 2 1 1 0 1 0 1 1 2 1 3 1 4 1 3 1 5 0 7-1 1-1 2-2 3-3 1-1 2-2 2-3 1-2 1-4 1-6 0-3 0-7 0-11 0-11 0-22 0-33 0-1 0-2 1-2 1 0 3 0 5 0 6 0 12 0 19 0 3 0 7 0 11 0 0 0 0 14 0 15 0 2 0 4 0 6-2-1-5-2-7-2z m7 122c-2 0-5 0-7 0-1 0-2 0-3 0 0 0 0 0 0 0-3-5-7-10-10-14-1-2-3-5-4-7 0 0-1-1-1-2 0 0 0-1 0-1 0-1 0-4 0-4 0 0 1 0 2 0 3 0 5 0 8 0 3 0 5 0 8 0 0 0 0-1 0-1 0-1 0-3 0-4 0-2 0-3 0-4 0-1 0-1 1-1 1 0 3 0 4 0 1 0 2 0 2 0 0 3 0 6 0 8 0 1 0 2 1 2 1 0 2 0 4 0 0 0 0 0 0 0 0 1 0 1 0 2 0 0 0 3 0 3-1 0-2 0-3 0-1 0-2 0-2 1 0 7 0 15 0 22z m-7-15c0-1 0-2 0-4 0-1 0-1 0-2 0 0 0-1 0-2 0 0-1 0-1 0-1 0-2 0-3 0-1 0-3 0-4 0 1 2 3 4 4 6 1 1 1 2 2 3 1 2 2 4 2 7 0-3 0-5 0-8z m41-2c-3 2-8 2-11 2-1 0-2 0-2 0 0 0 0 1 0 1 0 2 0 3 0 4 0 0 13 0 14 0 1 0 1 0 1 1 0 1 0 2 0 4 0 1 0 2 0 3 0 0-1 0-1 0-6 0-11 0-17 0-1 0-1 0-2 0 0 0 0-1 0-1-1-2-1-4-1-6-1-5-1-9-2-14 4 0 9 1 12-1 3-1 4-4 4-7-1-4-5-4-7-4-2 0-9-1-9 2-1-2-1-5-2-8 1 0 3-1 5-1 2-1 5-1 7-1 4 0 8 2 11 5 2 3 2 7 2 11 0 2 0 5 0 7 0 1-1 2-2 3 0 0 0 0 0 0-3 2 2 0 0 0z" horiz-adv-x="1000" />
92
93 <glyph glyph-name="up" unicode="&#xe832;" d="M687 254l-173 217c-8 9-22 9-29 0l-173-217c-9-12-1-29 15-29h345c16 0 24 17 15 29z" horiz-adv-x="1000" />
56
94
57 <glyph glyph-name="plus" unicode="&#xe81d;" d="M917 291v116c0 14-12 24-24 24h-283c-15 0-24 12-24 24v288c0 14-12 24-24 24h-117c-14 0-24-12-24-24v-283c0-15-11-24-23-24h-291c-14 0-24-12-24-24v-117c0-14 12-23 24-23h283c15 0 24-12 24-24v-284c0-14 12-23 24-23h117c14 0 24 11 24 23v279c0 14 11 24 23 24h284c19 0 31 12 31 24z" horiz-adv-x="1000" />
95 <glyph glyph-name="merge" unicode="&#xe833;" d="M200 110c0-72 58-131 130-131s130 59 130 131c0 45-24 86-60 109 18 139 133 179 202 190v-301c-38-23-65-64-65-112 0-72 59-130 130-130s130 58 130 130c0 48-26 89-65 112v487c39 23 65 64 65 112 0 72-58 130-130 130s-130-58-130-130c0-48 27-89 65-112v-55c-60-8-162-32-238-108-54-54-86-124-94-208-42-22-70-65-70-114z m468-158c-24 0-44 20-44 43s20 44 44 44c24 0 43-20 43-44s-19-43-43-43z m0 798c24 0 43-19 43-43s-20-43-43-43c-24 0-44 19-44 43s20 43 44 43z m-338-684c-24 0-43 20-43 43s19 44 43 44c24 0 43-20 43-44s-19-43-43-43z" horiz-adv-x="1000" />
58
96
59 <glyph glyph-name="remove" unicode="&#xe81e;" d="M836 602l-84 84c-9 9-26 9-35 0l-200-200c-10-10-26-10-36 0l-200 200c-9 9-26 9-36 0l-83-84c-9-9-9-26 0-35l200-200c10-10 10-26 0-36l-200-200c-9-9-9-26 0-36l83-83c10-9 27-9 36 0l200 200c10 10 26 10 36 0l200-200c9-9 26-9 35 0l84 83c9 10 9 27 0 36l-200 200c-10 10-10 26 0 36l200 200c9 12 9 26 0 35z" horiz-adv-x="1000" />
97 <glyph glyph-name="spin-alt" unicode="&#xe834;" d="M498 850c-114 0-228-39-320-116l0 0c173 140 428 130 588-31 134-134 164-332 89-495-10-29-5-50 12-68 21-20 61-23 84 0 3 3 12 15 15 24 71 180 33 393-112 539-99 98-228 147-356 147z m-409-274c-14 0-29-5-39-16-3-3-13-15-15-24-71-180-34-393 112-539 185-185 479-195 676-31l0 0c-173-140-428-130-589 31-134 134-163 333-89 495 11 29 6 50-12 68-11 11-27 17-44 16z" horiz-adv-x="1001" />
98
99 <glyph glyph-name="spin" unicode="&#xe838;" d="M462 850c-6 0-11-5-11-11l0-183 0 0c0-6 5-11 11-11l69 0c1 0 1 0 1 0 7 0 12 5 12 11l0 183 0 0c0 6-5 11-12 11l-69 0c0 0 0 0-1 0z m250-47c-4 1-8-2-10-5l-91-158 0 0c-4-6-2-13 4-16l60-34c0-1 0-1 0-1 6-3 13-1 16 4l91 158c3 6 2 13-4 16l-61 35c-1 1-3 1-5 1z m-428-2c-2 0-4-1-6-2l-61-35c-5-3-7-10-4-16l91-157c0 0 0 0 0 0 3-6 10-8 16-5l61 35c5 4 7 11 4 16l-91 157c0 1 0 1 0 1-2 4-6 6-10 6z m620-163c-2 0-4 0-6-1l-157-91c0 0 0 0 0 0-6-3-8-10-5-16l35-61c4-5 11-7 16-4l157 91c1 0 1 0 1 0 6 3 7 11 4 16l-35 61c-2 4-6 6-10 5z m-810-4c-5 0-9-2-11-6l-35-61c-3-5-1-12 4-15l158-91 0 0c6-4 13-2 16 4l35 60c0 0 0 0 0 0 3 6 1 13-4 16l-158 91c-2 1-4 2-5 2z m712-235l0 0c-6 0-11-5-11-11l0-69c0-1 0-1 0-1 0-7 5-12 11-12l183 0 0 0c6 0 11 5 11 12l0 69c0 0 0 0 0 1 0 6-5 11-11 11l-183 0z m-794-5l0 0c-7 0-12-5-12-12l0-69c0 0 0 0 0-1 0-6 5-11 12-11l182 0 0 0c6 0 11 5 11 11l0 69c0 1 0 1 0 1 0 7-5 12-11 12l-182 0z m772-153c-4 0-8-2-10-6l-34-60c-1 0-1 0-1 0-3-6-1-13 4-16l158-91c6-3 13-1 16 4l35 61c3 5 1 12-4 15l-158 92 0 0c-2 1-4 1-6 1z m-566-5c-1 0-3 0-5-1l-157-91c0 0-1 0-1 0-5-3-7-10-4-16l35-61c3-5 10-7 16-4l157 91c0 0 0 0 0 0 6 3 8 10 5 16l-35 61c-3 3-7 6-11 5z m468-121c-2 0-4 0-6-1l-61-35c-5-4-7-11-4-16l91-157c0-1 0-1 0-1 3-6 11-7 16-4l61 35c5 3 7 10 4 16l-91 157c0 0 0 0 0 0-2 4-6 6-10 6z m-367-2c-4 0-8-2-10-6l-91-158c-3-6-1-13 4-16l61-35c5-3 12-1 15 4l92 158 0 0c3 6 1 13-5 16l-60 35c0 0 0 0 0 0-2 1-4 1-6 2z m149-58c-7 0-12-5-12-11l0-183 0 0c0-6 5-11 12-11l69 0c0 0 0 0 1 0 6 0 11 5 11 11l0 183 0 0c0 6-5 11-11 11l-69 0c-1 0-1 0-1 0z" horiz-adv-x="1000" />
60
100
61 <glyph glyph-name="rhodecode" unicode="&#xe81f;" d="M175 633c-2-4-3-8-4-12-3-10-6-20-9-30-3-13-7-25-11-38-3-11-6-23-10-35-2-7-4-15-6-22-1-1-1-2-1-4 0 0 0 0 0 0 0-1 1-2 1-2 2-7 5-14 7-21 4-11 8-22 12-33 4-12 9-25 13-37 4-11 8-23 12-34 3-7 5-14 7-21 1-1 1-2 2-3 0-1 1-1 1-2 4-6 8-12 11-17 7-10 13-19 19-29 7-11 14-22 22-33 6-10 13-21 20-31 5-7 9-15 14-22 1-2 3-4 4-5 0-1 1-1 1-2 3-3 6-5 8-8 7-6 13-12 19-19 9-8 17-16 25-24 10-10 19-19 29-28 9-9 18-18 27-27 8-8 16-15 23-23 5-5 11-10 16-15 1-1 3-3 5-5 7-5 14-10 21-15 11-8 21-15 31-23 4-2 7-5 11-7 0-1 1-2 2-2 0 0 0-1 1 0 7 3 14 7 21 11 11 6 23 11 34 17 6 4 12 7 19 10 0 0 0 1 1 1 1 2 2 3 3 5 4 5 8 10 13 15 6 8 12 16 18 24 8 9 15 19 23 28 8 11 16 21 24 31 8 11 16 21 24 31 8 10 15 19 23 28 6 8 12 16 18 24 4 5 8 10 12 15 2 2 3 3 4 5 0 0 0 0 0 0-1 1-2 1-3 1-3 0-6 1-9 2-5 1-10 2-15 3-6 2-13 4-20 5-8 3-16 5-24 7-9 3-19 6-28 9-10 3-21 7-31 11-12 4-23 8-34 13-12 5-24 10-36 15-13 6-26 12-38 18-13 7-26 14-39 21-13 7-27 15-39 23-14 9-27 17-40 27-13 9-26 19-39 29-13 11-25 22-37 33-13 11-25 23-36 36-12 13-23 26-34 40-11 14-21 28-31 43-9 15-19 31-27 47 0 1 0 1 0 1z m-3 3c-1-5-3-9-4-14-3-10-7-21-10-32-4-12-8-25-12-37-3-10-6-20-9-30-1-3-2-6-3-8 0-1 0-2 0-2 1-5 3-10 5-15 3-10 6-20 10-30 4-12 8-24 12-37 4-12 8-24 12-36 3-9 6-18 9-26 1-3 1-5 2-8 0 0 1-1 1-2 2-4 5-8 7-12 5-10 10-19 15-28 6-11 12-23 19-34 6-11 12-22 18-33 4-8 8-15 12-23 1-2 2-4 4-6 4-5 8-9 13-14 7-8 15-16 23-24 9-10 18-20 26-29 9-9 17-18 25-26 5-6 10-11 15-17 2-1 3-3 5-5 5-5 11-11 17-17 9-8 17-17 26-26 9-9 18-18 27-27 7-7 14-14 21-21 2-2 3-3 5-5 0 0 1-1 1-1 0 0 1 0 1 0 11 2 22 3 32 5 9 1 17 2 26 3 0 0 1 1 1 1 1 1 2 3 4 4 4 5 9 10 13 15 7 8 14 15 20 22 9 9 17 18 25 27 9 10 18 20 27 30 8 9 17 19 26 29 8 9 16 17 24 26 7 7 13 15 20 22 4 5 8 9 13 14 1 1 2 2 3 3 0 1 1 1 1 1 0 1-3 1-3 1-3 1-7 2-10 3-4 2-9 3-14 5-6 2-13 4-19 6-8 3-16 6-24 9-9 3-18 7-27 11-10 4-20 8-30 13-11 5-22 10-33 16-12 5-23 11-35 18-12 6-24 13-36 20-12 8-25 16-37 24-13 8-25 17-37 26-13 10-25 19-38 29-12 11-24 21-36 33-12 11-24 23-35 35-11 13-22 25-33 39-10 13-21 27-30 42-10 15-19 30-27 45-9 16-17 32-24 48z m-2 10c-1-4-2-8-3-11-1-10-3-19-5-29-2-12-5-25-7-37-3-13-5-26-8-39-1-10-3-20-5-30-1-5-2-10-3-15 0-1 0-1 0-2 1-3 2-5 3-8 3-9 7-19 10-29 4-12 9-25 13-37 4-11 8-22 11-33 2-5 4-11 6-16 0-1 1-2 1-2 1-3 2-5 4-7 4-9 8-18 13-27 6-12 11-23 17-35 6-11 11-22 17-33 3-7 7-14 11-21 0-2 1-3 1-4 1-1 2-1 2-2 5-6 9-11 14-17 8-9 15-18 22-27 9-10 17-20 26-30 7-9 15-18 22-27 5-6 10-11 15-17 0-1 1-2 2-3 0 0 0 0 0 0 1-1 2-1 3-2 7-4 14-9 21-14 10-7 21-14 31-22 11-7 21-14 31-20 6-4 12-9 18-13 3-2 7-5 10-8 10-8 19-16 29-24 7-5 13-11 20-17 1 0 1 0 1 1 1 1 2 2 3 3 4 4 8 8 12 13 6 6 12 13 18 20 8 8 16 17 23 25 9 10 18 19 26 29 9 9 18 19 27 29 9 9 18 19 26 28 8 9 16 17 23 26 6 6 13 13 19 20 4 4 7 8 11 12 1 2 3 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0-3 1-3 1-3 1-6 2-9 2-5 2-10 4-15 5-6 2-12 5-18 7-8 3-16 6-24 9-8 4-17 8-26 12-10 4-20 9-30 13-11 6-22 11-32 16-12 6-23 13-35 19-12 7-23 14-35 21-13 8-25 16-37 24-12 8-25 17-37 26-12 9-24 19-36 29-13 10-25 21-36 32-12 11-24 22-35 34-12 12-22 25-33 38-11 13-21 26-30 40-10 14-19 29-28 44-9 15-17 30-24 46-4 10-8 20-12 30z m696 21c-2 4-5 7-9 9-5 3-11 5-16 8-11 4-23 9-34 13-23 8-47 14-71 20-24 6-49 12-74 17-25 6-50 10-76 15-25 4-50 8-75 10-13 1-26 1-39 0-6-1-13-2-19-3-6-1-13-2-19-3-26-4-51-9-77-14-25-5-50-10-75-16-25-5-49-12-74-20-12-4-24-9-36-13-6-3-11-5-17-8-3-1-6-2-9-3-3-1-5-2-8-4-4-2-7-5-10-9-1-2-2-4-3-7-1-3-2-6-3-9-4-11-7-24-9-36-5-24-7-49-6-74 0-13 1-25 3-38 1-12 3-25 5-37 5-25 12-50 20-74 4-12 8-24 13-36 4-11 10-22 15-33 10-21 21-42 34-62 12-20 25-39 39-58 14-19 28-37 43-55 16-18 33-36 50-54 17-18 34-35 52-52 18-17 36-33 55-49 10-7 19-15 28-22 10-8 19-15 28-23 2-2 5-4 7-7 0 0 1-1 1-1 0 0 1 0 1 0 0 0 1 0 2 0 4 4 9 8 14 11 9 8 19 15 28 23 18 15 36 31 54 47 18 16 35 32 52 49 17 16 33 34 49 51 16 18 32 37 47 56 14 18 28 38 41 57 13 20 25 40 36 61 11 21 21 43 30 65 9 22 17 45 23 68 6 23 11 47 13 70 3 24 3 49 2 73 0 3-1 6-2 9 0 3-1 6-2 9-1 6-2 12-3 18-3 11-5 22-8 33-4 9-7 19-11 28-2 5 13-29 0 0z m-51-210c-7-25-15-49-26-73-9-22-19-44-30-64-12-21-24-40-37-59-13-19-27-38-42-56-15-18-31-36-47-54-17-18-34-36-52-53-18-17-37-34-56-50-9-7-19-15-28-23-1 0-2-1-2-1-1 0-2 0-2 0-1 0-2 1-2 1 0 0-1 1-1 1-2 1-3 3-4 4-4 3-9 7-14 11-2 1-4 3-7 5-2 2-4 4-6 6-5 4-9 8-14 13-9 8-18 17-27 25-10 9-18 18-27 27-4 4-8 9-13 13-4 4-8 9-12 13-17 17-33 35-49 53-15 18-30 37-44 57-14 20-27 40-38 61-12 21-23 42-32 64-10 22-18 45-25 67-2 6-4 12-5 19-1 6-2 12-3 19-2 13-4 26-4 39-1 13-2 26-1 39 0 12 1 25 3 37 0 4 0 7 1 10 0 1 0 3 0 5 1 1 1 3 1 4 0 3 1 5 2 7 0 2 0 3 0 4 0 1 1 2 2 3 1 0 2 1 3 2 0 0 1 0 1 1 1 0 2 0 3 1 3 1 6 2 9 3 6 2 12 5 18 7 23 8 47 16 72 23 12 3 24 6 37 9 6 1 12 2 18 4 7 1 13 2 19 4 26 5 51 9 77 13 13 1 26 3 39 5 3 0 7 1 10 1 1 1 3 1 4 1 2 0 3 0 4 0 6 0 12 0 17-1 1 0 2-1 4-1 1 0 3-1 4-1 3 0 6-1 9-1 7-1 13-2 19-3 13-2 25-4 38-6 25-4 51-8 76-13 25-6 50-12 75-19 12-4 24-8 37-12 6-2 12-4 18-6 3-1 6-2 9-3 1-1 3-1 4-2 1 0 1 0 2 0 1-1 2-1 2-1 2-2 3-2 4-4 1-1 1-1 1-2 0-1 0-2 0-2 1-1 1-2 1-3 2-6 3-13 4-19 1-7 2-13 3-20 0-3 0-6 0-9 0-1 0-2 0-2 0-1 0-2 0-3 1-1 1-3 1-5 5-23 7-48 5-72-1-13-3-26-6-38-8-29 8 35 0 0z m-197 0c-2 4-3 9-5 13 0 1 0 1 0 2-1 0 0 1-1 1 0 1 0 2 0 2 0 1-1 2-1 3-1 2-3 4-4 5-2 2-5 4-7 4 2 2 4 3 7 5 1 1 2 2 3 2 1 1 2 1 2 2 0 1 0 1 0 2 1 0 1 1 2 1 0 1 1 2 1 4 0 2 0 4 0 6 0 3 0 5 0 7 0 3 0 5-1 7-1 6-4 10-8 14-1 2-3 3-5 4-3 2-5 4-8 5-3 1-6 2-9 3-3 0-5 0-7 0-3 0-6 0-8 0-13 0-25 0-37 0-5 0-10 0-14 0-1 0-2 0-3 0 0 0 0-4 0-5 0-3 0-6 0-9 0-1 0-2 0-3 0-1 0-1 1-1 1 0 12 0 12 0 0-8 0-16 0-24 0-13 0-25 0-38 0-4 0-7 0-11 0 0 0-1 0-1-3 0-5 0-8 0-1 0-2 0-4 0 0 0-1 0-1-1 0-2 0-4 0-6 0-1 0-14 0-14 10 0 19 0 29 0 5 0 11 0 16 0 1 0 3 0 4 0 0 0 0 3 0 3 0 6 0 11 0 17 0 1 0 1-1 1-1 0-2 0-4 0-1 0-3 0-4 0 0 0-1-1-1 0 0 5 0 10 0 15 0 2 0 5 0 8 0 1 0 1 0 2 0 0 0 0 1 0 2 0 5 0 8 0 2 0 4 0 6 0 1 0 3 0 4 0 1 0 2-1 3-2 1-1 2-2 3-3 0-1 0-1 0-2 0-2 1-3 1-4 1-1 1-2 2-3 0-1 0-1 0-1 0-1 0-2 0-2 1-6 2-12 3-17 1-3 1-5 2-8 0 0 0-1 0-1 0 0 0 0 0 0 11 0 21 0 32 0 0 0 1 0 1 0 0 0 0 0 0 0 0 3 0 5 0 8 0 5 0 10 0 15 0 0 0 0 0 0-1-2-1-4-2-5z m-26 53c0-2-3-3-4-4-1 0-1-1-1-1 0 0-1 0-1 0 0 0-1 0-1 0-1-1-1-2-2-2-1 0-2 0-3 0-2 0-4 0-5 0-1 0-2 0-2 0-3 0-7 0-10 0 0 0-4 0-4 0 0 9 0 19 0 28 0 0 13 0 14 0 4 0 8 0 12-1 1 0 3-1 4-2 1 0 2-1 3-2 1-2 2-4 3-6 0-1 0-1 0-2-1-1-1-1-1-2-1-1-1-1-1-2-1-1-1-2-1-4z m131-53c0 9 0 18 0 27 0 9-2 18-8 24-7 7-19 8-28 7-2 0-4 0-6-1-1 0-1-1-2-2-1 0-2 0-2-1-3-1-6-3-8-6 0 9 0 18 0 27 0 6 0 12 0 18 0 2 0 3 0 5 0 1 0 1 0 1-11 0-22 0-32 0-1 0-3 0-4 0 0 0 0-4 0-4 0-5 0-11 0-16 0 0 1 0 1 0 1 0 3 0 4 0 3 0 5 0 8 0 0 0 0-5 0-6 0-11 0-23 0-34 0-11 0-22 0-33 0-1 0-2 0-3 0-1 0-1-1-1-3 0-6 0-9 0-1 0-2 0-3 0 0 0 0-1 0-1 0-6 0-11 0-17 0-1 0-1 0-2 0 0 0 0 0 0 2 0 3 0 4 0 12 0 24 0 36 0 0 0 9 0 9 0 0 5 0 10 0 15 0 1 0 3 0 5 0 0-6 0-7 0 0 0-6 0-6 0 0 1 0 3 0 4 0 6 0 12 0 18 0 3 0 5 0 7 0 1 0 1 0 2 0 0 1 1 2 2 1 1 2 2 3 2 1 1 1 1 2 1 1 0 1 0 1 1 2 1 3 1 4 1 3 1 5 0 7-1 1-1 2-2 3-3 1-1 2-2 2-3 1-2 1-4 1-6 0-3 0-7 0-11 0-11 0-22 0-33 0-1 0-2 1-2 1 0 3 0 5 0 6 0 12 0 19 0 3 0 7 0 11 0 0 0 0 14 0 15 0 2 0 4 0 6-2-1-5-2-7-2z m7 122c-2 0-5 0-7 0-1 0-2 0-3 0 0 0 0 0 0 0-3-5-7-10-10-14-1-2-3-5-4-7 0 0-1-1-1-2 0 0 0-1 0-1 0-1 0-4 0-4 0 0 1 0 2 0 3 0 5 0 8 0 3 0 5 0 8 0 0 0 0-1 0-1 0-1 0-3 0-4 0-2 0-3 0-4 0-1 0-1 1-1 1 0 3 0 4 0 1 0 2 0 2 0 0 3 0 6 0 8 0 1 0 2 1 2 1 0 2 0 4 0 0 0 0 0 0 0 0 1 0 1 0 2 0 0 0 3 0 3-1 0-2 0-3 0-1 0-2 0-2 1 0 7 0 15 0 22z m-7-15c0-1 0-2 0-4 0-1 0-1 0-2 0 0 0-1 0-2 0 0-1 0-1 0-1 0-2 0-3 0-1 0-3 0-4 0 1 2 3 4 4 6 1 1 1 2 2 3 1 2 2 4 2 7 0-3 0-5 0-8z m41-2c-3 2-8 2-11 2-1 0-2 0-2 0 0 0 0 1 0 1 0 2 0 3 0 4 0 0 13 0 14 0 1 0 1 0 1 1 0 1 0 2 0 4 0 1 0 2 0 3 0 0-1 0-1 0-6 0-11 0-17 0-1 0-1 0-2 0 0 0 0-1 0-1-1-2-1-4-1-6-1-5-1-9-2-14 4 0 9 1 12-1 3-1 4-4 4-7-1-4-5-4-7-4-2 0-9-1-9 2-1-2-1-5-2-8 1 0 3-1 5-1 2-1 5-1 7-1 4 0 8 2 11 5 2 3 2 7 2 11 0 2 0 5 0 7 0 1-1 2-2 3 0 0 0 0 0 0-3 2 2 0 0 0z" horiz-adv-x="1000" />
101 <glyph glyph-name="docs" unicode="&#xf0c5;" 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-37t-38-16h-233v-357h286v143q0 22 11 49t27 42z m534-449v643h-215v-232q0-22-15-38t-38-15h-232v-358h500z" horiz-adv-x="1000" />
102
103 <glyph glyph-name="menu" unicode="&#xf0c9;" d="M857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-14-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
62
104
63 <glyph glyph-name="svn-inv" unicode="&#xe820;" d="M933 841h-852c-36 0-65-29-65-65v-853c0-36 29-65 65-65h852c36 0 66 29 66 65v853c0 36-30 65-66 65z m-765-438c3-4 7-7 13-10 5-3 11-6 18-8 7-3 14-5 21-8 7-3 14-6 21-10 7-4 13-9 18-14 5-6 10-13 13-20 3-8 5-18 5-29 0-16-3-30-8-44-6-14-14-26-24-37-10-10-22-18-37-24-15-7-31-10-49-10-9 0-18 1-27 3s-18 5-27 9c-8 4-16 8-23 13-7 5-13 10-18 17l25 32c2 3 4 5 7 6 3 2 6 3 9 3 4 0 8-2 12-4 3-3 8-6 12-10 5-3 10-6 16-9 6-3 14-4 23-4 13 0 23 3 30 10 7 7 10 18 10 32 0 6-1 12-4 16-4 4-8 7-13 10-5 3-11 6-18 8-7 2-14 5-21 7-7 3-14 6-21 9-6 4-12 8-18 14-5 6-9 13-12 21-3 8-5 18-5 30 0 14 3 28 8 40 5 13 12 25 22 35 10 9 22 17 36 23 14 6 29 9 47 9 9 0 17-1 26-3s16-4 23-8c7-3 14-7 20-11 6-5 11-10 15-15l-21-29c-2-3-5-6-7-7-3-2-6-3-9-3-3 0-7 1-10 3-3 3-7 5-11 8-4 2-9 4-14 7-5 2-12 3-19 3-6 0-12-1-17-3-5-2-9-4-12-8-4-3-6-7-8-11-1-5-2-10-2-15 0-5 2-10 5-14z m312-210h-64l-77 313h57c6 0 10-1 14-4 4-3 6-6 7-11l32-173c2-7 4-14 6-23 1-8 3-17 4-26 3 9 6 18 9 26 4 9 7 16 11 23l73 173c1 2 2 4 4 6 2 2 4 3 6 5 2 1 4 2 7 3 3 1 5 1 8 1h57l-154-313z m423 0h-37c-5 0-10 1-13 2-4 2-7 5-10 9l-109 194c-1-4-1-8-1-12-1-4-1-7-1-10l-22-183h-62l39 313h37c3 0 6 0 8 0 2 0 4-1 5-1 2-1 3-2 4-4s3-3 5-5l110-194c0 5 0 10 1 14 0 5 1 9 1 13l21 177h62l-38-313z" horiz-adv-x="1000" />
105 <glyph glyph-name="paste" unicode="&#xf0ea;" d="M429-79h500v358h-233q-22 0-37 15t-16 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-15 27-42t11-49z" horiz-adv-x="1000" />
106
107 <glyph glyph-name="doc-text" unicode="&#xf0f6;" 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 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-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" />
64
108
65 <glyph glyph-name="tag" unicode="&#xe821;" d="M450 791l-371 11c-17 0-31-14-31-31l12-369c0-7 2-16 9-21l471-471c12-12 31-12 46 0l359 359c12 12 12 31 0 45l-474 467c-7 7-14 10-21 10z m-86-222c0-45-38-83-83-83s-83 38-83 83 38 83 83 83 83-38 83-83z" horiz-adv-x="1000" />
109 <glyph glyph-name="plus-squared" unicode="&#xf0fe;" d="M714 314v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-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" />
110
111 <glyph glyph-name="folder-empty" unicode="&#xf114;" 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" />
66
112
67 <glyph glyph-name="copy" unicode="&#xf0c5;" 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-37t-38-16h-233v-357h286v143q0 22 11 49t27 42z m534-449v643h-215v-232q0-22-15-38t-38-15h-232v-358h500z" horiz-adv-x="1000" />
113 <glyph glyph-name="folder-open-empty" unicode="&#xf115;" d="M994 331q0 19-30 19h-607q-22 0-48-12t-39-29l-164-203q-11-13-11-22 0-20 30-20h607q23 0 48 13t40 29l164 203q10 12 10 22z m-637 90h429v90q0 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-90q0-35-25-67l-165-203q-24-30-65-49t-78-19h-607q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q52 0 88-37t37-88v-90h107q30 0 56-13t37-40q8-17 8-37z" horiz-adv-x="1071.4" />
114
115 <glyph glyph-name="minus-squared" unicode="&#xf146;" d="M714 314v72q0 14-10 25t-25 10h-500q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h500q14 0 25 10t10 25z m143 304v-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" />
68
116
69 <glyph glyph-name="file-text" unicode="&#xf0f6;" 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 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-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" />
117 <glyph glyph-name="minus-squared-alt" unicode="&#xf147;" d="M643 404v-36q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v36q0 7 5 12t13 5h464q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" />
118
119 <glyph glyph-name="doc-inv" unicode="&#xf15b;" d="M571 564v264q13-8 21-16l227-228q8-7 16-20h-264z m-71-18q0-22 16-37t38-16h303v-589q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h446v-304z" horiz-adv-x="857.1" />
70
120
71 <glyph glyph-name="directory-empty" unicode="&#xf114;" 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" />
121 <glyph glyph-name="doc-text-inv" unicode="&#xf15c;" 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-37t38-16z 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 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" horiz-adv-x="857.1" />
72
122
73 <glyph glyph-name="file-text-inv" unicode="&#xf15c;" 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-37t38-16z 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 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" horiz-adv-x="857.1" />
123 <glyph glyph-name="plus-squared-alt" unicode="&#xf196;" d="M643 404v-36q0-8-5-13t-13-5h-196v-196q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v196h-196q-8 0-13 5t-5 13v36q0 7 5 12t13 5h196v197q0 8 5 13t13 5h36q8 0 13-5t5-13v-197h196q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" />
74
124
75 <glyph glyph-name="file-code" unicode="&#xf1c9;" 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 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z m-518 500q4 7 12 7t13-3l28-21q7-5 7-12t-3-13l-102-136 102-136q4-6 3-13t-7-12l-28-21q-6-4-13-4t-12 7l-126 168q-8 11 0 22z m447-167q8-11 0-22l-126-168q-4-6-11-7t-14 4l-28 21q-6 5-7 12t3 13l102 136-102 136q-4 6-3 13t7 12l28 21q6 4 14 3t11-7z m-346-258q-7 1-11 8t-3 13l77 464q1 7 7 11t14 3l35-5q7-2 11-8t3-13l-77-464q-1-7-7-11t-13-3z" horiz-adv-x="857.1" />
125 <glyph glyph-name="file-code" unicode="&#xf1c9;" 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 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z m-518 500q4 7 12 7t13-3l28-21q7-5 7-12t-3-13l-102-136 102-136q4-6 3-13t-7-12l-28-21q-6-4-13-4t-12 7l-126 168q-8 11 0 22z m447-167q8-11 0-22l-126-168q-4-6-11-7t-14 4l-28 21q-6 5-7 12t3 13l102 136-102 136q-4 6-3 13t7 12l28 21q6 4 14 3t11-7z m-346-258q-7 1-11 8t-3 13l77 464q1 7 7 11t14 3l35-5q7-2 11-8t3-13l-77-464q-1-7-7-11t-13-3z" horiz-adv-x="857.1" />
126
127 <glyph glyph-name="history" unicode="&#xf1da;" d="M857 350q0-87-34-166t-91-137-137-92-166-34q-96 0-183 41t-147 114q-4 6-4 13t5 11l76 77q6 5 14 5 9-1 13-7 41-53 100-82t126-29q58 0 110 23t92 61 61 91 22 111-22 111-61 91-92 61-110 23q-55 0-105-20t-90-57l77-77q17-16 8-38-10-23-33-23h-250q-15 0-25 11t-11 25v250q0 24 22 33 22 10 39-8l72-72q60 57 137 88t159 31q87 0 166-34t137-92 91-137 34-166z m-357 161v-250q0-8-5-13t-13-5h-178q-8 0-13 5t-5 13v35q0 8 5 13t13 5h125v197q0 8 5 13t12 5h36q8 0 13-5t5-13z" horiz-adv-x="857.1" />
128
129 <glyph glyph-name="sliders" unicode="&#xf1de;" 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-25t-26-11h-142q-15 0-25 11t-11 25v142q0 15 11 26t25 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" />
130
131 <glyph glyph-name="trash" unicode="&#xf1f8;" d="M286 82v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m143 0v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m142 0v393q0 8-5 13t-12 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q7 0 12 5t5 13z m-303 554h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q23 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
76 </font>
132 </font>
77 </defs>
133 </defs>
78 </svg> No newline at end of file
134 </svg>
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: file renamed from rhodecode/public/images/rhodecode-logo-white-216x60.png to rhodecode/public/images/rhodecode-logo-white-60x60.png, binary diff hidden
NO CONTENT: file renamed from rhodecode/public/images/rhodecode-logo-white-216x60.png to rhodecode/public/images/rhodecode-logo-white-60x60.png, binary diff hidden
@@ -98,7 +98,7 b' function setRCMouseBindings(repoName, re'
98 });
98 });
99 Mousetrap.bind(['g c'], function(e) {
99 Mousetrap.bind(['g c'], function(e) {
100 window.location = pyroutes.url(
100 window.location = pyroutes.url(
101 'repo_changelog', {'repo_name': repoName});
101 'repo_commits', {'repo_name': repoName});
102 });
102 });
103 Mousetrap.bind(['g F'], function(e) {
103 Mousetrap.bind(['g F'], function(e) {
104 window.location = pyroutes.url(
104 window.location = pyroutes.url(
@@ -131,6 +131,7 b' function registerRCRoutes() {'
131 pyroutes.register('repo_new', '/_admin/repos/new', []);
131 pyroutes.register('repo_new', '/_admin/repos/new', []);
132 pyroutes.register('repo_create', '/_admin/repos/create', []);
132 pyroutes.register('repo_create', '/_admin/repos/create', []);
133 pyroutes.register('repo_groups', '/_admin/repo_groups', []);
133 pyroutes.register('repo_groups', '/_admin/repo_groups', []);
134 pyroutes.register('repo_groups_data', '/_admin/repo_groups_data', []);
134 pyroutes.register('repo_group_new', '/_admin/repo_group/new', []);
135 pyroutes.register('repo_group_new', '/_admin/repo_group/new', []);
135 pyroutes.register('repo_group_create', '/_admin/repo_group/create', []);
136 pyroutes.register('repo_group_create', '/_admin/repo_group/create', []);
136 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
137 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
@@ -148,6 +149,7 b' function registerRCRoutes() {'
148 pyroutes.register('repo_group_list_data', '/_repo_groups', []);
149 pyroutes.register('repo_group_list_data', '/_repo_groups', []);
149 pyroutes.register('goto_switcher_data', '/_goto_data', []);
150 pyroutes.register('goto_switcher_data', '/_goto_data', []);
150 pyroutes.register('markup_preview', '/_markup_preview', []);
151 pyroutes.register('markup_preview', '/_markup_preview', []);
152 pyroutes.register('file_preview', '/_file_preview', []);
151 pyroutes.register('store_user_session_value', '/_store_session_attr', []);
153 pyroutes.register('store_user_session_value', '/_store_session_attr', []);
152 pyroutes.register('journal', '/_admin/journal', []);
154 pyroutes.register('journal', '/_admin/journal', []);
153 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
155 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
@@ -195,14 +197,17 b' function registerRCRoutes() {'
195 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
197 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
196 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
198 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
197 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
199 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
200 pyroutes.register('repo_files_upload_file', '/%(repo_name)s/upload_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
198 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
201 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
199 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
202 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
200 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
203 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
201 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
204 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
205 pyroutes.register('repo_commits', '/%(repo_name)s/commits', ['repo_name']);
206 pyroutes.register('repo_commits_file', '/%(repo_name)s/commits/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
207 pyroutes.register('repo_commits_elements', '/%(repo_name)s/commits_elements', ['repo_name']);
208 pyroutes.register('repo_commits_elements_file', '/%(repo_name)s/commits_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
202 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
209 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
203 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
210 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
204 pyroutes.register('repo_changelog_elements', '/%(repo_name)s/changelog_elements', ['repo_name']);
205 pyroutes.register('repo_changelog_elements_file', '/%(repo_name)s/changelog_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
206 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
211 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
207 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
212 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
208 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
213 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
@@ -356,6 +361,12 b' function registerRCRoutes() {'
356 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
361 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
357 pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
362 pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
358 pyroutes.register('my_account_external_identity_delete', '/_admin/my_account/external-identity/delete', []);
363 pyroutes.register('my_account_external_identity_delete', '/_admin/my_account/external-identity/delete', []);
364 pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']);
365 pyroutes.register('repo_artifacts_data', '/%(repo_name)s/artifacts_data', ['repo_name']);
366 pyroutes.register('repo_artifacts_new', '/%(repo_name)s/artifacts/new', ['repo_name']);
367 pyroutes.register('repo_artifacts_get', '/%(repo_name)s/artifacts/download/%(uid)s', ['repo_name', 'uid']);
368 pyroutes.register('repo_artifacts_store', '/%(repo_name)s/artifacts/store', ['repo_name']);
369 pyroutes.register('repo_artifacts_delete', '/%(repo_name)s/artifacts/delete/%(uid)s', ['repo_name', 'uid']);
359 pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']);
370 pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']);
360 pyroutes.register('repo_automation_update', '/%(repo_name)s/settings/automation/%(entry_id)s/update', ['repo_name', 'entry_id']);
371 pyroutes.register('repo_automation_update', '/%(repo_name)s/settings/automation/%(entry_id)s/update', ['repo_name', 'entry_id']);
361 pyroutes.register('edit_repo_remote_push', '/%(repo_name)s/settings/remote/push', ['repo_name']);
372 pyroutes.register('edit_repo_remote_push', '/%(repo_name)s/settings/remote/push', ['repo_name']);
@@ -528,7 +528,19 b''
528 if ($.isFunction(serviceUrl)) {
528 if ($.isFunction(serviceUrl)) {
529 serviceUrl = serviceUrl.call(that.element, query);
529 serviceUrl = serviceUrl.call(that.element, query);
530 }
530 }
531 cacheKey = serviceUrl + '?' + $.param(params || {});
531
532 var callParams = {};
533 //make an evaluated copy of params
534 $.each(params, function(index, value) {
535 if($.isFunction(value)){
536 callParams[index] = value();
537 }
538 else {
539 callParams[index] = value;
540 }
541 });
542
543 cacheKey = serviceUrl + '?' + $.param(callParams);
532 response = that.cachedResponse[cacheKey];
544 response = that.cachedResponse[cacheKey];
533 }
545 }
534
546
@@ -536,7 +548,7 b''
536 that.suggestions = response.suggestions;
548 that.suggestions = response.suggestions;
537 that.suggest();
549 that.suggest();
538 } else if (!that.isBadQuery(query)) {
550 } else if (!that.isBadQuery(query)) {
539 if (options.onSearchStart.call(that.element, options.params) === false) {
551 if (options.onSearchStart.call(that.element, params) === false) {
540 return;
552 return;
541 }
553 }
542 if (that.currentRequest) {
554 if (that.currentRequest) {
@@ -102,7 +102,7 b' var showRepoStats = function(target, dat'
102 var total = 0;
102 var total = 0;
103 var no_data = true;
103 var no_data = true;
104 var tbl = document.createElement('table');
104 var tbl = document.createElement('table');
105 tbl.setAttribute('class', 'trending_language_tbl');
105 tbl.setAttribute('class', 'trending_language_tbl rctable');
106
106
107 $.each(data, function(key, val){
107 $.each(data, function(key, val){
108 total += val.count;
108 total += val.count;
@@ -120,54 +120,47 b' var showRepoStats = function(target, dat'
120 cnt += 1;
120 cnt += 1;
121 no_data = false;
121 no_data = false;
122
122
123 var hide = cnt > 2;
124 var tr = document.createElement('tr');
123 var tr = document.createElement('tr');
125 if (hide) {
126 tr.setAttribute('style', 'display:none');
127 tr.setAttribute('class', 'stats_hidden');
128 }
129
124
130 var key = val[0];
125 var key = val[0];
131 var obj = {"desc": val[1].desc, "count": val[1].count};
126 var obj = {"desc": val[1].desc, "count": val[1].count};
132
127
133 var percentage = Math.round((obj.count / total * 100), 2);
128 // meta language names
134
135 var td1 = document.createElement('td');
129 var td1 = document.createElement('td');
136 td1.width = 300;
137 var trending_language_label = document.createElement('div');
130 var trending_language_label = document.createElement('div');
138 trending_language_label.innerHTML = obj.desc + " (.{0})".format(key);
131 trending_language_label.innerHTML = obj.desc;
139 td1.appendChild(trending_language_label);
132 td1.appendChild(trending_language_label);
140
133
134 // extensions
141 var td2 = document.createElement('td');
135 var td2 = document.createElement('td');
142 var trending_language = document.createElement('div');
136 var extension = document.createElement('div');
143 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
137 extension.innerHTML = ".{0}".format(key)
144
138 td2.appendChild(extension);
145 trending_language.title = key + " " + nr_files;
146
139
147 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
140 // number of files
148 + "</span><b>" + percentage + "% " + nr_files + "</b>";
141 var td3 = document.createElement('td');
142 var file_count = document.createElement('div');
143 var percentage_num = Math.round((obj.count / total * 100), 2);
144 var label = _ngettext('file', 'files', obj.count);
145 file_count.innerHTML = "{0} {1} ({2}%)".format(obj.count, label, percentage_num) ;
146 td3.appendChild(file_count);
149
147
150 trending_language.setAttribute("class", 'trending_language');
148 // percentage
151 $('b', trending_language)[0].style.width = percentage + "%";
149 var td4 = document.createElement('td');
152 td2.appendChild(trending_language);
150 td4.setAttribute("class", 'trending_language');
151
152 var percentage = document.createElement('div');
153 percentage.setAttribute('class', 'lang-bar');
154 percentage.innerHTML = "&nbsp;";
155 percentage.style.width = percentage_num + '%';
156 td4.appendChild(percentage);
153
157
154 tr.appendChild(td1);
158 tr.appendChild(td1);
155 tr.appendChild(td2);
159 tr.appendChild(td2);
160 tr.appendChild(td3);
161 tr.appendChild(td4);
156 tbl.appendChild(tr);
162 tbl.appendChild(tr);
157 if (cnt == 3) {
158 var show_more = document.createElement('tr');
159 var td = document.createElement('td');
160 lnk = document.createElement('a');
161
163
162 lnk.href = '#';
163 lnk.innerHTML = _gettext('Show more');
164 lnk.id = 'code_stats_show_more';
165 td.appendChild(lnk);
166
167 show_more.appendChild(td);
168 show_more.appendChild(document.createElement('td'));
169 tbl.appendChild(show_more);
170 }
171 });
164 });
172
165
173 $(container).html(tbl);
166 $(container).html(tbl);
@@ -46,6 +46,8 b' var CommitsController = function () {'
46 self.$graphCanvas.html('');
46 self.$graphCanvas.html('');
47
47
48 var edgeData = $("[data-graph]").data('graph') || this.$graphCanvas.data('graph') || [];
48 var edgeData = $("[data-graph]").data('graph') || this.$graphCanvas.data('graph') || [];
49 var prev_link = $('.load-more-commits').find('.prev-commits').get(0);
50 var next_link = $('.load-more-commits').find('.next-commits').get(0);
49
51
50 // Determine max number of edges per row in graph
52 // Determine max number of edges per row in graph
51 var edgeCount = 1;
53 var edgeCount = 1;
@@ -57,10 +59,20 b' var CommitsController = function () {'
57 });
59 });
58 });
60 });
59
61
62 if (prev_link && next_link) {
63 var graph_padding = -64;
64 }
65 else if (next_link) {
66 var graph_padding = -32;
67 } else {
68 var graph_padding = 0;
69 }
70
60 var x_step = Math.min(10, Math.floor(86 / edgeCount));
71 var x_step = Math.min(10, Math.floor(86 / edgeCount));
72 var height = $('#changesets').find('.commits-range').height() + graph_padding;
61 var graph_options = {
73 var graph_options = {
62 width: 100,
74 width: 100,
63 height: $('#changesets').find('.commits-range').height(),
75 height: height,
64 x_step: x_step,
76 x_step: x_step,
65 y_step: 42,
77 y_step: 42,
66 dotRadius: 3.5,
78 dotRadius: 3.5,
@@ -85,13 +97,20 b' var CommitsController = function () {'
85 this.$graphCanvas.commits(graph_options);
97 this.$graphCanvas.commits(graph_options);
86
98
87 this.setLabelText(edgeData);
99 this.setLabelText(edgeData);
88 if ($('.load-more-commits').find('.prev-commits').get(0)) {
89 var padding = 75;
90
100
91 } else {
101 var padding = 90;
92 var padding = 43;
102 if (prev_link) {
103 padding += 34;
104
93 }
105 }
94 $('#graph_nodes').css({'padding-top': padding});
106 $('#graph_nodes').css({'padding-top': padding});
107
108 $.each($('.message.truncate'), function(idx, value) {
109 if(!(value.offsetWidth < value.scrollWidth)){
110 $(this).closest('td').siblings('.expand_commit').find('i').hide();
111 }
112 });
113
95 };
114 };
96
115
97 this.getChunkUrl = function (page, chunk, branch, commit_id, f_path) {
116 this.getChunkUrl = function (page, chunk, branch, commit_id, f_path) {
@@ -112,10 +131,10 b' var CommitsController = function () {'
112 }
131 }
113
132
114 if (urlData['commit_id'] && urlData['f_path']) {
133 if (urlData['commit_id'] && urlData['f_path']) {
115 return pyroutes.url('repo_changelog_elements_file', urlData);
134 return pyroutes.url('repo_commits_elements_file', urlData);
116 }
135 }
117 else {
136 else {
118 return pyroutes.url('repo_changelog_elements', urlData);
137 return pyroutes.url('repo_commits_elements', urlData);
119 }
138 }
120
139
121 };
140 };
@@ -204,7 +204,12 b' var CodeMirrorCompleteAfter = function(c'
204 };
204 };
205
205
206 var initCodeMirror = function(textAreadId, resetUrl, focus, options) {
206 var initCodeMirror = function(textAreadId, resetUrl, focus, options) {
207 if (textAreadId.substr(0,1) === "#"){
208 var ta = $(textAreadId).get(0);
209 }else {
207 var ta = $('#' + textAreadId).get(0);
210 var ta = $('#' + textAreadId).get(0);
211 }
212
208 if (focus === undefined) {
213 if (focus === undefined) {
209 focus = true;
214 focus = true;
210 }
215 }
@@ -644,18 +649,6 b' var fillCodeMirrorOptions = function(tar'
644 }
649 }
645 };
650 };
646
651
647 var CodeMirrorPreviewEnable = function(edit_mode) {
648 // in case it a preview enabled mode enable the button
649 if (['markdown', 'rst', 'gfm'].indexOf(edit_mode) !== -1) {
650 $('#render_preview').removeClass('hidden');
651 }
652 else {
653 if (!$('#render_preview').hasClass('hidden')) {
654 $('#render_preview').addClass('hidden');
655 }
656 }
657 };
658
659
652
660 /* markup form */
653 /* markup form */
661 (function(mod) {
654 (function(mod) {
@@ -587,12 +587,14 b' var CommentsController = function() {'
587 $('#content').removeClass("wrapper");
587 $('#content').removeClass("wrapper");
588 $('#content').addClass("wide-mode-wrapper");
588 $('#content').addClass("wide-mode-wrapper");
589 $(node).addClass('btn-success');
589 $(node).addClass('btn-success');
590 return true
590 } else {
591 } else {
591 $('#content').removeClass("wide-mode-wrapper");
592 $('#content').removeClass("wide-mode-wrapper");
592 $('#content').addClass("wrapper");
593 $('#content').addClass("wrapper");
593 $(node).removeClass('btn-success');
594 $(node).removeClass('btn-success');
595 return false
594 }
596 }
595 return false;
597
596 };
598 };
597
599
598 this.toggleComments = function(node, show) {
600 this.toggleComments = function(node, show) {
@@ -19,17 +19,23 b''
19 /**
19 /**
20 * Search file list
20 * Search file list
21 */
21 */
22 // global reference to file-node filter
22
23 var _NODEFILTER = {};
23 var NodeFilter = {};
24
24
25 var fileBrowserListeners = function(node_list_url, url_base){
25 var fileBrowserListeners = function (node_list_url, url_base) {
26 var n_filter = $('#node_filter').get(0);
26 var $filterInput = $('#node_filter');
27 var n_filter = $filterInput.get(0);
27
28
28 _NODEFILTER.filterTimeout = null;
29 NodeFilter.filterTimeout = null;
29 var nodes = null;
30 var nodes = null;
30
31
31 _NODEFILTER.fetchNodes = function(callback) {
32 NodeFilter.focus = function () {
32 $.ajax({url: node_list_url, headers: {'X-PARTIAL-XHR': true}})
33 $filterInput.focus()
34 };
35
36 NodeFilter.fetchNodes = function (callback) {
37 $.ajax(
38 {url: node_list_url, headers: {'X-PARTIAL-XHR': true}})
33 .done(function(data){
39 .done(function (data) {
34 nodes = data.nodes;
40 nodes = data.nodes;
35 if (callback) {
41 if (callback) {
@@ -41,36 +47,125 b' var fileBrowserListeners = function(node'
41 });
47 });
42 };
48 };
43
49
44 _NODEFILTER.fetchNodesCallback = function() {
50 NodeFilter.initFilter = function (e) {
45 $('#node_filter_box_loading').hide();
51 if ($filterInput.hasClass('loading')) {
46 $('#node_filter_box').removeClass('hidden').show();
52 return
47 n_filter.focus();
53 }
48 if ($('#node_filter').hasClass('init')){
54
49 n_filter.value = '';
55 // in case we are already loaded, do nothing
50 $('#node_filter').removeClass('init');
56 if (!$filterInput.hasClass('init')) {
57 return NodeFilter.handleKey(e);
58 }
59 var iconLoading = 'icon-spin animate-spin';
60 var iconSearch = 'icon-search';
61 $('.files-filter-box-path i').removeClass(iconSearch).addClass(iconLoading);
62 $filterInput.addClass('loading');
63
64 var callback = function (org) {
65 return function () {
66 if ($filterInput.hasClass('init')) {
67 $filterInput.removeClass('init');
68 $filterInput.removeClass('loading');
51 }
69 }
70 $('.files-filter-box-path i').removeClass(iconLoading).addClass(iconSearch);
71
72 // auto re-filter if we filled in the input
73 if (n_filter.value !== "") {
74 NodeFilter.updateFilter(n_filter, e)()
75 }
76
77 }
78 };
79 // load node data
80 NodeFilter.fetchNodes(callback());
81
82 };
83
84 NodeFilter.resetFilter = function () {
85 $('#tbody').show();
86 $('#tbody_filtered').hide();
87 $filterInput.val('');
88 };
89
90 NodeFilter.handleKey = function (e) {
91 var scrollDown = function (element) {
92 var elementBottom = element.offset().top + $(element).outerHeight();
93 var windowBottom = window.innerHeight + $(window).scrollTop();
94 if (elementBottom > windowBottom) {
95 var offset = elementBottom - window.innerHeight;
96 $('html,body').scrollTop(offset);
97 return false;
98 }
99 return true;
52 };
100 };
53
101
54 _NODEFILTER.initFilter = function(){
102 var scrollUp = function (element) {
55 $('#node_filter_box_loading').removeClass('hidden').show();
103 if (element.offset().top < $(window).scrollTop()) {
56 $('#search_activate_id').hide();
104 $('html,body').scrollTop(element.offset().top);
57 $('#search_deactivate_id').removeClass('hidden').show();
105 return false;
58 $('#add_node_id').hide();
106 }
59 _NODEFILTER.fetchNodes(_NODEFILTER.fetchNodesCallback);
107 return true;
108 };
109 var $hlElem = $('.browser-highlight');
110
111 if (e.keyCode === 40) { // Down
112 if ($hlElem.length === 0) {
113 $('.browser-result').first().addClass('browser-highlight');
114 } else {
115 var next = $hlElem.next();
116 if (next.length !== 0) {
117 $hlElem.removeClass('browser-highlight');
118 next.addClass('browser-highlight');
119 }
120 }
121
122 if ($hlElem.get(0) !== undefined){
123 scrollDown($hlElem);
124 }
125 }
126 if (e.keyCode === 38) { // Up
127 e.preventDefault();
128 if ($hlElem.length !== 0) {
129 var next = $hlElem.prev();
130 if (next.length !== 0) {
131 $('.browser-highlight').removeClass('browser-highlight');
132 next.addClass('browser-highlight');
133 }
134 }
135
136 if ($hlElem.get(0) !== undefined){
137 scrollUp($hlElem);
138 }
139
140 }
141 if (e.keyCode === 13) { // Enter
142 if ($('.browser-highlight').length !== 0) {
143 var url = $('.browser-highlight').find('.match-link').attr('href');
144 window.location = url;
145 }
146 }
147 if (e.keyCode === 27) { // Esc
148 NodeFilter.resetFilter();
149 $('html,body').scrollTop(0);
150 }
151
152 var capture_keys = [
153 40, // ArrowDown
154 38, // ArrowUp
155 39, // ArrowRight
156 37, // ArrowLeft
157 13, // Enter
158 27 // Esc
159 ];
160
161 if ($.inArray(e.keyCode, capture_keys) === -1) {
162 clearTimeout(NodeFilter.filterTimeout);
163 NodeFilter.filterTimeout = setTimeout(NodeFilter.updateFilter(n_filter, e), 200);
164 }
165
60 };
166 };
61
167
62 _NODEFILTER.resetFilter = function(){
168 NodeFilter.fuzzy_match = function (filepath, query) {
63 $('#node_filter_box_loading').hide();
64 $('#node_filter_box').hide();
65 $('#search_activate_id').show();
66 $('#search_deactivate_id').hide();
67 $('#add_node_id').show();
68 $('#tbody').show();
69 $('#tbody_filtered').hide();
70 $('#node_filter').val('');
71 };
72
73 _NODEFILTER.fuzzy_match = function(filepath, query) {
74 var highlight = [];
169 var highlight = [];
75 var order = 0;
170 var order = 0;
76 for (var i = 0; i < query.length; i++) {
171 for (var i = 0; i < query.length; i++) {
@@ -89,11 +184,13 b' var fileBrowserListeners = function(node'
89 return false;
184 return false;
90 }
185 }
91 }
186 }
92 return {'order': order,
187 return {
93 'highlight': highlight};
188 'order': order,
189 'highlight': highlight
190 };
94 };
191 };
95
192
96 _NODEFILTER.sortPredicate = function(a, b) {
193 NodeFilter.sortPredicate = function (a, b) {
97 if (a.order < b.order) return -1;
194 if (a.order < b.order) return -1;
98 if (a.order > b.order) return 1;
195 if (a.order > b.order) return 1;
99 if (a.filepath < b.filepath) return -1;
196 if (a.filepath < b.filepath) return -1;
@@ -101,17 +198,17 b' var fileBrowserListeners = function(node'
101 return 0;
198 return 0;
102 };
199 };
103
200
104 _NODEFILTER.updateFilter = function(elem, e) {
201 NodeFilter.updateFilter = function (elem, e) {
105 return function(){
202 return function () {
106 // Reset timeout
203 // Reset timeout
107 _NODEFILTER.filterTimeout = null;
204 NodeFilter.filterTimeout = null;
108 var query = elem.value.toLowerCase();
205 var query = elem.value.toLowerCase();
109 var match = [];
206 var match = [];
110 var matches_max = 20;
207 var matches_max = 20;
111 if (query !== ""){
208 if (query !== "") {
112 var results = [];
209 var results = [];
113 for(var k=0;k<nodes.length;k++){
210 for (var k = 0; k < nodes.length; k++) {
114 var result = _NODEFILTER.fuzzy_match(
211 var result = NodeFilter.fuzzy_match(
115 nodes[k].name.toLowerCase(), query);
212 nodes[k].name.toLowerCase(), query);
116 if (result) {
213 if (result) {
117 result.type = nodes[k].type;
214 result.type = nodes[k].type;
@@ -119,7 +216,7 b' var fileBrowserListeners = function(node'
119 results.push(result);
216 results.push(result);
120 }
217 }
121 }
218 }
122 results = results.sort(_NODEFILTER.sortPredicate);
219 results = results.sort(NodeFilter.sortPredicate);
123 var limit = matches_max;
220 var limit = matches_max;
124 if (results.length < matches_max) {
221 if (results.length < matches_max) {
125 limit = results.length;
222 limit = results.length;
@@ -142,7 +239,7 b' var fileBrowserListeners = function(node'
142 };
239 };
143
240
144 var typeIcon = '<i class="{0}"></i>'.format(typeObj[t]);
241 var typeIcon = '<i class="{0}"></i>'.format(typeObj[t]);
145 match.push('<tr class="browser-result"><td><a class="pjax-link" href="{0}">{1}{2}</a></td><td colspan="5"></td></tr>'.format(new_url,typeIcon, n_hl));
242 match.push('<tr class="browser-result"><td><a class="match-link" href="{0}">{1}{2}</a></td><td colspan="5"></td></tr>'.format(new_url, typeIcon, n_hl));
146 }
243 }
147 }
244 }
148 if(results.length > limit){
245 if (results.length > limit) {
@@ -162,8 +259,7 b' var fileBrowserListeners = function(node'
162 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_gettext('No matching files')));
259 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_gettext('No matching files')));
163 }
260 }
164 $('#tbody_filtered').html(match.join(""));
261 $('#tbody_filtered').html(match.join(""));
165 }
262 } else {
166 else{
167 $('#tbody').show();
263 $('#tbody').show();
168 $('#tbody_filtered').hide();
264 $('#tbody_filtered').hide();
169 }
265 }
@@ -171,82 +267,6 b' var fileBrowserListeners = function(node'
171 };
267 };
172 };
268 };
173
269
174 var scrollDown = function(element){
175 var elementBottom = element.offset().top + $(element).outerHeight();
176 var windowBottom = window.innerHeight + $(window).scrollTop();
177 if (elementBottom > windowBottom) {
178 var offset = elementBottom - window.innerHeight;
179 $('html,body').scrollTop(offset);
180 return false;
181 }
182 return true;
183 };
184
185 var scrollUp = function(element){
186 if (element.offset().top < $(window).scrollTop()) {
187 $('html,body').scrollTop(element.offset().top);
188 return false;
189 }
190 return true;
191 };
192
193 $('#filter_activate').click(function() {
194 _NODEFILTER.initFilter();
195 });
196
197 $('#filter_deactivate').click(function() {
198 _NODEFILTER.resetFilter();
199 });
200
201 $(n_filter).click(function() {
202 if ($('#node_filter').hasClass('init')){
203 n_filter.value = '';
204 $('#node_filter').removeClass('init');
205 }
206 });
207
208 $(n_filter).keydown(function(e) {
209 if (e.keyCode === 40){ // Down
210 if ($('.browser-highlight').length === 0){
211 $('.browser-result').first().addClass('browser-highlight');
212 } else {
213 var next = $('.browser-highlight').next();
214 if (next.length !== 0) {
215 $('.browser-highlight').removeClass('browser-highlight');
216 next.addClass('browser-highlight');
217 }
218 }
219 scrollDown($('.browser-highlight'));
220 }
221 if (e.keyCode === 38){ // Up
222 e.preventDefault();
223 if ($('.browser-highlight').length !== 0){
224 var next = $('.browser-highlight').prev();
225 if (next.length !== 0) {
226 $('.browser-highlight').removeClass('browser-highlight');
227 next.addClass('browser-highlight');
228 }
229 }
230 scrollUp($('.browser-highlight'));
231 }
232 if (e.keyCode === 13){ // Enter
233 if ($('.browser-highlight').length !== 0){
234 var url = $('.browser-highlight').find('.pjax-link').attr('href');
235 $.pjax({url: url, container: '#pjax-container', timeout: pjaxTimeout});
236 }
237 }
238 if (e.keyCode === 27){ // Esc
239 _NODEFILTER.resetFilter();
240 $('html,body').scrollTop(0);
241 }
242 });
243 var capture_keys = [40, 38, 39, 37, 13, 27];
244 $(n_filter).keyup(function(e) {
245 if ($.inArray(e.keyCode, capture_keys) === -1){
246 clearTimeout(_NODEFILTER.filterTimeout);
247 _NODEFILTER.filterTimeout = setTimeout(_NODEFILTER.updateFilter(n_filter, e),200);
248 }
249 });
250 };
270 };
251
271
252 var getIdentNode = function(n){
272 var getIdentNode = function(n){
@@ -308,3 +328,190 b' var getSelectionLink = function(e) {'
308 }
328 }
309 }
329 }
310 };
330 };
331
332 var getFileState = function() {
333 // relies on a global set filesUrlData
334 var f_path = filesUrlData['f_path'];
335 var commit_id = filesUrlData['commit_id'];
336
337 var url_params = {
338 repo_name: templateContext.repo_name,
339 commit_id: commit_id,
340 f_path:'__FPATH__'
341 };
342 if (atRef !== '') {
343 url_params['at'] = atRef
344 }
345
346 var _url_base = pyroutes.url('repo_files', url_params);
347 var _node_list_url = pyroutes.url('repo_files_nodelist',
348 {repo_name: templateContext.repo_name,
349 commit_id: commit_id, f_path: f_path});
350
351 return {
352 f_path: f_path,
353 commit_id: commit_id,
354 node_list_url: _node_list_url,
355 url_base: _url_base
356 };
357 };
358
359 var getFilesMetadata = function() {
360 // relies on metadataRequest global state
361 if (metadataRequest && metadataRequest.readyState != 4) {
362 metadataRequest.abort();
363 }
364
365 if ($('#file-tree-wrapper').hasClass('full-load')) {
366 // in case our HTML wrapper has full-load class we don't
367 // trigger the async load of metadata
368 return false;
369 }
370
371 var state = getFileState();
372 var url_data = {
373 'repo_name': templateContext.repo_name,
374 'commit_id': state.commit_id,
375 'f_path': state.f_path
376 };
377
378 var url = pyroutes.url('repo_nodetree_full', url_data);
379
380 metadataRequest = $.ajax({url: url});
381
382 metadataRequest.done(function(data) {
383 $('#file-tree').html(data);
384 timeagoActivate();
385 });
386 metadataRequest.fail(function (data, textStatus, errorThrown) {
387 if (data.status != 0) {
388 alert("Error while fetching metadata.\nError code {0} ({1}).Please consider reloading the page".format(data.status,data.statusText));
389 }
390 });
391 };
392
393 // show more authors
394 var showAuthors = function(elem, annotate) {
395 var state = getFileState('callbacks');
396
397 var url = pyroutes.url('repo_file_authors',
398 {'repo_name': templateContext.repo_name,
399 'commit_id': state.commit_id, 'f_path': state.f_path});
400
401 $.pjax({
402 url: url,
403 data: 'annotate={0}'.format(annotate),
404 container: '#file_authors',
405 push: false,
406 timeout: 5000
407 }).complete(function(){
408 $(elem).hide();
409 $('#file_authors_title').html(_gettext('All Authors'))
410 })
411 };
412
413
414 (function (mod) {
415
416 if (typeof exports == "object" && typeof module == "object") {
417 // CommonJS
418 module.exports = mod();
419 } else {
420 // Plain browser env
421 (this || window).FileEditor = mod();
422 }
423
424 })(function () {
425 "use strict";
426
427 function FileEditor(textAreaElement, options) {
428 if (!(this instanceof FileEditor)) {
429 return new FileEditor(textAreaElement, options);
430 }
431 // bind the element instance to our Form
432 var te = $(textAreaElement).get(0);
433 if (te !== undefined) {
434 te.FileEditor = this;
435 }
436
437 this.modes_select = '#set_mode';
438 this.filename_selector = '#filename';
439 this.commit_btn_selector = '#commit_btn';
440 this.line_wrap_selector = '#line_wrap';
441 this.editor_preview_selector = '#editor_preview';
442
443 if (te !== undefined) {
444 this.cm = initCodeMirror(textAreaElement, null, false);
445 }
446
447 // FUNCTIONS and helpers
448 var self = this;
449
450 this.submitHandler = function() {
451 $(self.commit_btn_selector).on('click', function(e) {
452
453 var filename = $(self.filename_selector).val();
454 if (filename === "") {
455 alert("Missing filename");
456 e.preventDefault();
457 }
458
459 var button = $(this);
460 if (button.hasClass('clicked')) {
461 button.attr('disabled', true);
462 } else {
463 button.addClass('clicked');
464 }
465 });
466 };
467 this.submitHandler();
468
469 // on select line wraps change the editor
470 this.lineWrapHandler = function () {
471 $(self.line_wrap_selector).on('change', function (e) {
472 var selected = e.currentTarget;
473 var line_wraps = {'on': true, 'off': false}[selected.value];
474 setCodeMirrorLineWrap(self.cm, line_wraps)
475 });
476 };
477 this.lineWrapHandler();
478
479
480 this.showPreview = function () {
481
482 var _text = self.cm.getValue();
483 var _file_path = $(self.filename_selector).val();
484 if (_text && _file_path) {
485 $('.show-preview').addClass('active');
486 $('.show-editor').removeClass('active');
487
488 $(self.editor_preview_selector).show();
489 $(self.cm.getWrapperElement()).hide();
490
491
492 var post_data = {'text': _text, 'file_path': _file_path, 'csrf_token': CSRF_TOKEN};
493 $(self.editor_preview_selector).html(_gettext('Loading ...'));
494
495 var url = pyroutes.url('file_preview');
496
497 ajaxPOST(url, post_data, function (o) {
498 $(self.editor_preview_selector).html(o);
499 })
500 }
501
502 };
503
504 this.showEditor = function () {
505 $(self.editor_preview_selector).hide();
506 $('.show-editor').addClass('active');
507 $('.show-preview').removeClass('active');
508
509 $(self.cm.getWrapperElement()).show();
510 };
511
512
513 }
514
515 return FileEditor;
516 });
517
@@ -17,56 +17,42 b''
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 var onSuccessFollow = function(target){
19 var onSuccessFollow = function (target) {
20 var f = $(target);
20 var targetEl = $(target);
21 var f_cnt = $('#current_followers_count');
22
21
23 if(f.hasClass('follow')){
22 var callback = function () {
24 f.removeClass('follow');
23 targetEl.animate({'opacity': 1.00}, 200);
25 f.addClass('following');
24 if (targetEl.hasClass('watching')) {
26 f.attr('title', _gettext('Stop following this repository'));
25 targetEl.removeClass('watching');
27 $(f).html(_gettext('Unfollow'));
26 targetEl.attr('title', _gettext('Stopped watching this repository'));
28 if(f_cnt.length){
27 $(targetEl).html('<i class="icon-eye"></i>'+_gettext('Watch'));
29 var cnt = Number(f_cnt.html())+1;
28 } else {
30 f_cnt.html(cnt);
29 targetEl.addClass('watching');
31 }
30 targetEl.attr('title', _gettext('Started watching this repository'));
32 }
31 $(targetEl).html('<i class="icon-eye-off"></i>'+_gettext('Unwatch'));
33 else{
34 f.removeClass('following');
35 f.addClass('follow');
36 f.attr('title', _gettext('Start following this repository'));
37 $(f).html(_gettext('Follow'));
38 if(f_cnt.length){
39 var cnt = Number(f_cnt.html())-1;
40 f_cnt.html(cnt);
41 }
42 }
32 }
43 };
33 };
34 targetEl.animate({'opacity': 0.15}, 200, callback);
35 };
44
36
45 // TODO:: check if the function is needed. 0 usage found
37
46 var toggleFollowingUser = function(target,follows_user_id,token,user_id){
38 var toggleFollowingUser = function (target, follows_user_id) {
47 var args = {
39 var args = {
48 'follows_user_id': follows_user_id,
40 'follows_user_id': follows_user_id,
49 'auth_token': token,
50 'csrf_token': CSRF_TOKEN
41 'csrf_token': CSRF_TOKEN
51 };
42 };
52 if(user_id != undefined){
43
53 args.user_id = user_id
54 }
55 ajaxPOST(pyroutes.url('toggle_following'), args, function(){
44 ajaxPOST(pyroutes.url('toggle_following'), args, function () {
56 onSuccessFollow(target);
45 onSuccessFollow(target);
57 });
46 });
58 return false;
47 return false;
59 };
48 };
60
49
61 var toggleFollowingRepo = function(target,follows_repo_id,token,user_id){
50 var toggleFollowingRepo = function (target, follows_repo_id) {
62 var args = {
51 var args = {
63 'follows_repo_id': follows_repo_id,
52 'follows_repo_id': follows_repo_id,
64 'auth_token': token,
65 'csrf_token': CSRF_TOKEN
53 'csrf_token': CSRF_TOKEN
66 };
54 };
67 if(user_id != undefined){
55
68 args.user_id = user_id
69 }
70 ajaxPOST(pyroutes.url('toggle_following'), args, function(){
56 ajaxPOST(pyroutes.url('toggle_following'), args, function () {
71 onSuccessFollow(target);
57 onSuccessFollow(target);
72 });
58 });
@@ -73,10 +73,3 b' var select2RefSwitcher = function(target'
73 {'repo_name': templateContext.repo_name});
73 {'repo_name': templateContext.repo_name});
74 select2RefBaseSwitcher(targetElement, loadUrl, initialData);
74 select2RefBaseSwitcher(targetElement, loadUrl, initialData);
75 };
75 };
76
77 var select2FileHistorySwitcher = function(targetElement, initialData, state) {
78 var loadUrl = pyroutes.url('repo_file_history',
79 {'repo_name': templateContext.repo_name, 'commit_id': state.rev,
80 'f_path': state.f_path});
81 select2RefBaseSwitcher(targetElement, loadUrl, initialData);
82 };
@@ -9,20 +9,23 b''
9 %endif
9 %endif
10 </%def>
10 </%def>
11
11
12 <%def name="breadcrumbs_links()">
12 <%def name="breadcrumbs_links()"></%def>
13 ${_('Audit long entry')} ${c.audit_log_entry.entry_id}
14 </%def>
15
13
16 <%def name="menu_bar_nav()">
14 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='admin')}
15 ${self.menu_items(active='admin')}
18 </%def>
16 </%def>
17
18 <%def name="menu_bar_subnav()">
19 ${self.admin_menu(active='audit_logs')}
20 </%def>
21
19 <%def name="main()">
22 <%def name="main()">
20 <div class="box">
23 <div class="box">
21 <!-- box / title -->
24
22 <div class="title">
25 <div class="title">
23 ${self.breadcrumbs()}
26 ${_('Audit long entry')} ${c.audit_log_entry.entry_id}
24 </div>
27 </div>
25 <!-- end box / title -->
28
26 <div class="table">
29 <div class="table">
27 <div id="user_log">
30 <div id="user_log">
28 <table class="rctable audit-log">
31 <table class="rctable audit-log">
@@ -8,7 +8,19 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12
13 <%def name="menu_bar_nav()">
14 ${self.menu_items(active='admin')}
15 </%def>
16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='audit_logs')}
19 </%def>
20
21 <%def name="main()">
22 <div class="box">
23 <div class="title">
12 ${h.form(None, id_="filter_form", method="get")}
24 ${h.form(None, id_="filter_form", method="get")}
13 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or ''}" placeholder="${_('filter...')}"/>
25 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or ''}" placeholder="${_('filter...')}"/>
14 <input type='submit' value="${_('filter')}" class="btn" />
26 <input type='submit' value="${_('filter')}" class="btn" />
@@ -16,19 +28,8 b''
16 ${h.end_form()}
28 ${h.end_form()}
17 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
29 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
18 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
30 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
19 </%def>
31 </div>
20
21 <%def name="menu_bar_nav()">
22 ${self.menu_items(active='admin')}
23 </%def>
24
32
25 <%def name="main()">
26 <div class="box">
27 <!-- box / title -->
28 <div class="title">
29 ${self.breadcrumbs()}
30 </div>
31 <!-- end box / title -->
32 <div class="table">
33 <div class="table">
33 <div id="user_log">
34 <div id="user_log">
34 <%include file="/admin/admin_log_base.mako" />
35 <%include file="/admin/admin_log_base.mako" />
@@ -8,29 +8,26 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 &raquo;
14 ${_('Authentication Plugins')}
15 </%def>
16
12
17 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
18 ${self.menu_items(active='admin')}
14 ${self.menu_items(active='admin')}
19 </%def>
15 </%def>
20
16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='authentication')}
19 </%def>
20
21 <%def name="main()">
21 <%def name="main()">
22
22
23 <div class="box">
23 <div class="box">
24 <div class="title">
25 ${self.breadcrumbs()}
26 </div>
27
24
28 <div class='sidebar-col-wrapper'>
25 <div class='sidebar-col-wrapper'>
29
26
30 <div class="sidebar">
27 <div class="sidebar">
31 <ul class="nav nav-pills nav-stacked">
28 <ul class="nav nav-pills nav-stacked">
32 % for item in resource.get_root().get_nav_list():
29 % for item in resource.get_root().get_nav_list():
33 <li ${'class=active' if item == resource else ''}>
30 <li ${('class=active' if item == resource else '')}>
34 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
31 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
35 </li>
32 </li>
36 % endfor
33 % endfor
@@ -66,10 +63,10 b''
66 <th>${_('Plugin ID')}</th>
63 <th>${_('Plugin ID')}</th>
67 <th>${_('Enabled')}</th>
64 <th>${_('Enabled')}</th>
68 %for plugin in available_plugins:
65 %for plugin in available_plugins:
69 <tr class="${'inactive' if (not plugin.is_active() and plugin.get_id() in enabled_plugins) else ''}">
66 <tr class="${('inactive' if (not plugin.is_active() and plugin.get_id() in enabled_plugins) else '')}">
70 <td>
67 <td>
71 <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${'btn-success' if plugin.get_id() in enabled_plugins else ''}">
68 <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${('btn-success' if plugin.get_id() in enabled_plugins else '')}">
72 ${_('activated') if plugin.get_id() in enabled_plugins else _('not active')}
69 ${(_('activated') if plugin.get_id() in enabled_plugins else _('not active'))}
73 </span>
70 </span>
74 </td>
71 </td>
75 <td>${plugin.get_display_name()}</td>
72 <td>${plugin.get_display_name()}</td>
@@ -20,19 +20,20 b''
20 ${self.menu_items(active='admin')}
20 ${self.menu_items(active='admin')}
21 </%def>
21 </%def>
22
22
23 <%def name="menu_bar_subnav()">
24 ${self.admin_menu(active='authentication')}
25 </%def>
26
23 <%def name="main()">
27 <%def name="main()">
28
24 <div class="box">
29 <div class="box">
25 <div class="title">
30
26 ${self.breadcrumbs()}
27 </div>
28 <div class='sidebar-col-wrapper'>
31 <div class='sidebar-col-wrapper'>
29
32
30 ## TODO: This is repeated in the auth root template and should be merged
31 ## into a single solution.
32 <div class="sidebar">
33 <div class="sidebar">
33 <ul class="nav nav-pills nav-stacked">
34 <ul class="nav nav-pills nav-stacked">
34 % for item in resource.get_root().get_nav_list():
35 % for item in resource.get_root().get_nav_list():
35 <li ${'class=active' if item == resource else ''}>
36 <li ${('class=active' if item == resource else '')}>
36 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
37 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
37 </li>
38 </li>
38 % endfor
39 % endfor
@@ -18,11 +18,12 b''
18 ${self.menu_items(active='admin')}
18 ${self.menu_items(active='admin')}
19 </%def>
19 </%def>
20
20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='defaults')}
23 </%def>
24
21 <%def name="main()">
25 <%def name="main()">
22 <div class="box">
26 <div class="box">
23 <div class="title">
24 ${self.breadcrumbs()}
25 </div>
26
27
27 ##main
28 ##main
28 <div class="sidebar-col-wrapper">
29 <div class="sidebar-col-wrapper">
@@ -3,9 +3,9 b''
3
3
4 <%def name="title()">
4 <%def name="title()">
5 %if c.show_private:
5 %if c.show_private:
6 ${_('Private Gists for user %s') % c.rhodecode_user.username}
6 ${_('Private Gists for user {}').format(c.rhodecode_user.username)}
7 %elif c.show_public:
7 %elif c.show_public:
8 ${_('Public Gists for user %s') % c.rhodecode_user.username}
8 ${_('Public Gists for user {}').format(c.rhodecode_user.username)}
9 %else:
9 %else:
10 ${_('Public Gists')}
10 ${_('Public Gists')}
11 %endif
11 %endif
@@ -14,64 +14,59 b''
14 %endif
14 %endif
15 </%def>
15 </%def>
16
16
17 <%def name="breadcrumbs_links()">
17 <%def name="breadcrumbs_links()"></%def>
18 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
19 %if c.show_private and not c.show_public:
20 ${_('Private Gists for user %s') % c.rhodecode_user.username}
21 %elif c.show_public and not c.show_private:
22 ${_('Public Gists for user %s') % c.rhodecode_user.username}
23 %elif c.show_public and c.show_private:
24 ${_('All Gists for user %s') % c.rhodecode_user.username}
25 %else:
26 ${_('All Public Gists')}
27 %endif
28 - <span id="gists_count">0</span>
29 </%def>
30
18
31 <%def name="menu_bar_nav()">
19 <%def name="menu_bar_nav()">
32 ${self.menu_items(active='gists')}
20 ${self.menu_items(active='gists')}
33 </%def>
21 </%def>
34
22
35
23 <%def name="main()">
36
24
37 <%def name="main()">
38 <div class="box">
25 <div class="box">
39 <div class="title">
26 <div class="title">
40 ${self.breadcrumbs(class_="breadcrumbs block-left")}
27
28 <ul class="button-links">
29 % if c.is_super_admin:
30 <li class="btn ${('active' if c.active=='all' else '')}"><a href="${h.route_path('gists_show', _query={'all': 1})}">${_('All gists')}</a></li>
31 %endif
32 <li class="btn ${('active' if c.active=='public' else '')}"><a href="${h.route_path('gists_show')}">${_('All public')}</a></li>
41 %if c.rhodecode_user.username != h.DEFAULT_USER:
33 %if c.rhodecode_user.username != h.DEFAULT_USER:
42 <ul class="links block-right">
34 <li class="btn ${('active' if c.active=='my_all' else '')}"><a href="${h.route_path('gists_show', _query={'public':1, 'private': 1})}">${_('My gists')}</a></li>
43 <li>
35 <li class="btn ${('active' if c.active=='my_private' else '')}"><a href="${h.route_path('gists_show', _query={'private': 1})}">${_('My private')}</a></li>
44 <a href="${h.route_path('gists_new')}" class="btn btn-primary">${_(u'Create New Gist')}</a>
36 <li class="btn ${('active' if c.active=='my_public' else '')}"><a href="${h.route_path('gists_show', _query={'public': 1})}">${_('My public')}</a></li>
45 </li>
37 %endif
46 </ul>
38 </ul>
47 %endif
48 </div>
49
50
39
51 <div class="sidebar-col-wrapper scw-small">
40 % if c.rhodecode_user.username != h.DEFAULT_USER:
52 ##main
41 <div class="pull-right">
53 <div class="sidebar">
42 <a class="btn btn-primary" href="${h.route_path('gists_new')}" >
54 <ul class="nav nav-pills nav-stacked">
43 ${_(u'Create New Gist')}
55 % if h.HasPermissionAll('hg.admin')('access admin gists page'):
44 </a>
56 <li class="${'active' if c.active=='all' else ''}"><a href="${h.route_path('gists_show', _query={'all': 1})}">${_('All gists')}</a></li>
45 </div>
57 %endif
46 % endif
58 <li class="${'active' if c.active=='public' else ''}"><a href="${h.route_path('gists_show')}">${_('All public')}</a></li>
47
59 %if c.rhodecode_user.username != h.DEFAULT_USER:
48 <div class="grid-quick-filter">
60 <li class="${'active' if c.active=='my_all' else ''}"><a href="${h.route_path('gists_show', _query={'public':1, 'private': 1})}">${_('My gists')}</a></li>
49 <ul class="grid-filter-box">
61 <li class="${'active' if c.active=='my_private' else ''}"><a href="${h.route_path('gists_show', _query={'private': 1})}">${_('My private')}</a></li>
50 <li class="grid-filter-box-icon">
62 <li class="${'active' if c.active=='my_public' else ''}"><a href="${h.route_path('gists_show', _query={'public': 1})}">${_('My public')}</a></li>
51 <i class="icon-search"></i>
63 %endif
52 </li>
53 <li class="grid-filter-box-input">
54 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
55 </li>
64 </ul>
56 </ul>
65 </div>
57 </div>
66
58
67 <div class="main-content">
59 </div>
60
61 <div class="main-content-full-width">
68 <div id="repos_list_wrap">
62 <div id="repos_list_wrap">
69 <table id="gist_list_table" class="display"></table>
63 <table id="gist_list_table" class="display"></table>
70 </div>
64 </div>
71 </div>
65 </div>
72 </div>
66
73 </div>
67 </div>
74 <script>
68
69 <script type="text/javascript">
75 $(document).ready(function() {
70 $(document).ready(function() {
76
71
77 var get_datatable_count = function(){
72 var get_datatable_count = function(){
@@ -48,7 +48,7 b''
48 </code>
48 </code>
49 </div>
49 </div>
50 <div class="stats">
50 <div class="stats">
51 %if h.HasPermissionAny('hg.admin')() or c.gist.gist_owner == c.rhodecode_user.user_id:
51 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
52 <div class="remove_gist">
52 <div class="remove_gist">
53 ${h.secure_form(h.route_path('gist_delete', gist_id=c.gist.gist_access_id), request=request)}
53 ${h.secure_form(h.route_path('gist_delete', gist_id=c.gist.gist_access_id), request=request)}
54 ${h.submit('remove_gist', _('Delete'),class_="btn btn-mini btn-danger",onclick="return confirm('"+_('Confirm to delete this Gist')+"');")}
54 ${h.submit('remove_gist', _('Delete'),class_="btn btn-mini btn-danger",onclick="return confirm('"+_('Confirm to delete this Gist')+"');")}
@@ -59,7 +59,7 b''
59 ## only owner should see that
59 ## only owner should see that
60 <a href="#copySource" onclick="return false;" class="btn btn-mini icon-clipboard clipboard-action" data-clipboard-text="${c.files[0].content}">${_('Copy content')}</a>
60 <a href="#copySource" onclick="return false;" class="btn btn-mini icon-clipboard clipboard-action" data-clipboard-text="${c.files[0].content}">${_('Copy content')}</a>
61
61
62 %if h.HasPermissionAny('hg.admin')() or c.gist.gist_owner == c.rhodecode_user.user_id:
62 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
63 ${h.link_to(_('Edit'), h.route_path('gist_edit', gist_id=c.gist.gist_access_id), class_="btn btn-mini")}
63 ${h.link_to(_('Edit'), h.route_path('gist_edit', gist_id=c.gist.gist_access_id), class_="btn btn-mini")}
64 %endif
64 %endif
65 ${h.link_to(_('Show as Raw'), h.route_path('gist_show_formatted', gist_id=c.gist.gist_access_id, revision='tip', format='raw'), class_="btn btn-mini")}
65 ${h.link_to(_('Show as Raw'), h.route_path('gist_show_formatted', gist_id=c.gist.gist_access_id, revision='tip', format='raw'), class_="btn btn-mini")}
@@ -6,7 +6,7 b''
6 elif context['c'].repo_group:
6 elif context['c'].repo_group:
7 return "/admin/repo_groups/repo_group_edit.mako"
7 return "/admin/repo_groups/repo_group_edit.mako"
8 else:
8 else:
9 return "/admin/settings/settings.mako"
9 return "/admin/integrations/global.mako"
10 %>
10 %>
11 <%inherit file="${inherit(context)}" />
11 <%inherit file="${inherit(context)}" />
12
12
@@ -31,12 +31,6 b''
31 %endif
31 %endif
32 </%def>
32 </%def>
33
33
34 <%def name="menu_bar_subnav()">
35 %if c.repo:
36 ${self.repo_menu(active='options')}
37 %endif
38 </%def>
39
40 <%def name="main_content()">
34 <%def name="main_content()">
41 ${next.body()}
35 ${next.body()}
42 </%def>
36 </%def>
@@ -43,7 +43,7 b''
43 %if c.repo:
43 %if c.repo:
44 ${_('Current Integrations for Repository: {repo_name}').format(repo_name=c.repo.repo_name)}
44 ${_('Current Integrations for Repository: {repo_name}').format(repo_name=c.repo.repo_name)}
45 %elif c.repo_group:
45 %elif c.repo_group:
46 ${_('Current Integrations for repository group: {repo_group_name}').format(repo_group_name=c.repo_group.group_name)}
46 ${_('Repository Group Integrations: {}').format(c.repo_group.group_name)}</h3>
47 %else:
47 %else:
48 ${_('Current Integrations')}
48 ${_('Current Integrations')}
49 %endif
49 %endif
@@ -107,11 +107,9 b''
107 %for IntegrationType, integration in c.integrations_list:
107 %for IntegrationType, integration in c.integrations_list:
108 <tr id="integration_${integration.integration_id}">
108 <tr id="integration_${integration.integration_id}">
109 <td class="td-enabled">
109 <td class="td-enabled">
110 %if integration.enabled:
110 <div class="pull-left">
111 <div class="flag_status approved pull-left"></div>
111 ${h.bool2icon(integration.enabled)}
112 %else:
112 </div>
113 <div class="flag_status rejected pull-left"></div>
114 %endif
115 </td>
113 </td>
116 <td class="td-description">
114 <td class="td-description">
117 ${integration.name}
115 ${integration.name}
@@ -25,6 +25,9 b''
25 </div>
25 </div>
26 </div>
26 </div>
27 </div>
27 </div>
28 <p class="help-block help-block-inline" >
29 ${_('Server URL is available as ${server_url} variable. E.g. Redirect url: ${server_url}/_admin/exception_tracker')}
30 </p>
28
31
29 <div class="label">
32 <div class="label">
30 <label for="redirect_url">${_('Redirect URL')}:</label>
33 <label for="redirect_url">${_('Redirect URL')}:</label>
@@ -5,51 +5,60 b''
5 <a href="${h.route_path('my_account_edit')}" class="panel-edit">${_('Edit')}</a>
5 <a href="${h.route_path('my_account_edit')}" class="panel-edit">${_('Edit')}</a>
6 </div>
6 </div>
7
7
8 <div class="panel-body">
8 <div class="panel-body fields">
9 <div class="fieldset">
9 <div class="field">
10 <div class="left-label">
10 <div class="label">
11 ${_('Photo')}:
11 ${_('Photo')}:
12 </div>
12 </div>
13 <div class="right-content">
13 <div class="input">
14 <div class="text-as-placeholder">
14 %if c.visual.use_gravatar:
15 %if c.visual.use_gravatar:
15 ${base.gravatar(c.user.email, 100)}
16 ${base.gravatar(c.user.email, 100)}
16 %else:
17 %else:
17 ${base.gravatar(c.user.email, 20)}
18 ${base.gravatar(c.user.email, 100)}
18 ${_('Avatars are disabled')}
19 %endif
19 %endif
20 </div>
20 </div>
21 </div>
21 </div>
22 <div class="fieldset">
22 </div>
23 <div class="left-label">
23 <div class="field">
24 <div class="label">
24 ${_('Username')}:
25 ${_('Username')}:
25 </div>
26 </div>
26 <div class="right-content">
27 <div class="input">
28 <div class="text-as-placeholder">
27 ${c.user.username}
29 ${c.user.username}
28 </div>
30 </div>
29 </div>
31 </div>
30 <div class="fieldset">
32 </div>
31 <div class="left-label">
33 <div class="field">
34 <div class="label">
32 ${_('First Name')}:
35 ${_('First Name')}:
33 </div>
36 </div>
34 <div class="right-content">
37 <div class="input">
38 <div class="text-as-placeholder">
35 ${c.user.first_name}
39 ${c.user.first_name}
36 </div>
40 </div>
37 </div>
41 </div>
38 <div class="fieldset">
42 </div>
39 <div class="left-label">
43 <div class="field">
44 <div class="label">
40 ${_('Last Name')}:
45 ${_('Last Name')}:
41 </div>
46 </div>
42 <div class="right-content">
47 <div class="input">
48 <div class="text-as-placeholder">
43 ${c.user.last_name}
49 ${c.user.last_name}
44 </div>
50 </div>
45 </div>
51 </div>
46 <div class="fieldset">
52 </div>
47 <div class="left-label">
53 <div class="field">
54 <div class="label">
48 ${_('Email')}:
55 ${_('Email')}:
49 </div>
56 </div>
50 <div class="right-content">
57 <div class="input">
58 <div class="text-as-placeholder">
51 ${c.user.email or _('Missing email, please update your user email address.')}
59 ${c.user.email or _('Missing email, please update your user email address.')}
52 </div>
60 </div>
53 </div>
61 </div>
54 </div>
62 </div>
63 </div>
55 </div> No newline at end of file
64 </div>
@@ -58,8 +58,7 b''
58 ${base.gravatar(c.user.email, 100)}
58 ${base.gravatar(c.user.email, 100)}
59 <p class="help-block">${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
59 <p class="help-block">${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
60 %else:
60 %else:
61 ${base.gravatar(c.user.email, 20)}
61 ${base.gravatar(c.user.email, 100)}
62 ${_('Avatars are disabled')}
63 %endif
62 %endif
64 </div>
63 </div>
65 </div>
64 </div>
@@ -8,9 +8,7 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 ${_('My Notifications')}
13 </%def>
14
12
15 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
16 ${self.menu_items(active='my_account')}
14 ${self.menu_items(active='my_account')}
@@ -19,7 +17,8 b''
19 <%def name="main()">
17 <%def name="main()">
20 <div class="box">
18 <div class="box">
21 <div class="title">
19 <div class="title">
22 ${self.breadcrumbs()}
20 ${_('My Notifications')}
21
23 <div class="notifications_buttons">
22 <div class="notifications_buttons">
24 %if c.notifications:
23 %if c.notifications:
25 <button id='mark_all_read' class="btn btn-default" type="submit">
24 <button id='mark_all_read' class="btn btn-default" type="submit">
@@ -18,12 +18,12 b''
18 ${self.menu_items(active='admin')}
18 ${self.menu_items(active='admin')}
19 </%def>
19 </%def>
20
20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='permissions')}
23 </%def>
21
24
22 <%def name="main()">
25 <%def name="main()">
23 <div class="box">
26 <div class="box">
24 <div class="title">
25 ${self.breadcrumbs()}
26 </div>
27
27
28 <div class="sidebar-col-wrapper scw-small">
28 <div class="sidebar-col-wrapper scw-small">
29 ##main
29 ##main
@@ -20,13 +20,12 b''
20 ${self.menu_items(active='admin')}
20 ${self.menu_items(active='admin')}
21 </%def>
21 </%def>
22
22
23 <%def name="menu_bar_subnav()">
24 ${self.admin_menu(active='repository_groups')}
25 </%def>
26
23 <%def name="main()">
27 <%def name="main()">
24 <div class="box">
28 <div class="box">
25 <!-- box / title -->
26 <div class="title">
27 ${self.breadcrumbs()}
28 </div>
29 <!-- end box / title -->
30 ${h.secure_form(h.route_path('repo_group_create'), request=request)}
29 ${h.secure_form(h.route_path('repo_group_create'), request=request)}
31 <div class="form">
30 <div class="form">
32 <!-- fields -->
31 <!-- fields -->
@@ -13,7 +13,7 b''
13 </%def>
13 </%def>
14
14
15 <%def name="menu_bar_subnav()">
15 <%def name="menu_bar_subnav()">
16 ${self.repo_group_menu(active='options')}
16 ${self.repo_group_menu(active='settings')}
17 </%def>
17 </%def>
18
18
19 <%def name="main_content()">
19 <%def name="main_content()">
@@ -23,10 +23,6 b''
23 <%def name="main()">
23 <%def name="main()">
24
24
25 <div class="box">
25 <div class="box">
26 <div class="title">
27 ${self.repo_group_page_title(c.repo_group)}
28 </div>
29
30 <div class="sidebar-col-wrapper">
26 <div class="sidebar-col-wrapper">
31 ##main
27 ##main
32 <div class="sidebar">
28 <div class="sidebar">
@@ -1,10 +1,16 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <%
3 <%
4 source_repo_id = c.repo_group.changeset_cache.get('source_repo_id')
5
4 elems = [
6 elems = [
5 (_('Repository Group ID'), c.repo_group.group_id, '', ''),
7 (_('Repository Group ID'), c.repo_group.group_id, '', ''),
6 (_('Owner'), lambda:base.gravatar_with_user(c.repo_group.user.email), '', ''),
8 (_('Owner'), lambda:base.gravatar_with_user(c.repo_group.user.email), '', ''),
7 (_('Created on'), h.format_date(c.repo_group.created_on), '', ''),
9 (_('Created on'), h.format_date(c.repo_group.created_on), '', ''),
10 (_('Updated on'), h.format_date(c.repo_group.updated_on), '', ''),
11 (_('Cached Commit date'), (c.repo_group.changeset_cache.get('date')), '', ''),
12 (_('Cached Commit repo_id'), (h.link_to_if(source_repo_id, source_repo_id, h.route_path('repo_summary', repo_name='_{}'.format(source_repo_id)))), '', ''),
13
8 (_('Is Personal Group'), c.repo_group.personal or False, '', ''),
14 (_('Is Personal Group'), c.repo_group.personal or False, '', ''),
9
15
10 (_('Total repositories'), c.repo_group.repositories_recursive_count, '', ''),
16 (_('Total repositories'), c.repo_group.repositories_recursive_count, '', ''),
@@ -16,7 +22,7 b''
16
22
17 <div class="panel panel-default">
23 <div class="panel panel-default">
18 <div class="panel-heading">
24 <div class="panel-heading">
19 <h3 class="panel-title">${_('Repository Group: %s') % c.repo_group.group_name}</h3>
25 <h3 class="panel-title">${_('Repository Group Advanced: {}').format(c.repo_group.name)}</h3>
20 </div>
26 </div>
21 <div class="panel-body">
27 <div class="panel-body">
22 ${base.dt_info_panel(elems)}
28 ${base.dt_info_panel(elems)}
@@ -2,7 +2,7 b''
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('Repository Group Permissions')}</h3>
5 <h3 class="panel-title">${_('Repository Group Permissions: {}').format(c.repo_group.name)}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 ${h.secure_form(h.route_path('edit_repo_group_perms_update', repo_group_name=c.repo_group.group_name), request=request)}
8 ${h.secure_form(h.route_path('edit_repo_group_perms_update', repo_group_name=c.repo_group.group_name), request=request)}
@@ -141,7 +141,7 b''
141 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.admin', checked=_user_group.permission=='group.admin')}</td>
141 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.admin', checked=_user_group.permission=='group.admin')}</td>
142 <td class="td-componentname">
142 <td class="td-componentname">
143 <i class="icon-user-group"></i>
143 <i class="icon-user-group"></i>
144 %if h.HasPermissionAny('hg.admin')():
144 %if c.is_super_admin:
145 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
145 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
146 ${_user_group.users_group_name}
146 ${_user_group.users_group_name}
147 </a>
147 </a>
@@ -3,7 +3,7 b''
3
3
4 <div class="panel panel-default">
4 <div class="panel panel-default">
5 <div class="panel-heading">
5 <div class="panel-heading">
6 <h3 class="panel-title">${_('Settings for Repository Group: %s') % c.repo_group.name}</h3>
6 <h3 class="panel-title">${_('Repository Group Settings: {}').format(c.repo_group.name)}</h3>
7 </div>
7 </div>
8 <div class="panel-body">
8 <div class="panel-body">
9 ${h.secure_form(h.route_path('edit_repo_group', repo_group_name=c.repo_group.group_name), request=request)}
9 ${h.secure_form(h.route_path('edit_repo_group', repo_group_name=c.repo_group.group_name), request=request)}
@@ -8,21 +8,25 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="repo_group_count">0</span> ${_('repository groups')}
14 </%def>
15
12
16 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='admin')}
14 ${self.menu_items(active='admin')}
18 </%def>
15 </%def>
19
16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='repository_groups')}
19 </%def>
20
20 <%def name="main()">
21 <%def name="main()">
21 <div class="box">
22 <div class="box">
23
22 <div class="title">
24 <div class="title">
23 ${self.breadcrumbs()}
25 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
26 <span id="repo_group_count">0</span> ${_('repository groups')}
27
24 <ul class="links">
28 <ul class="links">
25 %if h.HasPermissionAny('hg.admin','hg.repogroup.create.true')():
29 %if c.can_create_repo_group:
26 <li>
30 <li>
27 <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-success">${_(u'Add Repository Group')}</a>
31 <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-success">${_(u'Add Repository Group')}</a>
28 </li>
32 </li>
@@ -36,15 +40,32 b''
36
40
37 <script>
41 <script>
38 $(document).ready(function() {
42 $(document).ready(function() {
39
43 var $repoGroupsListTable = $('#group_list_table');
40 var get_datatable_count = function(){
41 var api = $('#group_list_table').dataTable().api();
42 $('#repo_group_count').text(api.page.info().recordsDisplay);
43 };
44
44
45 // repo group list
45 // repo group list
46 $('#group_list_table').DataTable({
46 $repoGroupsListTable.DataTable({
47 data: ${c.data|n},
47 processing: true,
48 serverSide: true,
49 ajax: {
50 "url": "${h.route_path('repo_groups_data')}",
51 "dataSrc": function (json) {
52 var filteredCount = json.recordsFiltered;
53 var filteredInactiveCount = json.recordsFilteredInactive;
54 var totalInactive = json.recordsTotalInactive;
55 var total = json.recordsTotal;
56
57 var _text = _gettext(
58 "{0} of {1} repository groups").format(
59 filteredCount, total);
60
61 if (total === filteredCount) {
62 _text = _gettext("{0} repository groups").format(total);
63 }
64 $('#repo_group_count').text(_text);
65 return json.data;
66 },
67 },
68
48 dom: 'rtp',
69 dom: 'rtp',
49 pageLength: ${c.visual.admin_grid_items},
70 pageLength: ${c.visual.admin_grid_items},
50 order: [[ 0, "asc" ]],
71 order: [[ 0, "asc" ]],
@@ -62,36 +83,34 b''
62 { data: {"_": "owner",
83 { data: {"_": "owner",
63 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
84 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
64 { data: {"_": "action",
85 { data: {"_": "action",
65 "sort": "action"}, title: "${_('Action')}", className: "td-action" }
86 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false }
66 ],
87 ],
67 language: {
88 language: {
68 paginate: DEFAULT_GRID_PAGINATION,
89 paginate: DEFAULT_GRID_PAGINATION,
90 sProcessing: _gettext('loading...'),
69 emptyTable: _gettext("No repository groups available yet.")
91 emptyTable: _gettext("No repository groups available yet.")
70 },
92 },
71 "initComplete": function( settings, json ) {
72 get_datatable_count();
73 quick_repo_menu();
74 }
75 });
93 });
76
94
77 // update the counter when doing search
95 $repoGroupsListTable.on('xhr.dt', function(e, settings, json, xhr){
78 $('#group_list_table').on( 'search.dt', function (e,settings) {
96 $repoGroupsListTable.css('opacity', 1);
79 get_datatable_count();
97 });
98
99 $repoGroupsListTable.on('preXhr.dt', function(e, settings, data){
100 $repoGroupsListTable.css('opacity', 0.3);
80 });
101 });
81
102
82 // filter, filter both grids
103 // filter
83 $('#q_filter').on( 'keyup', function () {
104 $('#q_filter').on('keyup',
84
105 $.debounce(250, function() {
85 var repo_group_api = $('#group_list_table').dataTable().api();
106 $repoGroupsListTable.DataTable().search(
86 repo_group_api
107 $('#q_filter').val()
87 .columns(0)
108 ).draw();
88 .search(this.value)
109 })
89 .draw();
110 );
90 });
111 });
91
112
92 // refilter table if page load via back button
93 $("#q_filter").trigger('keyup');
94 });
95 </script>
113 </script>
114
96 </%def>
115 </%def>
97
116
@@ -26,12 +26,12 b''
26 ${self.menu_items(active='admin')}
26 ${self.menu_items(active='admin')}
27 </%def>
27 </%def>
28
28
29 <%def name="menu_bar_subnav()">
30 ${self.admin_menu(active='repositories')}
31 </%def>
32
29 <%def name="main()">
33 <%def name="main()">
30 <div class="box">
34 <div class="box">
31 <!-- box / title -->
32 <div class="title">
33 ${self.breadcrumbs()}
34 </div>
35 <%include file="repo_add_base.mako"/>
35 <%include file="repo_add_base.mako"/>
36 </div>
36 </div>
37 </%def>
37 </%def>
@@ -20,7 +20,7 b''
20 </%def>
20 </%def>
21
21
22 <%def name="menu_bar_subnav()">
22 <%def name="menu_bar_subnav()">
23 ${self.repo_menu(active='options')}
23 ${self.repo_menu(active='settings')}
24 </%def>
24 </%def>
25
25
26 <%def name="main_content()">
26 <%def name="main_content()">
@@ -34,10 +34,6 b''
34
34
35 <%def name="main()">
35 <%def name="main()">
36 <div class="box">
36 <div class="box">
37 <div class="title">
38 ${self.repo_page_title(c.rhodecode_db_repo)}
39
40 </div>
41
37
42 <div class="sidebar-col-wrapper scw-small">
38 <div class="sidebar-col-wrapper scw-small">
43 <div class="sidebar">
39 <div class="sidebar">
@@ -7,9 +7,11 b''
7 (_('Created on'), h.format_date(c.rhodecode_db_repo.created_on), '', ''),
7 (_('Created on'), h.format_date(c.rhodecode_db_repo.created_on), '', ''),
8 (_('Updated on'), h.format_date(c.rhodecode_db_repo.updated_on), '', ''),
8 (_('Updated on'), h.format_date(c.rhodecode_db_repo.updated_on), '', ''),
9 (_('Cached Commit id'), lambda: h.link_to(c.rhodecode_db_repo.changeset_cache.get('short_id'), h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.changeset_cache.get('raw_id'))), '', ''),
9 (_('Cached Commit id'), lambda: h.link_to(c.rhodecode_db_repo.changeset_cache.get('short_id'), h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.changeset_cache.get('raw_id'))), '', ''),
10 (_('Cached Commit date'), c.rhodecode_db_repo.changeset_cache.get('date'), '', ''),
10 (_('Attached scoped tokens'), len(c.rhodecode_db_repo.scoped_tokens), '', [x.user for x in c.rhodecode_db_repo.scoped_tokens]),
11 (_('Attached scoped tokens'), len(c.rhodecode_db_repo.scoped_tokens), '', [x.user for x in c.rhodecode_db_repo.scoped_tokens]),
11 (_('Pull requests source'), len(c.rhodecode_db_repo.pull_requests_source), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.source_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_source]),
12 (_('Pull requests source'), len(c.rhodecode_db_repo.pull_requests_source), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.source_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_source]),
12 (_('Pull requests target'), len(c.rhodecode_db_repo.pull_requests_target), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.target_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_target]),
13 (_('Pull requests target'), len(c.rhodecode_db_repo.pull_requests_target), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.target_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_target]),
14 (_('Attached Artifacts'), len(c.rhodecode_db_repo.artifacts), '', ''),
13 ]
15 ]
14 %>
16 %>
15
17
@@ -136,7 +136,7 b''
136 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.admin', checked=_user_group.permission=='repository.admin')}</td>
136 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.admin', checked=_user_group.permission=='repository.admin')}</td>
137 <td class="td-componentname">
137 <td class="td-componentname">
138 <i class="icon-user-group"></i>
138 <i class="icon-user-group"></i>
139 %if h.HasPermissionAny('hg.admin')():
139 %if c.is_super_admin:
140 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
140 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
141 ${_user_group.users_group_name}
141 ${_user_group.users_group_name}
142 </a>
142 </a>
@@ -8,21 +8,25 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="repo_count">0</span> ${_('repositories')}
14 </%def>
15
12
16 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='admin')}
14 ${self.menu_items(active='admin')}
18 </%def>
15 </%def>
19
16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='repositories')}
19 </%def>
20
20 <%def name="main()">
21 <%def name="main()">
21 <div class="box">
22 <div class="box">
23
22 <div class="title">
24 <div class="title">
23 ${self.breadcrumbs()}
25 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
26 <span id="repo_count">0</span> ${_('repositories')}
27
24 <ul class="links">
28 <ul class="links">
25 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
29 %if c.can_create_repo:
26 <li>
30 <li>
27 <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success">${_(u'Add Repository')}</a>
31 <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success">${_(u'Add Repository')}</a>
28 </li>
32 </li>
@@ -66,7 +70,7 b''
66 { data: {"_": "state",
70 { data: {"_": "state",
67 "sort": "state"}, title: "${_('State')}", className: "td-tags td-state" },
71 "sort": "state"}, title: "${_('State')}", className: "td-tags td-state" },
68 { data: {"_": "action",
72 { data: {"_": "action",
69 "sort": "action"}, title: "${_('Action')}", className: "td-action" }
73 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false }
70 ],
74 ],
71 language: {
75 language: {
72 paginate: DEFAULT_GRID_PAGINATION,
76 paginate: DEFAULT_GRID_PAGINATION,
@@ -13,11 +13,15 b''
13 &raquo;
13 &raquo;
14 ${_('Settings')}
14 ${_('Settings')}
15 </%def>
15 </%def>
16
16 ##
17 <%def name="menu_bar_nav()">
17 <%def name="menu_bar_nav()">
18 ${self.menu_items(active='admin')}
18 ${self.menu_items(active='admin')}
19 </%def>
19 </%def>
20
20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='settings')}
23 </%def>
24
21 <%def name="side_bar_nav()">
25 <%def name="side_bar_nav()">
22 % for navitem in c.navlist:
26 % for navitem in c.navlist:
23 <li class="${'active' if c.active in navitem.active_list else ''}">
27 <li class="${'active' if c.active in navitem.active_list else ''}">
@@ -32,9 +36,6 b''
32
36
33 <%def name="main()">
37 <%def name="main()">
34 <div class="box">
38 <div class="box">
35 <div class="title">
36 ${self.breadcrumbs()}
37 </div>
38
39
39 ##main
40 ##main
40 <div class='sidebar-col-wrapper'>
41 <div class='sidebar-col-wrapper'>
@@ -6,18 +6,24 b''
6 % if c.exception_list_count == 1:
6 % if c.exception_list_count == 1:
7 ${_('There is {} stored exception.').format(c.exception_list_count)}
7 ${_('There is {} stored exception.').format(c.exception_list_count)}
8 % else:
8 % else:
9 ${_('There are {} stored exceptions.').format(c.exception_list_count)}
9 ${_('There are total {} stored exceptions.').format(c.exception_list_count)}
10 % endif
10 % endif
11 <br/>
11 ${_('Store directory')}: ${c.exception_store_dir}
12 ${_('Store directory')}: ${c.exception_store_dir}
12
13
13 ${h.secure_form(h.route_path('admin_settings_exception_tracker_delete_all'), request=request)}
14 ${h.secure_form(h.route_path('admin_settings_exception_tracker_delete_all'), request=request)}
14 <div style="margin: 0 0 20px 0" class="fake-space"></div>
15 <div style="margin: 0 0 20px 0" class="fake-space"></div>
15
16 <input type="hidden" name="type_filter", value="${c.type_filter}">
16 <div class="field">
17 <div class="field">
17 <button class="btn btn-small btn-danger" type="submit"
18 <button class="btn btn-small btn-danger" type="submit"
18 onclick="return confirm('${_('Confirm to delete all exceptions')}');">
19 onclick="return confirm('${_('Confirm to delete all exceptions')}');">
19 <i class="icon-remove-sign"></i>
20 <i class="icon-remove-sign"></i>
21 % if c.type_filter:
22 ${_('Delete All `{}`').format(c.type_filter)}
23 % else:
20 ${_('Delete All')}
24 ${_('Delete All')}
25 % endif
26
21 </button>
27 </button>
22 </div>
28 </div>
23
29
@@ -48,7 +54,9 b''
48 <td><a href="${h.route_path('admin_settings_exception_tracker_show', exception_id=tb['exc_id'])}"><code>${tb['exc_id']}</code></a></td>
54 <td><a href="${h.route_path('admin_settings_exception_tracker_show', exception_id=tb['exc_id'])}"><code>${tb['exc_id']}</code></a></td>
49 <td>${h.format_date(tb['exc_utc_date'])}</td>
55 <td>${h.format_date(tb['exc_utc_date'])}</td>
50 <td>${tb['app_type']}</td>
56 <td>${tb['app_type']}</td>
51 <td>${tb['exc_type']}</td>
57 <td>
58 <a href="${h.current_route_path(request, type_filter=tb['exc_type'])}">${tb['exc_type']}</a>
59 </td>
52 </tr>
60 </tr>
53 <% cnt -=1 %>
61 <% cnt -=1 %>
54 % endfor
62 % endfor
@@ -19,13 +19,12 b''
19 ${self.menu_items(active='admin')}
19 ${self.menu_items(active='admin')}
20 </%def>
20 </%def>
21
21
22 <%def name="menu_bar_subnav()">
23 ${self.admin_menu(active='user_groups')}
24 </%def>
25
22 <%def name="main()">
26 <%def name="main()">
23 <div class="box main-content">
27 <div class="box main-content">
24 <!-- box / title -->
25 <div class="title">
26 ${self.breadcrumbs()}
27 </div>
28 <!-- end box / title -->
29 ${h.secure_form(h.route_path('user_groups_create'), request=request)}
28 ${h.secure_form(h.route_path('user_groups_create'), request=request)}
30 <div class="form">
29 <div class="form">
31 <!-- fields -->
30 <!-- fields -->
@@ -20,11 +20,12 b''
20 ${self.menu_items(active='admin')}
20 ${self.menu_items(active='admin')}
21 </%def>
21 </%def>
22
22
23 <%def name="menu_bar_subnav()">
24 ${self.admin_menu(active='user_groups')}
25 </%def>
26
23 <%def name="main()">
27 <%def name="main()">
24 <div class="box">
28 <div class="box">
25 <div class="title">
26 ${self.breadcrumbs()}
27 </div>
28
29
29 ##main
30 ##main
30 <div class="sidebar-col-wrapper">
31 <div class="sidebar-col-wrapper">
@@ -143,7 +143,7 b''
143 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td>
143 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td>
144 <td class="td-user">
144 <td class="td-user">
145 <i class="icon-user-group"></i>
145 <i class="icon-user-group"></i>
146 %if h.HasPermissionAny('hg.admin')():
146 %if c.is_super_admin:
147 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
147 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
148 ${_user_group.users_group_name}
148 ${_user_group.users_group_name}
149 </a>
149 </a>
@@ -8,22 +8,25 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="user_group_count">0</span>
14 </%def>
15
12
16 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='admin')}
14 ${self.menu_items(active='admin')}
18 </%def>
15 </%def>
19
16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='user_groups')}
19 </%def>
20
20 <%def name="main()">
21 <%def name="main()">
21 <div class="box">
22 <div class="box">
22
23
23 <div class="title">
24 <div class="title">
24 ${self.breadcrumbs()}
25 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
26 <span id="user_group_count">0</span>
27
25 <ul class="links">
28 <ul class="links">
26 %if h.HasPermissionAny('hg.admin', 'hg.usergroup.create.true')():
29 %if c.can_create_user_group:
27 <li>
30 <li>
28 <a href="${h.route_path('user_groups_new')}" class="btn btn-small btn-success">${_(u'Add User Group')}</a>
31 <a href="${h.route_path('user_groups_new')}" class="btn btn-small btn-success">${_(u'Add User Group')}</a>
29 </li>
32 </li>
@@ -102,7 +105,7 b''
102 // filter
105 // filter
103 $('#q_filter').on('keyup',
106 $('#q_filter').on('keyup',
104 $.debounce(250, function() {
107 $.debounce(250, function() {
105 $('#user_group_list_table').DataTable().search(
108 $userGroupsListTable.DataTable().search(
106 $('#q_filter').val()
109 $('#q_filter').val()
107 ).draw();
110 ).draw();
108 })
111 })
@@ -13,23 +13,24 b''
13 &raquo;
13 &raquo;
14 ${h.link_to(_('Users'),h.route_path('users'))}
14 ${h.link_to(_('Users'),h.route_path('users'))}
15 &raquo;
15 &raquo;
16 % if c.user.active:
17 ${c.user.username}
18 % else:
19 <strike title="${_('This user is set as disabled')}">${c.user.username}</strike>
20 % endif
21
22 </%def>
16 </%def>
23
17
24 <%def name="menu_bar_nav()">
18 <%def name="menu_bar_nav()">
25 ${self.menu_items(active='admin')}
19 ${self.menu_items(active='admin')}
26 </%def>
20 </%def>
27
21
22 <%def name="menu_bar_subnav()">
23 ${self.admin_menu(active='users')}
24 </%def>
25
26
28 <%def name="main()">
27 <%def name="main()">
29 <div class="box user_settings">
28 <div class="box user_settings">
30 <div class="title">
29 % if not c.user.active:
31 ${self.breadcrumbs()}
30 <div class="alert alert-warning text-center">
31 <strong>${_('This user is set as disabled')}</strong>
32 </div>
32 </div>
33 % endif
33
34
34 ##main
35 ##main
35 <div class="sidebar-col-wrapper">
36 <div class="sidebar-col-wrapper">
@@ -81,7 +81,7 b''
81 </div>
81 </div>
82 %endif
82 %endif
83 <button class="btn btn-default" type="submit" ${'disabled="disabled"' if c.personal_repo_group else ''}>
83 <button class="btn btn-default" type="submit" ${'disabled="disabled"' if c.personal_repo_group else ''}>
84 <i class="icon-folder-close"></i>
84 <i class="icon-repo-group"></i>
85 ${_('Create personal repository group')}
85 ${_('Create personal repository group')}
86 </button>
86 </button>
87 ${h.end_form()}
87 ${h.end_form()}
@@ -61,9 +61,9 b''
61 </div>
61 </div>
62 <div class="input">
62 <div class="input">
63 ${h.text('new_ip')} ${h.text('description', placeholder=_('Description...'))}
63 ${h.text('new_ip')} ${h.text('description', placeholder=_('Description...'))}
64 <span class="help-block">${_('Enter comma separated list of ip addresses like 127.0.0.1,\n'
64 <span class="help-block pre-formatting">${_('Enter comma separated list of ip addresses like 10.0.0.1,10.0.0.2.\n'
65 'or use a ip address with a mask 127.0.0.1/24, to create a network range.\n'
65 'Use a ip address with a mask 127.0.0.1/24, to create a network match pattern.\n'
66 'To specify multiple address range use 127.0.0.1-127.0.0.10 syntax')}</span>
66 'To specify multiple entries on an address range use 127.0.0.1-127.0.0.10 syntax')}</span>
67 </div>
67 </div>
68 </div>
68 </div>
69 <div class="buttons">
69 <div class="buttons">
@@ -29,8 +29,7 b''
29 ${base.gravatar(c.user.email, 100)}
29 ${base.gravatar(c.user.email, 100)}
30 <p class="help-block">${_('Change the avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
30 <p class="help-block">${_('Change the avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
31 %else:
31 %else:
32 ${base.gravatar(c.user.email, 20)}
32 ${base.gravatar(c.user.email, 100)}
33 ${_('Avatars are disabled')}
34 %endif
33 %endif
35 </div>
34 </div>
36 </div>
35 </div>
@@ -8,21 +8,24 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="user_count">0</span>
14 </%def>
15
12
16 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='admin')}
14 ${self.menu_items(active='admin')}
18 </%def>
15 </%def>
19
16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='users')}
19 </%def>
20
20 <%def name="main()">
21 <%def name="main()">
21
22
22 <div class="box">
23 <div class="box">
23
24
24 <div class="title">
25 <div class="title">
25 ${self.breadcrumbs()}
26 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
27 <span id="user_count">0</span>
28
26 <ul class="links">
29 <ul class="links">
27 <li>
30 <li>
28 <a href="${h.route_path('users_new')}" class="btn btn-small btn-success">${_(u'Add User')}</a>
31 <a href="${h.route_path('users_new')}" class="btn btn-small btn-success">${_(u'Add User')}</a>
@@ -9,10 +9,12 b''
9 <div id="header-inner" class="wrapper">
9 <div id="header-inner" class="wrapper">
10 <div id="logo">
10 <div id="logo">
11 <div class="logo-wrapper">
11 <div class="logo-wrapper">
12 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a>
12 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
13 </div>
13 </div>
14 %if c.rhodecode_name:
14 % if c.rhodecode_name:
15 <div class="branding">- ${h.branding(c.rhodecode_name)}</div>
15 <div class="branding">
16 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
17 </div>
16 %endif
18 % endif
17 </div>
19 </div>
18 <!-- MENU BAR NAV -->
20 <!-- MENU BAR NAV -->
@@ -72,22 +74,67 b''
72 </div>
74 </div>
73 </%def>
75 </%def>
74
76
75 <%def name="admin_menu()">
77 <%def name="admin_menu(active=None)">
76 <ul class="admin_menu submenu">
78 <%
77 <li><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
79 def is_active(selected):
78 <li><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
80 if selected == active:
79 <li><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
81 return "active"
80 <li><a href="${h.route_path('users')}">${_('Users')}</a></li>
82 %>
81 <li><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
83
82 <li><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
84 <div id="context-bar">
83 <li><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
85 <div class="wrapper">
84 <li><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
86 <div class="title">
85 <li><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
87 <div class="title-content">
86 <li class="last"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
88 <div class="title-main">
89 % if c.is_super_admin:
90 ${_('Super Admin Panel')}
91 % else:
92 ${_('Delegated Admin Panel')}
93 % endif
94 </div>
95 </div>
96 </div>
97
98 <ul id="context-pages" class="navigation horizontal-list">
99
100 ## super admin case
101 % if c.is_super_admin:
102 <li class="${is_active('audit_logs')}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
103 <li class="${is_active('repositories')}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
104 <li class="${is_active('repository_groups')}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
105 <li class="${is_active('users')}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
106 <li class="${is_active('user_groups')}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
107 <li class="${is_active('permissions')}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
108 <li class="${is_active('authentication')}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
109 <li class="${is_active('integrations')}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
110 <li class="${is_active('defaults')}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
111 <li class="${is_active('settings')}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
112
113 ## delegated admin
114 % elif c.is_delegated_admin:
115 <%
116 repositories=c.auth_user.repositories_admin or c.can_create_repo
117 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
118 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
119 %>
120
121 %if repositories:
122 <li class="${is_active('repositories')} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
123 %endif
124 %if repository_groups:
125 <li class="${is_active('repository_groups')} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
126 %endif
127 %if user_groups:
128 <li class="${is_active('user_groups')} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
129 %endif
130 % endif
87 </ul>
131 </ul>
132
133 </div>
134 <div class="clear"></div>
135 </div>
88 </%def>
136 </%def>
89
137
90
91 <%def name="dt_info_panel(elements)">
138 <%def name="dt_info_panel(elements)">
92 <dl class="dl-horizontal">
139 <dl class="dl-horizontal">
93 %for dt, dd, title, show_items in elements:
140 %for dt, dd, title, show_items in elements:
@@ -117,7 +164,6 b''
117 </dl>
164 </dl>
118 </%def>
165 </%def>
119
166
120
121 <%def name="gravatar(email, size=16)">
167 <%def name="gravatar(email, size=16)">
122 <%
168 <%
123 if (size > 16):
169 if (size > 16):
@@ -143,23 +189,9 b''
143 </%def>
189 </%def>
144
190
145
191
146 ## admin menu used for people that have some admin resources
192 <%def name="repo_page_title(repo_instance)">
147 <%def name="admin_menu_simple(repositories=None, repository_groups=None, user_groups=None)">
193 <div class="title-content repo-title">
148 <ul class="submenu">
149 %if repositories:
150 <li class="local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
151 %endif
152 %if repository_groups:
153 <li class="local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
154 %endif
155 %if user_groups:
156 <li class="local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
157 %endif
158 </ul>
159 </%def>
160
194
161 <%def name="repo_page_title(repo_instance)">
162 <div class="title-content">
163 <div class="title-main">
195 <div class="title-main">
164 ## SVN/HG/GIT icons
196 ## SVN/HG/GIT icons
165 %if h.is_hg(repo_instance):
197 %if h.is_hg(repo_instance):
@@ -182,11 +214,29 b''
182 ## repo name with group name
214 ## repo name with group name
183 ${h.breadcrumb_repo_link(repo_instance)}
215 ${h.breadcrumb_repo_link(repo_instance)}
184
216
217 ## Context Actions
218 <div class="pull-right">
219 %if c.rhodecode_user.username != h.DEFAULT_USER:
220 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_name, _query=dict(auth_token=c.rhodecode_user.feed_token))}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
221
222 <a href="#WatchRepo" onclick="toggleFollowingRepo(this, templateContext.repo_id); return false" title="${_('Watch this Repository and actions on it in your personalized journal')}" class="btn btn-sm ${('watching' if c.repository_is_user_following else '')}">
223 % if c.repository_is_user_following:
224 <i class="icon-eye-off"></i>${_('Unwatch')}
225 % else:
226 <i class="icon-eye"></i>${_('Watch')}
227 % endif
228
229 </a>
230 %else:
231 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_name)}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
232 %endif
233 </div>
234
185 </div>
235 </div>
186
236
187 ## FORKED
237 ## FORKED
188 %if repo_instance.fork:
238 %if repo_instance.fork:
189 <p>
239 <p class="discreet">
190 <i class="icon-code-fork"></i> ${_('Fork of')}
240 <i class="icon-code-fork"></i> ${_('Fork of')}
191 ${h.link_to_if(c.has_origin_repo_read_perm,repo_instance.fork.repo_name, h.route_path('repo_summary', repo_name=repo_instance.fork.repo_name))}
241 ${h.link_to_if(c.has_origin_repo_read_perm,repo_instance.fork.repo_name, h.route_path('repo_summary', repo_name=repo_instance.fork.repo_name))}
192 </p>
242 </p>
@@ -194,7 +244,7 b''
194
244
195 ## IMPORTED FROM REMOTE
245 ## IMPORTED FROM REMOTE
196 %if repo_instance.clone_uri:
246 %if repo_instance.clone_uri:
197 <p>
247 <p class="discreet">
198 <i class="icon-code-fork"></i> ${_('Clone from')}
248 <i class="icon-code-fork"></i> ${_('Clone from')}
199 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
249 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
200 </p>
250 </p>
@@ -202,12 +252,12 b''
202
252
203 ## LOCKING STATUS
253 ## LOCKING STATUS
204 %if repo_instance.locked[0]:
254 %if repo_instance.locked[0]:
205 <p class="locking_locked">
255 <p class="locking_locked discreet">
206 <i class="icon-repo-lock"></i>
256 <i class="icon-repo-lock"></i>
207 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
257 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
208 </p>
258 </p>
209 %elif repo_instance.enable_locking:
259 %elif repo_instance.enable_locking:
210 <p class="locking_unlocked">
260 <p class="locking_unlocked discreet">
211 <i class="icon-repo-unlock"></i>
261 <i class="icon-repo-unlock"></i>
212 ${_('Repository not locked. Pull repository to lock it.')}
262 ${_('Repository not locked. Pull repository to lock it.')}
213 </p>
263 </p>
@@ -222,78 +272,81 b''
222 if selected == active:
272 if selected == active:
223 return "active"
273 return "active"
224 %>
274 %>
275 % if c.rhodecode_db_repo.archived:
276 <div class="alert alert-warning text-center">
277 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
278 </div>
279 % endif
225
280
226 <!--- CONTEXT BAR -->
281 <!--- REPO CONTEXT BAR -->
227 <div id="context-bar">
282 <div id="context-bar">
228 <div class="wrapper">
283 <div class="wrapper">
284
285 <div class="title">
286 ${self.repo_page_title(c.rhodecode_db_repo)}
287 </div>
288
229 <ul id="context-pages" class="navigation horizontal-list">
289 <ul id="context-pages" class="navigation horizontal-list">
230 <li class="${is_active('summary')}"><a class="menulink" href="${h.route_path('repo_summary', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
290 <li class="${is_active('summary')}"><a class="menulink" href="${h.route_path('repo_summary', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
231 <li class="${is_active('changelog')}"><a class="menulink" href="${h.route_path('repo_changelog', repo_name=c.repo_name)}"><div class="menulabel">${_('Changelog')}</div></a></li>
291 <li class="${is_active('commits')}"><a class="menulink" href="${h.route_path('repo_commits', repo_name=c.repo_name)}"><div class="menulabel">${_('Commits')}</div></a></li>
232 <li class="${is_active('files')}"><a class="menulink" href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.rhodecode_db_repo.landing_rev[1], f_path='')}"><div class="menulabel">${_('Files')}</div></a></li>
292 <li class="${is_active('files')}"><a class="menulink" href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.rhodecode_db_repo.landing_rev[1], f_path='')}"><div class="menulabel">${_('Files')}</div></a></li>
233 <li class="${is_active('compare')}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
293 <li class="${is_active('compare')}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
234 <li class="${is_active('search')}"><a class="menulink" href="${h.route_path('search_repo',repo_name=c.repo_name)}"><div class="menulabel">${_('Search')}</div></a></li>
235
294
236 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
295 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
237 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
296 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
238 <li class="${is_active('showpullrequest')}">
297 <li class="${is_active('showpullrequest')}">
239 <a class="menulink" href="${h.route_path('pullrequest_show_all', repo_name=c.repo_name)}" title="${h.tooltip(_('Show Pull Requests for %s') % c.repo_name)}">
298 <a class="menulink" href="${h.route_path('pullrequest_show_all', repo_name=c.repo_name)}" title="${h.tooltip(_('Show Pull Requests for %s') % c.repo_name)}">
240 %if c.repository_pull_requests:
299 <div class="menulabel">
241 <span class="pr_notifications">${c.repository_pull_requests}</span>
300 %if c.repository_pull_requests == 1:
301 ${_('Pull Request')} ${c.repository_pull_requests}
302 %else:
303 ${_('Pull Requests')} ${c.repository_pull_requests}
242 %endif
304 %endif
243 <div class="menulabel">${_('Pull Requests')}</div>
305 </div>
244 </a>
306 </a>
245 </li>
307 </li>
246 %endif
308 %endif
247
309
310 <li class="${is_active('artifacts')}"><a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}"><div class="menulabel">${_('Artifacts')} (BETA)</div></a></li>
311
312 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
313 <li class="${is_active('settings')}"><a class="menulink" href="${h.route_path('edit_repo',repo_name=c.repo_name)}"><div class="menulabel">${_('Repository Settings')}</div></a></li>
314 %endif
315
316 ## determine if we have "any" option available
317 <%
318 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
319 has_actions = (c.rhodecode_user.username != h.DEFAULT_USER and c.rhodecode_db_repo.repo_type in ['git','hg'] ) or can_lock
320 %>
248 <li class="${is_active('options')}">
321 <li class="${is_active('options')}">
322 % if has_actions:
249 <a class="menulink dropdown">
323 <a class="menulink dropdown">
250 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
324 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
251 </a>
325 </a>
252 <ul class="submenu">
326 <ul class="submenu">
253 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
327 <li><a href="${h.route_path('repo_fork_new',repo_name=c.repo_name)}">${_('Fork this repository')}</a></li>
254 <li><a href="${h.route_path('edit_repo',repo_name=c.repo_name)}">${_('Repository Settings')}</a></li>
328 <li><a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a></li>
255 %endif
329 %if can_lock:
256 %if c.rhodecode_db_repo.fork:
257 <li>
258 <a title="${h.tooltip(_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name))}"
259 href="${h.route_path('repo_compare',
260 repo_name=c.rhodecode_db_repo.fork.repo_name,
261 source_ref_type=c.rhodecode_db_repo.landing_rev[0],
262 source_ref=c.rhodecode_db_repo.landing_rev[1],
263 target_repo=c.repo_name,target_ref_type='branch' if request.GET.get('branch') else c.rhodecode_db_repo.landing_rev[0],
264 target_ref=request.GET.get('branch') or c.rhodecode_db_repo.landing_rev[1],
265 _query=dict(merge=1))}"
266 >
267 ${_('Compare fork')}
268 </a>
269 </li>
270 %endif
271
272 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
273 %if c.rhodecode_db_repo.locked[0]:
330 %if c.rhodecode_db_repo.locked[0]:
274 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock')}</a></li>
331 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
275 %else:
332 %else:
276 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock')}</a></li>
333 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
277 %endif
278 %endif
279 %if c.rhodecode_user.username != h.DEFAULT_USER:
280 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
281 <li><a href="${h.route_path('repo_fork_new',repo_name=c.repo_name)}">${_('Fork')}</a></li>
282 <li><a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a></li>
283 %endif
334 %endif
284 %endif
335 %endif
285 </ul>
336 </ul>
337 % else:
338 <a class="menulink disabled">
339 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
340 </a>
341 % endif
286 </li>
342 </li>
343
287 </ul>
344 </ul>
288 </div>
345 </div>
289 <div class="clear"></div>
346 <div class="clear"></div>
290 </div>
347 </div>
291 % if c.rhodecode_db_repo.archived:
348
292 <div class="alert alert-warning text-center">
349 <!--- REPO END CONTEXT BAR -->
293 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
294 </div>
295 % endif
296 <!--- END CONTEXT BAR -->
297
350
298 </%def>
351 </%def>
299
352
@@ -301,14 +354,14 b''
301 <div class="title-content">
354 <div class="title-content">
302 <div class="title-main">
355 <div class="title-main">
303 ## Repository Group icon
356 ## Repository Group icon
304 <i class="icon-folder-close"></i>
357 <i class="icon-repo-group"></i>
305
358
306 ## repo name with group name
359 ## repo name with group name
307 ${h.breadcrumb_repo_group_link(repo_group_instance)}
360 ${h.breadcrumb_repo_group_link(repo_group_instance)}
308 </div>
361 </div>
309
362
310 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
363 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
311 <div class="repo-group-desc">
364 <div class="repo-group-desc discreet">
312 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
365 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
313 </div>
366 </div>
314
367
@@ -321,8 +374,6 b''
321 if selected == active:
374 if selected == active:
322 return "active"
375 return "active"
323
376
324 is_admin = h.HasPermissionAny('hg.admin')('can create repos index page')
325
326 gr_name = c.repo_group.group_name if c.repo_group else None
377 gr_name = c.repo_group.group_name if c.repo_group else None
327 # create repositories with write permission on group is set to true
378 # create repositories with write permission on group is set to true
328 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
379 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
@@ -331,35 +382,49 b''
331
382
332 %>
383 %>
333
384
334 <!--- CONTEXT BAR -->
385 <!--- REPO GROUP CONTEXT BAR -->
335 <div id="context-bar">
386 <div id="context-bar">
336 <div class="wrapper">
387 <div class="wrapper">
388 <div class="title">
389 ${self.repo_group_page_title(c.repo_group)}
390 </div>
391
337 <ul id="context-pages" class="navigation horizontal-list">
392 <ul id="context-pages" class="navigation horizontal-list">
338 <li class="${is_active('home')}"><a class="menulink" href="${h.route_path('repo_group_home', repo_group_name=c.repo_group.group_name)}"><div class="menulabel">${_('Group Home')}</div></a></li>
393 <li class="${is_active('home')}"><a class="menulink" href="${h.route_path('repo_group_home', repo_group_name=c.repo_group.group_name)}"><div class="menulabel">${_('Group Home')}</div></a></li>
339 <li class="${is_active('search')}"><a class="menulink" href="${h.route_path('search_repo_group', repo_group_name=c.repo_group.group_name)}"><div class="menulabel">${_('Search')}</div></a></li>
394 % if c.is_super_admin or group_admin:
340
395 <li class="${is_active('settings')}"><a class="menulink" href="${h.route_path('edit_repo_group',repo_group_name=c.repo_group.group_name)}" title="${_('You have admin right to this group, and can edit it')}"><div class="menulabel">${_('Group Settings')}</div></a></li>
396 % endif
397 ## determine if we have "any" option available
398 <%
399 can_create_repos = c.is_super_admin or group_admin or (group_write and create_on_write)
400 can_create_repo_groups = c.is_super_admin or group_admin
401 has_actions = can_create_repos or can_create_repo_groups
402 %>
341 <li class="${is_active('options')}">
403 <li class="${is_active('options')}">
404 % if has_actions:
342 <a class="menulink dropdown">
405 <a class="menulink dropdown">
343 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
406 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
344 </a>
407 </a>
345 <ul class="submenu">
408 <ul class="submenu">
346 %if is_admin or group_admin:
409 %if can_create_repos:
347 <li><a href="${h.route_path('edit_repo_group',repo_group_name=c.repo_group.group_name)}" title="${_('You have admin right to this group, and can edit it')}">${_('Group Settings')}</a></li>
348 %endif
349 %if is_admin or group_admin or (group_write and create_on_write):
350 <li><a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('Add Repository')}</a></li>
410 <li><a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('Add Repository')}</a></li>
351 %endif
411 %endif
352 %if is_admin or group_admin:
412 %if can_create_repo_groups:
353 <li><a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'Add Parent Group')}</a></li>
413 <li><a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'Add Repository Group')}</a></li>
354 %endif
414 %endif
355 </ul>
415 </ul>
416 % else:
417 <a class="menulink disabled">
418 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
419 </a>
420 % endif
356 </li>
421 </li>
357 </ul>
422 </ul>
358 </div>
423 </div>
359 <div class="clear"></div>
424 <div class="clear"></div>
360 </div>
425 </div>
361
426
362 <!--- END CONTEXT BAR -->
427 <!--- REPO GROUP CONTEXT BAR -->
363
428
364 </%def>
429 </%def>
365
430
@@ -431,7 +496,7 b''
431 <div>
496 <div>
432 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
497 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
433 <code>${item.position}</code>
498 <code>${item.position}</code>
434 <i class="icon-folder-close" title="${_('Repository group')}" style="font-size: 16px"></i>
499 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
435 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
500 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
436 </a>
501 </a>
437 </div>
502 </div>
@@ -484,10 +549,35 b''
484 <li>
549 <li>
485 <div class="menulabel main_filter_box">
550 <div class="menulabel main_filter_box">
486 <div class="main_filter_input_box">
551 <div class="main_filter_input_box">
487 <input class="main_filter_input" id="main_filter" size="15" type="text" name="main_filter" placeholder="${_('search / go to...')}" value=""/>
552 <ul class="searchItems">
488 </div>
553
489 <div class="main_filter_help_box">
554 % if c.template_context['search_context']['repo_id']:
555 <li class="searchTag searchTagFilter searchTagHidable" >
556 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
557 <span class="tag">
558 This repo
559 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
560 </span>
561 ##</a>
562 </li>
563 % elif c.template_context['search_context']['repo_group_id']:
564 <li class="searchTag searchTagFilter searchTagHidable">
565 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
566 <span class="tag">
567 This group
568 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
569 </span>
570 ##</a>
571 </li>
572 % endif
573
574 <li class="searchTagInput">
575 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
576 </li>
577 <li class="searchTag searchTagHelp">
490 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
578 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
579 </li>
580 </ul>
491 </div>
581 </div>
492 </div>
582 </div>
493
583
@@ -498,15 +588,31 b''
498
588
499 - Prefix query to allow special search:
589 - Prefix query to allow special search:
500
590
501 user:admin, to search for usernames
591 user:admin, to search for usernames, always global
592
593 user_group:devops, to search for user groups, always global
594
595 commit:efced4, to search for commits, scoped to repositories or groups
596
597 file:models.py, to search for file paths, scoped to repositories or groups
502
598
503 user_group:devops, to search for user groups
599 % if c.template_context['search_context']['repo_id']:
504
600 For advanced full text search visit: <a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">repository search</a>
505 commit:efced4, to search for commits
601 % elif c.template_context['search_context']['repo_group_id']:
602 For advanced full text search visit: <a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">repository group search</a>
603 % else:
604 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
605 % endif
506 </div>
606 </div>
507 </li>
607 </li>
508
608
509 ## ROOT MENU
609 ## ROOT MENU
610 <li class="${is_active('home')}">
611 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
612 <div class="menulabel">${_('Home')}</div>
613 </a>
614 </li>
615
510 %if c.rhodecode_user.username != h.DEFAULT_USER:
616 %if c.rhodecode_user.username != h.DEFAULT_USER:
511 <li class="${is_active('journal')}">
617 <li class="${is_active('journal')}">
512 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
618 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
@@ -520,33 +626,21 b''
520 </a>
626 </a>
521 </li>
627 </li>
522 %endif
628 %endif
629
523 <li class="${is_active('gists')}">
630 <li class="${is_active('gists')}">
524 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
631 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
525 <div class="menulabel">${_('Gists')}</div>
632 <div class="menulabel">${_('Gists')}</div>
526 </a>
633 </a>
527 </li>
634 </li>
528 <li class="${is_active('search')}">
635
529 <a class="menulink" title="${_('Search in repositories you have access to')}" href="${h.route_path('search')}">
636 % if c.is_super_admin or c.is_delegated_admin:
530 <div class="menulabel">${_('Search')}</div>
637 <li class="${is_active('admin')}">
638 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
639 <div class="menulabel">${_('Admin')} </div>
531 </a>
640 </a>
532 </li>
641 </li>
533 % if h.HasPermissionAll('hg.admin')('access admin main page'):
534 <li class="${is_active('admin')}">
535 <a class="menulink childs" title="${_('Admin settings')}" href="#" onclick="return false;">
536 <div class="menulabel">${_('Admin')} <div class="show_more"></div></div>
537 </a>
538 ${admin_menu()}
539 </li>
540 % elif c.rhodecode_user.repositories_admin or c.rhodecode_user.repository_groups_admin or c.rhodecode_user.user_groups_admin:
541 <li class="${is_active('admin')}">
542 <a class="menulink childs" title="${_('Delegated Admin settings')}">
543 <div class="menulabel">${_('Admin')} <div class="show_more"></div></div>
544 </a>
545 ${admin_menu_simple(c.rhodecode_user.repositories_admin,
546 c.rhodecode_user.repository_groups_admin,
547 c.rhodecode_user.user_groups_admin or h.HasPermissionAny('hg.usergroup.create.true')())}
548 </li>
549 % endif
642 % endif
643
550 ## render extra user menu
644 ## render extra user menu
551 ${usermenu(active=(active=='my_account'))}
645 ${usermenu(active=(active=='my_account'))}
552
646
@@ -606,7 +700,7 b''
606
700
607 if(data){
701 if(data){
608
702
609 tmpl += '<i class="icon-folder-close"></i> ';
703 tmpl += '<i class="icon-repo-group"></i> ';
610
704
611 }
705 }
612 tmpl += escapeMarkup(repoGroupName);
706 tmpl += escapeMarkup(repoGroupName);
@@ -615,20 +709,9 b''
615 }(result, escapeMarkup);
709 }(result, escapeMarkup);
616 };
710 };
617
711
618
619 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
620
621 if (value.split(':').length === 2) {
622 value = value.split(':')[1]
623 }
624
625 var searchType = data['type'];
626 var valueDisplay = data['value_display'];
627
628 var escapeRegExChars = function (value) {
712 var escapeRegExChars = function (value) {
629 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
713 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
630 };
714 };
631 var pattern = '(' + escapeRegExChars(value) + ')';
632
715
633 var getRepoIcon = function(repo_type) {
716 var getRepoIcon = function(repo_type) {
634 if (repo_type === 'hg') {
717 if (repo_type === 'hg') {
@@ -643,18 +726,39 b''
643 return ''
726 return ''
644 };
727 };
645
728
646 // highlight match
729 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
730
731 if (value.split(':').length === 2) {
732 value = value.split(':')[1]
733 }
734
735 var searchType = data['type'];
736 var searchSubType = data['subtype'];
737 var valueDisplay = data['value_display'];
738
739 var pattern = '(' + escapeRegExChars(value) + ')';
740
647 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
741 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
742
743 // highlight match
744 if (searchType != 'text') {
648 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
745 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
746 }
649
747
650 var icon = '';
748 var icon = '';
651
749
652 if (searchType === 'hint') {
750 if (searchType === 'hint') {
653 icon += '<i class="icon-folder-close"></i> ';
751 icon += '<i class="icon-repo-group"></i> ';
654 }
752 }
655 // full text search
753 // full text search/hints
656 else if (searchType === 'search') {
754 else if (searchType === 'search') {
657 icon += '<i class="icon-more"></i> ';
755 icon += '<i class="icon-more"></i> ';
756 if (searchSubType !== undefined && searchSubType == 'repo') {
757 valueDisplay += '<div class="pull-right tag">repository</div>';
758 }
759 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
760 valueDisplay += '<div class="pull-right tag">repo group</div>';
761 }
658 }
762 }
659 // repository
763 // repository
660 else if (searchType === 'repo') {
764 else if (searchType === 'repo') {
@@ -671,12 +775,13 b''
671 }
775 }
672 // repository groups
776 // repository groups
673 else if (searchType === 'repo_group') {
777 else if (searchType === 'repo_group') {
674 icon += '<i class="icon-folder-close"></i> ';
778 icon += '<i class="icon-repo-group"></i> ';
675 }
779 }
676 // user group
780 // user group
677 else if (searchType === 'user_group') {
781 else if (searchType === 'user_group') {
678 icon += '<i class="icon-group"></i> ';
782 icon += '<i class="icon-group"></i> ';
679 }
783 }
784 // user
680 else if (searchType === 'user') {
785 else if (searchType === 'user') {
681 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
786 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
682 }
787 }
@@ -690,6 +795,20 b''
690 icon += '<i class="icon-tag"></i>';
795 icon += '<i class="icon-tag"></i>';
691 }
796 }
692 }
797 }
798 // file
799 else if (searchType === 'file') {
800 var repo_data = data['repo_data'];
801 var repoIcon = getRepoIcon(repo_data['repository_type']);
802 if (repoIcon) {
803 icon += repoIcon;
804 } else {
805 icon += '<i class="icon-tag"></i>';
806 }
807 }
808 // generic text
809 else if (searchType === 'text') {
810 icon = '';
811 }
693
812
694 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
813 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
695 return tmpl.format(icon, valueDisplay);
814 return tmpl.format(icon, valueDisplay);
@@ -699,25 +818,53 b''
699 if (suggestion.type === "hint") {
818 if (suggestion.type === "hint") {
700 // we skip action
819 // we skip action
701 $('#main_filter').focus();
820 $('#main_filter').focus();
821 }
822 else if (suggestion.type === "text") {
823 // we skip action
824 $('#main_filter').focus();
825
702 } else {
826 } else {
703 window.location = suggestion['url'];
827 window.location = suggestion['url'];
704 }
828 }
705 };
829 };
830
706 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
831 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
707 if (queryLowerCase.split(':').length === 2) {
832 if (queryLowerCase.split(':').length === 2) {
708 queryLowerCase = queryLowerCase.split(':')[1]
833 queryLowerCase = queryLowerCase.split(':')[1]
709 }
834 }
835 if (suggestion.type === "text") {
836 // special case we don't want to "skip" display for
837 return true
838 }
710 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
839 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
711 };
840 };
712
841
842 var cleanContext = {
843 repo_view_type: null,
844
845 repo_id: null,
846 repo_name: "",
847
848 repo_group_id: null,
849 repo_group_name: null
850 };
851 var removeGoToFilter = function () {
852 $('.searchTagHidable').hide();
853 $('#main_filter').autocomplete(
854 'setOptions', {params:{search_context: cleanContext}});
855 };
856
713 $('#main_filter').autocomplete({
857 $('#main_filter').autocomplete({
714 serviceUrl: pyroutes.url('goto_switcher_data'),
858 serviceUrl: pyroutes.url('goto_switcher_data'),
715 params: {"search_context": templateContext.search_context},
859 params: {
860 "search_context": templateContext.search_context
861 },
716 minChars:2,
862 minChars:2,
717 maxHeight:400,
863 maxHeight:400,
718 deferRequestBy: 300, //miliseconds
864 deferRequestBy: 300, //miliseconds
719 tabDisabled: true,
865 tabDisabled: true,
720 autoSelectFirst: true,
866 autoSelectFirst: false,
867 containerClass: 'autocomplete-qfilter-suggestions',
721 formatResult: autocompleteMainFilterFormatResult,
868 formatResult: autocompleteMainFilterFormatResult,
722 lookupFilter: autocompleteMainFilterResult,
869 lookupFilter: autocompleteMainFilterResult,
723 onSelect: function (element, suggestion) {
870 onSelect: function (element, suggestion) {
@@ -736,6 +883,18 b''
736 $('#main_filter_help').toggle();
883 $('#main_filter_help').toggle();
737 };
884 };
738
885
886 $('#main_filter').on('keydown.autocomplete', function (e) {
887
888 var BACKSPACE = 8;
889 var el = $(e.currentTarget);
890 if(e.which === BACKSPACE){
891 var inputVal = el.val();
892 if (inputVal === ""){
893 removeGoToFilter()
894 }
895 }
896 });
897
739 </script>
898 </script>
740 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
899 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
741 </%def>
900 </%def>
@@ -7,7 +7,7 b" go_import_header = ''"
7 if hasattr(c, 'rhodecode_db_repo'):
7 if hasattr(c, 'rhodecode_db_repo'):
8 c.template_context['repo_type'] = c.rhodecode_db_repo.repo_type
8 c.template_context['repo_type'] = c.rhodecode_db_repo.repo_type
9 c.template_context['repo_landing_commit'] = c.rhodecode_db_repo.landing_rev[1]
9 c.template_context['repo_landing_commit'] = c.rhodecode_db_repo.landing_rev[1]
10 ## check repo context
10 c.template_context['repo_id'] = c.rhodecode_db_repo.repo_id
11 c.template_context['repo_view_type'] = h.get_repo_view_type(request)
11 c.template_context['repo_view_type'] = h.get_repo_view_type(request)
12
12
13 if getattr(c, 'repo_group', None):
13 if getattr(c, 'repo_group', None):
@@ -29,6 +29,7 b" c.template_context['default_user'] = {"
29 c.template_context['search_context'] = {
29 c.template_context['search_context'] = {
30 'repo_group_id': c.template_context.get('repo_group_id'),
30 'repo_group_id': c.template_context.get('repo_group_id'),
31 'repo_group_name': c.template_context.get('repo_group_name'),
31 'repo_group_name': c.template_context.get('repo_group_name'),
32 'repo_id': c.template_context.get('repo_id'),
32 'repo_name': c.template_context.get('repo_name'),
33 'repo_name': c.template_context.get('repo_name'),
33 'repo_view_type': c.template_context.get('repo_view_type'),
34 'repo_view_type': c.template_context.get('repo_view_type'),
34 }
35 }
@@ -133,13 +133,13 b''
133
133
134 <div class="checkbox">
134 <div class="checkbox">
135 ${h.checkbox('extensions_evolve' + suffix, 'True', **kwargs)}
135 ${h.checkbox('extensions_evolve' + suffix, 'True', **kwargs)}
136 <label for="extensions_evolve${suffix}">${_('Enable evolve extension')}</label>
136 <label for="extensions_evolve${suffix}">${_('Enable Evolve and Topic extension')}</label>
137 </div>
137 </div>
138 <div class="label">
138 <div class="label">
139 % if display_globals:
139 % if display_globals:
140 <span class="help-block">${_('Enable evolve extension for all repositories.')}</span>
140 <span class="help-block">${_('Enable Evolve and Topic extensions for all repositories.')}</span>
141 % else:
141 % else:
142 <span class="help-block">${_('Enable evolve extension for this repository.')}</span>
142 <span class="help-block">${_('Enable Evolve and Topic extensions for this repository.')}</span>
143 % endif
143 % endif
144 </div>
144 </div>
145
145
@@ -8,10 +8,7 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 <span id="obj_count">0</span> ${_('bookmarks')}
14 </%def>
15
12
16 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='repositories')}
14 ${self.menu_items(active='repositories')}
@@ -24,7 +21,7 b''
24 <%def name="main()">
21 <%def name="main()">
25 <div class="box">
22 <div class="box">
26 <div class="title">
23 <div class="title">
27 ${self.repo_page_title(c.rhodecode_db_repo)}
24
28 %if c.has_references:
25 %if c.has_references:
29 <ul class="links">
26 <ul class="links">
30 <li>
27 <li>
@@ -33,7 +30,8 b''
33 </ul>
30 </ul>
34 %endif
31 %endif
35 %if c.has_references:
32 %if c.has_references:
36 ${self.breadcrumbs()}
33 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
34 <span id="obj_count">0</span> ${_('bookmarks')}
37 %endif
35 %endif
38 </div>
36 </div>
39 <table id="obj_list_table" class="display"></table>
37 <table id="obj_list_table" class="display"></table>
@@ -8,10 +8,7 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 <span id="obj_count">0</span> ${_('branches')}
14 </%def>
15
12
16 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='repositories')}
14 ${self.menu_items(active='repositories')}
@@ -24,7 +21,7 b''
24 <%def name="main()">
21 <%def name="main()">
25 <div class="box">
22 <div class="box">
26 <div class="title">
23 <div class="title">
27 ${self.repo_page_title(c.rhodecode_db_repo)}
24
28 %if c.has_references:
25 %if c.has_references:
29 <ul class="links">
26 <ul class="links">
30 <li>
27 <li>
@@ -33,7 +30,8 b''
33 </ul>
30 </ul>
34 %endif
31 %endif
35 %if c.has_references:
32 %if c.has_references:
36 ${self.breadcrumbs()}
33 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
34 <span id="obj_count">0</span> ${_('branches')}
37 %endif
35 %endif
38 </div>
36 </div>
39 <table id="obj_list_table" class="display"></table>
37 <table id="obj_list_table" class="display"></table>
@@ -15,7 +15,7 b''
15 </%def>
15 </%def>
16
16
17 <%def name="menu_bar_subnav()">
17 <%def name="menu_bar_subnav()">
18 ${self.repo_menu(active='changelog')}
18 ${self.repo_menu(active='commits')}
19 </%def>
19 </%def>
20
20
21 <%def name="main()">
21 <%def name="main()">
@@ -25,17 +25,13 b''
25 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
25 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
26 </script>
26 </script>
27 <div class="box">
27 <div class="box">
28 <div class="title">
29 ${self.repo_page_title(c.rhodecode_db_repo)}
30 </div>
31
28
32 <div id="changeset_compare_view_content" class="summary changeset">
29 <div id="changeset_compare_view_content" class="summary changeset">
33 <div class="summary-detail">
30 <div class="summary-detail">
34 <div class="summary-detail-header">
31 <div class="fieldset">
35 <div class="breadcrumbs files_location">
32 <div class="left-label-summary">
36 <h4>
33 <p>${_('Commit')}</p>
37 ${_('Commit')}
34 <div class="right-label-summary">
38
39 <code>
35 <code>
40 ${h.show_id(c.commit)}
36 ${h.show_id(c.commit)}
41 </code>
37 </code>
@@ -57,9 +53,8 b''
57 <span class="tag hidden-${c.commit.hidden} tooltip" title="${_('Evolve State')}">${_('hidden')}</span>
53 <span class="tag hidden-${c.commit.hidden} tooltip" title="${_('Evolve State')}">${_('hidden')}</span>
58 % endif
54 % endif
59 % endif
55 % endif
60 </h4>
61
56
62 </div>
57
63 <div class="pull-right">
58 <div class="pull-right">
64 <span id="parent_link">
59 <span id="parent_link">
65 <a href="#parentCommit" title="${_('Parent Commit')}"><i class="icon-left icon-no-margin"></i>${_('parent')}</a>
60 <a href="#parentCommit" title="${_('Parent Commit')}"><i class="icon-left icon-no-margin"></i>${_('parent')}</a>
@@ -69,41 +64,44 b''
69 <a href="#childCommit" title="${_('Child Commit')}">${_('child')}<i class="icon-right icon-no-margin"></i></a>
64 <a href="#childCommit" title="${_('Child Commit')}">${_('child')}<i class="icon-right icon-no-margin"></i></a>
70 </span>
65 </span>
71 </div>
66 </div>
67
72 </div>
68 </div>
69 </div>
70 </div>
71
72
73
73
74 <div class="fieldset">
74 <div class="fieldset">
75 <div class="left-label">
75 <div class="left-label-summary">
76 ${_('Description')}:
76 <p>${_('Description')}:</p>
77 </div>
77 <div class="right-label-summary">
78 <div class="right-content">
79 <div id="trimmed_message_box" class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
78 <div id="trimmed_message_box" class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
80 <div id="message_expand" style="display:none;">
79 <div id="message_expand" style="display:none;">
81 ${_('Expand')}
80 ${_('Expand')}
82 </div>
81 </div>
83 </div>
82 </div>
84 </div>
83 </div>
84 </div>
85
85
86 %if c.statuses:
86 %if c.statuses:
87 <div class="fieldset">
87 <div class="fieldset">
88 <div class="left-label">
88 <div class="left-label-summary">
89 ${_('Commit status')}:
89 <p>${_('Commit status')}:</p>
90 </div>
90 <div class="right-label-summary">
91 <div class="right-content">
92 <div class="changeset-status-ico">
91 <div class="changeset-status-ico">
93 <div class="${'flag_status %s' % c.statuses[0]} pull-left"></div>
92 <div class="${'flag_status %s' % c.statuses[0]} pull-left"></div>
94 </div>
93 </div>
95 <div title="${_('Commit status')}" class="changeset-status-lbl">[${h.commit_status_lbl(c.statuses[0])}]</div>
94 <div title="${_('Commit status')}" class="changeset-status-lbl">[${h.commit_status_lbl(c.statuses[0])}]</div>
96 </div>
95 </div>
97 </div>
96 </div>
97 </div>
98 %endif
98 %endif
99
99
100 <div class="fieldset">
100 <div class="fieldset">
101 <div class="left-label">
101 <div class="left-label-summary">
102 ${_('References')}:
102 <p>${_('References')}:</p>
103 </div>
103 <div class="right-label-summary">
104 <div class="right-content">
105 <div class="tags">
104 <div class="tags">
106
107 %if c.commit.merge:
105 %if c.commit.merge:
108 <span class="mergetag tag">
106 <span class="mergetag tag">
109 <i class="icon-merge"></i>${_('merge')}
107 <i class="icon-merge"></i>${_('merge')}
@@ -132,12 +130,12 b''
132 </div>
130 </div>
133 </div>
131 </div>
134 </div>
132 </div>
133 </div>
135
134
136 <div class="fieldset">
135 <div class="fieldset">
137 <div class="left-label">
136 <div class="left-label-summary">
138 ${_('Diff options')}:
137 <p>${_('Diff options')}:</p>
139 </div>
138 <div class="right-label-summary">
140 <div class="right-content">
141 <div class="diff-actions">
139 <div class="diff-actions">
142 <a href="${h.route_path('repo_commit_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Raw diff'))}">
140 <a href="${h.route_path('repo_commit_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Raw diff'))}">
143 ${_('Raw Diff')}
141 ${_('Raw Diff')}
@@ -153,12 +151,12 b''
153 </div>
151 </div>
154 </div>
152 </div>
155 </div>
153 </div>
154 </div>
156
155
157 <div class="fieldset">
156 <div class="fieldset">
158 <div class="left-label">
157 <div class="left-label-summary">
159 ${_('Comments')}:
158 <p>${_('Comments')}:</p>
160 </div>
159 <div class="right-label-summary">
161 <div class="right-content">
162 <div class="comments-number">
160 <div class="comments-number">
163 %if c.comments:
161 %if c.comments:
164 <a href="#comments">${_ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}</a>,
162 <a href="#comments">${_ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}</a>,
@@ -173,12 +171,12 b''
173 </div>
171 </div>
174 </div>
172 </div>
175 </div>
173 </div>
174 </div>
176
175
177 <div class="fieldset">
176 <div class="fieldset">
178 <div class="left-label">
177 <div class="left-label-summary">
179 ${_('Unresolved TODOs')}:
178 <p>${_('Unresolved TODOs')}:</p>
180 </div>
179 <div class="right-label-summary">
181 <div class="right-content">
182 <div class="comments-number">
180 <div class="comments-number">
183 % if c.unresolved_comments:
181 % if c.unresolved_comments:
184 % for co in c.unresolved_comments:
182 % for co in c.unresolved_comments:
@@ -190,21 +188,23 b''
190 </div>
188 </div>
191 </div>
189 </div>
192 </div>
190 </div>
193
191 </div>
194 </div> <!-- end summary-detail -->
195
192
196 <div id="commit-stats" class="sidebar-right">
193 <div class="fieldset">
197 <div class="summary-detail-header">
194 <div class="left-label-summary">
198 <h4 class="item">
195 <p>${_('Author')}</p>
199 ${_('Author')}
196
200 </h4>
197 <div class="right-label-summary">
201 </div>
202 <div class="sidebar-right-content">
203 ${self.gravatar_with_user(c.commit.author)}
198 ${self.gravatar_with_user(c.commit.author)}
204 <div class="user-inline-data">- ${h.age_component(c.commit.date)}</div>
199 <div class="user-inline-data">- ${h.age_component(c.commit.date)}</div>
205 </div>
200 </div>
206 </div><!-- end sidebar -->
201 </div>
202
203 <div class="clear-fix"></div>
204
205 </div> <!-- end summary-detail -->
207 </div> <!-- end summary -->
206 </div> <!-- end summary -->
207 </div>
208 <div class="cs_files">
208 <div class="cs_files">
209 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
209 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
210 ${cbdiffs.render_diffset_menu(c.changes[c.commit.raw_id])}
210 ${cbdiffs.render_diffset_menu(c.changes[c.commit.raw_id])}
@@ -139,7 +139,7 b''
139 ## only super-admin, repo admin OR comment owner can delete, also hide delete if currently viewed comment is outdated
139 ## only super-admin, repo admin OR comment owner can delete, also hide delete if currently viewed comment is outdated
140 %if not outdated_at_ver and (not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed())):
140 %if not outdated_at_ver and (not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed())):
141 ## permissions to delete
141 ## permissions to delete
142 %if h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id:
142 %if c.is_super_admin or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id:
143 ## TODO: dan: add edit comment here
143 ## TODO: dan: add edit comment here
144 <a onclick="return Rhodecode.comments.deleteComment(this);" class="delete-comment"> ${_('Delete')}</a>
144 <a onclick="return Rhodecode.comments.deleteComment(this);" class="delete-comment"> ${_('Delete')}</a>
145 %else:
145 %else:
@@ -12,48 +12,54 b''
12 %endif
12 %endif
13 </%def>
13 </%def>
14
14
15 <%def name="breadcrumbs_links()">
15 <%def name="breadcrumbs_links()"></%def>
16 ${_('Commits')} -
17 r${c.commit_ranges[0].idx}:${h.short_id(c.commit_ranges[0].raw_id)}
18 ...
19 r${c.commit_ranges[-1].idx}:${h.short_id(c.commit_ranges[-1].raw_id)}
20 ${_ungettext('(%s commit)','(%s commits)', len(c.commit_ranges)) % len(c.commit_ranges)}
21 </%def>
22
16
23 <%def name="menu_bar_nav()">
17 <%def name="menu_bar_nav()">
24 ${self.menu_items(active='repositories')}
18 ${self.menu_items(active='repositories')}
25 </%def>
19 </%def>
26
20
27 <%def name="menu_bar_subnav()">
21 <%def name="menu_bar_subnav()">
28 ${self.repo_menu(active='changelog')}
22 ${self.repo_menu(active='commits')}
29 </%def>
23 </%def>
30
24
31 <%def name="main()">
25 <%def name="main()">
32 <div class="summary-header">
26 <div class="box">
33 <div class="title">
34 ${self.repo_page_title(c.rhodecode_db_repo)}
35 </div>
36 </div>
37
38
39 <div class="summary changeset">
27 <div class="summary changeset">
40 <div class="summary-detail">
28 <div class="summary-detail">
41 <div class="summary-detail-header">
29 <div class="summary-detail-header">
42 <span class="breadcrumbs files_location">
30 <span class="breadcrumbs files_location">
43 <h4>
31 <h4>
44 ${_('Commit Range')}
32 ${_('Commit Range')}
45 <code>
46 r${c.commit_ranges[0].idx}:${h.short_id(c.commit_ranges[0].raw_id)}...r${c.commit_ranges[-1].idx}:${h.short_id(c.commit_ranges[-1].raw_id)}
47 </code>
48 </h4>
33 </h4>
49 </span>
34 </span>
35
36 <div class="clear-fix"></div>
50 </div>
37 </div>
51
38
52 <div class="fieldset">
39 <div class="fieldset">
53 <div class="left-label">
40 <div class="left-label-summary">
54 ${_('Diff option')}:
41 <p class="spacing">${_('Range')}:</p>
42 <div class="right-label-summary">
43 <div class="code-header" >
44 <div class="compare_header">
45 <code class="fieldset-text-line">
46 r${c.commit_ranges[0].idx}:${h.short_id(c.commit_ranges[0].raw_id)}
47 ...
48 r${c.commit_ranges[-1].idx}:${h.short_id(c.commit_ranges[-1].raw_id)}
49 ${_ungettext('(%s commit)','(%s commits)', len(c.commit_ranges)) % len(c.commit_ranges)}
50 </code>
55 </div>
51 </div>
56 <div class="right-content">
52 </div>
53 </div>
54 </div>
55 </div>
56
57 <div class="fieldset">
58 <div class="left-label-summary">
59 <p class="spacing">${_('Diff Option')}:</p>
60 <div class="right-label-summary">
61 <div class="code-header" >
62 <div class="compare_header">
57 <div class="btn btn-primary">
63 <div class="btn btn-primary">
58 <a href="${h.route_path('repo_compare',
64 <a href="${h.route_path('repo_compare',
59 repo_name=c.repo_name,
65 repo_name=c.repo_name,
@@ -62,14 +68,17 b''
62 target_ref_type='rev',
68 target_ref_type='rev',
63 target_ref=c.commit_ranges[-1].raw_id)}"
69 target_ref=c.commit_ranges[-1].raw_id)}"
64 >
70 >
65 ${_('Show combined compare')}
71 ${_('Show combined diff')}
66 </a>
72 </a>
67 </div>
73 </div>
68 </div>
74 </div>
69 </div>
75 </div>
76 </div>
77 </div>
78 </div>
70
79
80 <div class="clear-fix"></div>
71 </div> <!-- end summary-detail -->
81 </div> <!-- end summary-detail -->
72
73 </div> <!-- end summary -->
82 </div> <!-- end summary -->
74
83
75 <div id="changeset_compare_view_content">
84 <div id="changeset_compare_view_content">
@@ -105,4 +114,6 b''
105 %endfor
114 %endfor
106 </div>
115 </div>
107 </div>
116 </div>
117 </div>
118
108 </%def>
119 </%def>
@@ -959,7 +959,8 b' def get_comments_for(diff_type, comments'
959 text: _gettext('Toggle Wide Mode diff'),
959 text: _gettext('Toggle Wide Mode diff'),
960 action: function () {
960 action: function () {
961 updateSticky();
961 updateSticky();
962 Rhodecode.comments.toggleWideMode(this);
962 var wide = Rhodecode.comments.toggleWideMode(this);
963 storeUserSessionAttr('rc_user_session_attr.wide_diff_mode', wide);
963 return null;
964 return null;
964 },
965 },
965 url: null,
966 url: null,
@@ -1002,6 +1003,11 b' def get_comments_for(diff_type, comments'
1002 ]
1003 ]
1003 };
1004 };
1004
1005
1006 // get stored diff mode and pre-enable it
1007 if (templateContext.session_attrs.wide_diff_mode === "true") {
1008 Rhodecode.comments.toggleWideMode(null);
1009 }
1010
1005 $("#diff_menu").select2({
1011 $("#diff_menu").select2({
1006 minimumResultsForSearch: -1,
1012 minimumResultsForSearch: -1,
1007 containerCssClass: "drop-menu",
1013 containerCssClass: "drop-menu",
@@ -23,17 +23,36 b''
23 </%def>
23 </%def>
24
24
25 <%def name="menu_bar_subnav()">
25 <%def name="menu_bar_subnav()">
26 ${self.repo_menu(active='changelog')}
26 ${self.repo_menu(active='commits')}
27 </%def>
27 </%def>
28
28
29 <%def name="main()">
29 <%def name="main()">
30
30
31 <div class="box">
31 <div class="box">
32
32 <div class="title">
33 <div class="title">
33 ${self.repo_page_title(c.rhodecode_db_repo)}
34 <div id="filter_changelog">
35 ${h.hidden('branch_filter')}
36 %if c.selected_name:
37 <div class="btn btn-default" id="clear_filter" >
38 ${_('Clear filter')}
39 </div>
40 %endif
41 </div>
42 <div class="pull-left obsolete-toggle">
43 % if h.is_hg(c.rhodecode_repo):
44 % if c.show_hidden:
45 <a class="action-link" href="${h.current_route_path(request, evolve=0)}">${_('Hide obsolete/hidden')}</a>
46 % else:
47 <a class="action-link" href="${h.current_route_path(request, evolve=1)}">${_('Show obsolete/hidden')}</a>
48 % endif
49 % else:
50 <span class="action-link disabled">${_('Show hidden')}</span>
51 % endif
52 </div>
34 <ul class="links">
53 <ul class="links">
35 <li>
54 <li>
36 <a href="#" class="btn btn-small" id="rev_range_container" style="display:none;"></a>
55
37 %if c.rhodecode_db_repo.fork:
56 %if c.rhodecode_db_repo.fork:
38 <span>
57 <span>
39 <a id="compare_fork_button"
58 <a id="compare_fork_button"
@@ -61,11 +80,6 b''
61 </span>
80 </span>
62 %endif
81 %endif
63
82
64 ## clear selection
65 <div title="${_('Clear selection')}" class="btn" id="rev_range_clear" style="display:none">
66 ${_('Clear selection')}
67 </div>
68
69 </li>
83 </li>
70 </ul>
84 </ul>
71 </div>
85 </div>
@@ -74,29 +88,7 b''
74 <script type="text/javascript" src="${h.asset('js/src/plugins/jquery.commits-graph.js')}"></script>
88 <script type="text/javascript" src="${h.asset('js/src/plugins/jquery.commits-graph.js')}"></script>
75
89
76 <div class="graph-header">
90 <div class="graph-header">
77 <div id="filter_changelog">
78 ${h.hidden('branch_filter')}
79 %if c.selected_name:
80 <div class="btn btn-default" id="clear_filter" >
81 ${_('Clear filter')}
82 </div>
83 %endif
84 </div>
85 ${self.breadcrumbs('breadcrumbs_light')}
91 ${self.breadcrumbs('breadcrumbs_light')}
86 <div class="pull-right">
87 % if h.is_hg(c.rhodecode_repo):
88 % if c.show_hidden:
89 <a class="action-link" href="${h.current_route_path(request, evolve=0)}">${_('Hide obsolete/hidden')}</a>
90 % else:
91 <a class="action-link" href="${h.current_route_path(request, evolve=1)}">${_('Show obsolete/hidden')}</a>
92 % endif
93 % else:
94 <span class="action-link disabled">${_('Show hidden')}</span>
95 % endif
96 </div>
97 <div id="commit-counter" data-total=${c.total_cs} class="pull-right">
98 ${_ungettext('showing %d out of %d commit', 'showing %d out of %d commits', c.showing_commits) % (c.showing_commits, c.total_cs)}
99 </div>
100 </div>
92 </div>
101
93
102 <div id="graph">
94 <div id="graph">
@@ -104,18 +96,21 b''
104 <div id="graph_nodes">
96 <div id="graph_nodes">
105 <div id="graph_canvas"></div>
97 <div id="graph_canvas"></div>
106 </div>
98 </div>
107 <div id="graph_content" class="main-content graph_full_width">
99 <div id="graph_content" class="graph_full_width">
108
100
109 <div class="table">
101 <div class="table">
110 <table id="changesets" class="rctable">
102 <table id="changesets" class="rctable">
111 <tr>
103 <tr>
112 ## checkbox
104 ## checkbox
113 <th></th>
105 <th colspan="4">
114 <th colspan="2"></th>
106 ## clear selection
107 <div title="${_('Clear selection')}" class="btn btn-sm" id="rev_range_clear" style="display:none">
108 <i class="icon-cancel-circled2"></i>
109 </div>
110 <div class="btn btn-sm disabled" disabled="disabled" id="rev_range_more" style="display:none;">${_('Select second commit')}</div>
111 <a href="#" class="btn btn-success btn-sm" id="rev_range_container" style="display:none;"></a>
112 </th>
115
113
116 <th>${_('Commit')}</th>
117 ## Mercurial phase/evolve state
118 <th></th>
119 ## commit message expand arrow
114 ## commit message expand arrow
120 <th></th>
115 <th></th>
121 <th>${_('Commit Message')}</th>
116 <th>${_('Commit Message')}</th>
@@ -124,6 +119,8 b''
124 <th>${_('Author')}</th>
119 <th>${_('Author')}</th>
125
120
126 <th>${_('Refs')}</th>
121 <th>${_('Refs')}</th>
122 ## comments
123 <th></th>
127 </tr>
124 </tr>
128
125
129 <tbody class="commits-range">
126 <tbody class="commits-range">
@@ -135,6 +132,9 b''
135 <div class="pagination-wh pagination-left">
132 <div class="pagination-wh pagination-left">
136 ${c.pagination.pager('$link_previous ~2~ $link_next')}
133 ${c.pagination.pager('$link_previous ~2~ $link_next')}
137 </div>
134 </div>
135 <div id="commit-counter" data-total=${c.total_cs} class="pull-right">
136 ${_ungettext('showing %d out of %d commit', 'showing %d out of %d commits', c.showing_commits) % (c.showing_commits, c.total_cs)}
137 </div>
138 </div>
138 </div>
139
139
140 <script type="text/javascript">
140 <script type="text/javascript">
@@ -144,6 +144,7 b''
144 // Create links to commit ranges when range checkboxes are selected
144 // Create links to commit ranges when range checkboxes are selected
145 var $commitCheckboxes = $('.commit-range');
145 var $commitCheckboxes = $('.commit-range');
146 // cache elements
146 // cache elements
147 var $commitRangeMore = $('#rev_range_more');
147 var $commitRangeContainer = $('#rev_range_container');
148 var $commitRangeContainer = $('#rev_range_container');
148 var $commitRangeClear = $('#rev_range_clear');
149 var $commitRangeClear = $('#rev_range_clear');
149
150
@@ -155,57 +156,68 b''
155 }
156 }
156 }
157 }
157 var open_new_pull_request = $('#open_new_pull_request');
158 var open_new_pull_request = $('#open_new_pull_request');
159
158 if(open_new_pull_request){
160 if (open_new_pull_request) {
159 var selected_changes = selectedCheckboxes.length;
161 var selected_changes = selectedCheckboxes.length;
160 if (selected_changes > 1 || selected_changes == 1 && templateContext.repo_type == 'svn') {
161 open_new_pull_request.hide();
162 open_new_pull_request.hide();
162 } else {
163 if (selected_changes == 1) {
163 if (selected_changes == 1) {
164 open_new_pull_request.html(_gettext('Open new pull request for selected commit'));
164 open_new_pull_request.html(_gettext('Open new pull request for selected commit'));
165 } else if (selected_changes == 0) {
165 } else {
166 open_new_pull_request.html(_gettext('Open new pull request'));
166 open_new_pull_request.html(_gettext('Open new pull request'));
167 }
167 }
168 open_new_pull_request.show();
168 open_new_pull_request.show();
169 }
169 }
170 }
171
170
172 if (selectedCheckboxes.length>0){
171 if (selectedCheckboxes.length > 0) {
173 var revEnd = selectedCheckboxes[0].name;
172 $('#compare_fork_button').hide();
174 var revStart = selectedCheckboxes[selectedCheckboxes.length-1].name;
173 var commitStart = $(selectedCheckboxes[selectedCheckboxes.length-1]).data();
175 var url = pyroutes.url('repo_commit',
174
176 {'repo_name': '${c.repo_name}',
175 var revStart = commitStart.commitId;
177 'commit_id': revStart+'...'+revEnd});
176
177 var commitEnd = $(selectedCheckboxes[0]).data();
178 var revEnd = commitEnd.commitId;
178
179
179 var link = (revStart == revEnd)
180 var lbl_start = '{0}'.format(commitStart.commitIdx, commitStart.shortId);
180 ? _gettext('Show selected commit __S')
181 var lbl_end = '{0}'.format(commitEnd.commitIdx, commitEnd.shortId);
181 : _gettext('Show selected commits __S ... __E');
182
182
183 link = link.replace('__S', revStart.substr(0,6));
183 var url = pyroutes.url('repo_commit', {'repo_name': '${c.repo_name}', 'commit_id': revStart+'...'+revEnd});
184 link = link.replace('__E', revEnd.substr(0,6));
184 var link = _gettext('Show commit range {0} ... {1}').format(lbl_start, lbl_end);
185
186 if (selectedCheckboxes.length > 1) {
187 $commitRangeClear.show();
188 $commitRangeMore.hide();
185
189
186 $commitRangeContainer
190 $commitRangeContainer
187 .attr('href',url)
191 .attr('href',url)
188 .html(link)
192 .html(link)
189 .show();
193 .show();
190
194
195
196 } else {
197 $commitRangeContainer.hide();
191 $commitRangeClear.show();
198 $commitRangeClear.show();
192 var _url = pyroutes.url('pullrequest_new',
199 $commitRangeMore.show();
193 {'repo_name': '${c.repo_name}',
200 }
194 'commit': revEnd});
201
202 // pull-request link
203 if (selectedCheckboxes.length == 1){
204 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'commit': revEnd});
195 open_new_pull_request.attr('href', _url);
205 open_new_pull_request.attr('href', _url);
196 $('#compare_fork_button').hide();
206 } else {
207 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
208 open_new_pull_request.attr('href', _url);
209 }
210
197 } else {
211 } else {
198 $commitRangeContainer.hide();
212 $commitRangeContainer.hide();
199 $commitRangeClear.hide();
213 $commitRangeClear.hide();
214 $commitRangeMore.hide();
200
215
201 %if c.branch_name:
216 %if c.branch_name:
202 var _url = pyroutes.url('pullrequest_new',
217 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'branch':'${c.branch_name}'});
203 {'repo_name': '${c.repo_name}',
204 'branch':'${c.branch_name}'});
205 open_new_pull_request.attr('href', _url);
218 open_new_pull_request.attr('href', _url);
206 %else:
219 %else:
207 var _url = pyroutes.url('pullrequest_new',
220 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
208 {'repo_name': '${c.repo_name}'});
209 open_new_pull_request.attr('href', _url);
221 open_new_pull_request.attr('href', _url);
210 %endif
222 %endif
211 $('#compare_fork_button').show();
223 $('#compare_fork_button').show();
@@ -241,13 +253,13 b''
241
253
242 $("#clear_filter").on("click", function() {
254 $("#clear_filter").on("click", function() {
243 var filter = {'repo_name': '${c.repo_name}'};
255 var filter = {'repo_name': '${c.repo_name}'};
244 window.location = pyroutes.url('repo_changelog', filter);
256 window.location = pyroutes.url('repo_commits', filter);
245 });
257 });
246
258
247 $("#branch_filter").select2({
259 $("#branch_filter").select2({
248 'dropdownAutoWidth': true,
260 'dropdownAutoWidth': true,
249 'width': 'resolve',
261 'width': 'resolve',
250 'placeholder': "${c.selected_name or _('Filter changelog')}",
262 'placeholder': "${c.selected_name or _('Branch filter')}",
251 containerCssClass: "drop-menu",
263 containerCssClass: "drop-menu",
252 dropdownCssClass: "drop-menu-dropdown",
264 dropdownCssClass: "drop-menu-dropdown",
253 query: function(query){
265 query: function(query){
@@ -295,7 +307,7 b''
295 else if (data.type == 'book'){
307 else if (data.type == 'book'){
296 filter["bookmark"] = selected;
308 filter["bookmark"] = selected;
297 }
309 }
298 window.location = pyroutes.url('repo_changelog', filter);
310 window.location = pyroutes.url('repo_commits', filter);
299 });
311 });
300
312
301 commitsController = new CommitsController();
313 commitsController = new CommitsController();
@@ -3,7 +3,7 b''
3
3
4 % if c.prev_page:
4 % if c.prev_page:
5 <tr>
5 <tr>
6 <td colspan="9" class="load-more-commits">
6 <td colspan="10" class="load-more-commits">
7 <a class="prev-commits" href="#loadPrevCommits" onclick="commitsController.loadPrev(this, ${c.prev_page}, '${c.branch_name}', '${c.commit_id}', '${c.f_path}');return false">
7 <a class="prev-commits" href="#loadPrevCommits" onclick="commitsController.loadPrev(this, ${c.prev_page}, '${c.branch_name}', '${c.commit_id}', '${c.f_path}');return false">
8 ${_('load previous')}
8 ${_('load previous')}
9 </a>
9 </a>
@@ -21,10 +21,14 b''
21 <tr id="sha_${commit.raw_id}" class="changelogRow container ${'tablerow%s' % (cnt%2)}">
21 <tr id="sha_${commit.raw_id}" class="changelogRow container ${'tablerow%s' % (cnt%2)}">
22
22
23 <td class="td-checkbox">
23 <td class="td-checkbox">
24 ${h.checkbox(commit.raw_id,class_="commit-range")}
24 ${h.checkbox(commit.raw_id,class_="commit-range", **{'data-commit-idx':commit.idx, 'data-commit-id': commit.raw_id, 'data-short-id': commit.short_id})}
25 </td>
25 </td>
26 ##
27 <td class="td-graphbox">
28
29 </td>
30
26 <td class="td-status">
31 <td class="td-status">
27
28 %if c.statuses.get(commit.raw_id):
32 %if c.statuses.get(commit.raw_id):
29 <div class="changeset-status-ico">
33 <div class="changeset-status-ico">
30 %if c.statuses.get(commit.raw_id)[2]:
34 %if c.statuses.get(commit.raw_id)[2]:
@@ -41,44 +45,38 b''
41 <div class="tooltip flag_status not_reviewed" title="${_('Commit status: Not Reviewed')}"></div>
45 <div class="tooltip flag_status not_reviewed" title="${_('Commit status: Not Reviewed')}"></div>
42 %endif
46 %endif
43 </td>
47 </td>
44 <td class="td-comments comments-col">
48
45 %if c.comments.get(commit.raw_id):
46 <a title="${_('Commit has comments')}" href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=commit.raw_id,_anchor='comment-%s' % c.comments[commit.raw_id][0].comment_id)}">
47 <i class="icon-comment"></i> ${len(c.comments[commit.raw_id])}
48 </a>
49 %endif
50 </td>
51 <td class="td-hash">
49 <td class="td-hash">
52 <code>
50 <code>
53
51
54 <a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=commit.raw_id)}">
52 <a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=commit.raw_id)}">
55 <span class="${'commit_hash obsolete' if getattr(commit, 'obsolete', None) else 'commit_hash'}">${h.show_id(commit)}</span>
53 <span class="${'commit_hash obsolete' if getattr(commit, 'obsolete', None) else 'commit_hash'}">${h.show_id(commit)}</span>
56 </a>
54 </a>
55
57 <i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${commit.raw_id}" title="${_('Copy the full commit id')}"></i>
56 <i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${commit.raw_id}" title="${_('Copy the full commit id')}"></i>
58 </code>
57
59 </td>
58 ## COMMIT PHASES
60 <td class="td-tags tags-col">
59
61 ## phase
60 ## Draft
62 % if hasattr(commit, 'phase'):
61 % if hasattr(commit, 'phase'):
63 % if commit.phase != 'public':
62 % if commit.phase != 'public':
64 <span class="tag phase-${commit.phase} tooltip" title="${_('Commit phase')}">${commit.phase}</span>
63 <span class="tag phase-${commit.phase} tooltip" title="${_('{} commit phase').format(commit.phase)}">${commit.phase[0].upper()}</span>
65 % endif
64 % endif
66 % endif
65 % endif
67
66
68 ## obsolete commits
67 ## obsolete commits
69 % if hasattr(commit, 'obsolete'):
68 % if hasattr(commit, 'obsolete') and commit.obsolete:
70 % if commit.obsolete:
69 <span class="tag obsolete-${commit.obsolete} tooltip" title="${_('Obsolete Evolve State')}">O</span>
71 <span class="tag obsolete-${commit.obsolete} tooltip" title="${_('Evolve State')}">${_('obsolete')}</span>
72 % endif
73 % endif
70 % endif
74
71
75 ## hidden commits
72 ## hidden commits
76 % if hasattr(commit, 'hidden'):
73 % if hasattr(commit, 'hidden') and commit.hidden:
77 % if commit.hidden:
74 <span class="tag obsolete-${commit.hidden} tooltip" title="${_('Hidden Evolve State')}">H</span>
78 <span class="tag obsolete-${commit.hidden} tooltip" title="${_('Evolve State')}">${_('hidden')}</span>
79 % endif
75 % endif
80 % endif
76
77 </code>
81 </td>
78 </td>
79
82 <td class="td-message expand_commit" data-commit-id="${commit.raw_id}" title="${_('Expand commit message')}" onclick="commitsController.expandCommit(this, true); return false">
80 <td class="td-message expand_commit" data-commit-id="${commit.raw_id}" title="${_('Expand commit message')}" onclick="commitsController.expandCommit(this, true); return false">
83 <i class="icon-expand-linked"></i>&nbsp;
81 <i class="icon-expand-linked"></i>&nbsp;
84 </td>
82 </td>
@@ -108,7 +106,7 b''
108 ## branch
106 ## branch
109 %if commit.branch:
107 %if commit.branch:
110 <span class="tag branchtag" title="${h.tooltip(_('Branch %s') % commit.branch)}">
108 <span class="tag branchtag" title="${h.tooltip(_('Branch %s') % commit.branch)}">
111 <a href="${h.route_path('repo_changelog',repo_name=c.repo_name,_query=dict(branch=commit.branch))}"><i class="icon-code-fork"></i>${h.shorter(commit.branch)}</a>
109 <a href="${h.route_path('repo_commits',repo_name=c.repo_name,_query=dict(branch=commit.branch))}"><i class="icon-code-fork"></i>${h.shorter(commit.branch)}</a>
112 </span>
110 </span>
113 %endif
111 %endif
114
112
@@ -130,6 +128,18 b''
130
128
131 </div>
129 </div>
132 </td>
130 </td>
131
132 <td class="td-comments comments-col">
133 <% cs_comments = c.comments.get(commit.raw_id,[]) %>
134 % if cs_comments:
135 <a title="${_('Commit has comments')}" href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=commit.raw_id,_anchor='comment-%s' % cs_comments[0].comment_id)}">
136 <i class="icon-comment"></i> ${len(cs_comments)}
137 </a>
138 % else:
139 <i class="icon-comment"></i> ${len(cs_comments)}
140 % endif
141 </td>
142
133 </tr>
143 </tr>
134 % endfor
144 % endfor
135
145
@@ -3,7 +3,7 b''
3
3
4 <table class="table rctable file_history">
4 <table class="table rctable file_history">
5 %for cnt,cs in enumerate(c.pagination):
5 %for cnt,cs in enumerate(c.pagination):
6 <tr id="chg_${cnt+1}" class="${'tablerow%s' % (cnt%2)}">
6 <tr id="chg_${cnt+1}" class="${('tablerow%s' % (cnt%2))}">
7 <td class="td-user">
7 <td class="td-user">
8 ${base.gravatar_with_user(cs.author, 16)}
8 ${base.gravatar_with_user(cs.author, 16)}
9 </td>
9 </td>
@@ -33,7 +33,19 b''
33 ${_('Show File')}
33 ${_('Show File')}
34 </a>
34 </a>
35 </td>
35 </td>
36 <td class="td-actions">
37 <a href="${h.route_path('repo_compare',repo_name=c.repo_name, source_ref_type="rev", source_ref=cs.raw_id,target_ref_type="rev", target_ref=c.commit_id,_query=dict(merge='1',f_path=c.changelog_for_path))}">
38 <span title="${'Diff {} vs {}'.format(cs.raw_id[:8],c.commit_id[:8])}">${_('Diff File')}</span>
39 </a>
40 </td>
36 </tr>
41 </tr>
37 %endfor
42 %endfor
43 <tr>
44 <td colspan="6">
45 <a id="file_history_overview_full" href="${h.route_path('repo_commits_file',repo_name=c.repo_name, commit_id=c.commit_id, f_path=c.f_path)}">
46 ${_('Show Full History')}
47 </a>
48 </td>
49 </tr>
38 </table>
50 </table>
39 </div>
51 </div>
@@ -13,9 +13,7 b''
13 %endif
13 %endif
14 </%def>
14 </%def>
15
15
16 <%def name="breadcrumbs_links()">
16 <%def name="breadcrumbs_links()"></%def>
17 ${_ungettext('%s commit','%s commits', len(c.commit_ranges)) % len(c.commit_ranges)}
18 </%def>
19
17
20 <%def name="menu_bar_nav()">
18 <%def name="menu_bar_nav()">
21 ${self.menu_items(active='repositories')}
19 ${self.menu_items(active='repositories')}
@@ -32,10 +30,6 b''
32 </script>
30 </script>
33
31
34 <div class="box">
32 <div class="box">
35 <div class="title">
36 ${self.repo_page_title(c.rhodecode_db_repo)}
37 </div>
38
39 <div class="summary changeset">
33 <div class="summary changeset">
40 <div class="summary-detail">
34 <div class="summary-detail">
41 <div class="summary-detail-header">
35 <div class="summary-detail-header">
@@ -43,24 +37,24 b''
43 <h4>
37 <h4>
44 ${_('Compare Commits')}
38 ${_('Compare Commits')}
45 % if c.file_path:
39 % if c.file_path:
46 ${_('for file')} <a href="#${'a_' + h.FID('',c.file_path)}">${c.file_path}</a>
40 ${_('for file')} <a href="#${('a_' + h.FID('',c.file_path))}">${c.file_path}</a>
47 % endif
41 % endif
48
42
49 % if c.commit_ranges:
43 % if c.commit_ranges:
50 <code>
44 <code>
51 r${c.source_commit.idx}:${h.short_id(c.source_commit.raw_id)}...r${c.target_commit.idx}:${h.short_id(c.target_commit.raw_id)}
45 r${c.commit_ranges[0].idx}:${h.short_id(c.commit_ranges[0].raw_id)}...r${c.commit_ranges[-1].idx}:${h.short_id(c.commit_ranges[-1].raw_id)}
52 </code>
46 </code>
53 % endif
47 % endif
54 </h4>
48 </h4>
55 </span>
49 </span>
50
51 <div class="clear-fix"></div>
56 </div>
52 </div>
57
53
58 <div class="fieldset">
54 <div class="fieldset">
59 <div class="left-label">
55 <div class="left-label-summary">
60 ${_('Target')}:
56 <p class="spacing">${_('Target')}:</p>
61 </div>
57 <div class="right-label-summary">
62 <div class="right-content">
63 <div>
64 <div class="code-header" >
58 <div class="code-header" >
65 <div class="compare_header">
59 <div class="compare_header">
66 ## The hidden elements are replaced with a select2 widget
60 ## The hidden elements are replaced with a select2 widget
@@ -72,11 +66,9 b''
72 </div>
66 </div>
73
67
74 <div class="fieldset">
68 <div class="fieldset">
75 <div class="left-label">
69 <div class="left-label-summary">
76 ${_('Source')}:
70 <p class="spacing">${_('Source')}:</p>
77 </div>
71 <div class="right-label-summary">
78 <div class="right-content">
79 <div>
80 <div class="code-header" >
72 <div class="code-header" >
81 <div class="compare_header">
73 <div class="compare_header">
82 ## The hidden elements are replaced with a select2 widget
74 ## The hidden elements are replaced with a select2 widget
@@ -88,17 +80,29 b''
88 </div>
80 </div>
89
81
90 <div class="fieldset">
82 <div class="fieldset">
91 <div class="left-label">
83 <div class="left-label-summary">
92 ${_('Actions')}:
84 <p class="spacing">${_('Actions')}:</p>
93 </div>
85 <div class="right-label-summary">
94 <div class="right-content">
95 <div>
96 <div class="code-header" >
86 <div class="code-header" >
97 <div class="compare_header">
87 <div class="compare_header">
98
99 <div class="compare-buttons">
88 <div class="compare-buttons">
100 % if c.compare_home:
89 % if c.compare_home:
101 <a id="compare_revs" class="btn btn-primary"> ${_('Compare Commits')}</a>
90 <a id="compare_revs" class="btn btn-primary"> ${_('Compare Commits')}</a>
91 %if c.rhodecode_db_repo.fork:
92
93 <a class="btn btn-default" title="${h.tooltip(_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name))}"
94 href="${h.route_path('repo_compare',
95 repo_name=c.rhodecode_db_repo.fork.repo_name,
96 source_ref_type=c.rhodecode_db_repo.landing_rev[0],
97 source_ref=c.rhodecode_db_repo.landing_rev[1],
98 target_repo=c.repo_name,target_ref_type='branch' if request.GET.get('branch') else c.rhodecode_db_repo.landing_rev[0],
99 target_ref=request.GET.get('branch') or c.rhodecode_db_repo.landing_rev[1],
100 _query=dict(merge=1))}"
101 >
102 ${_('Compare with origin')}
103 </a>
104
105 %endif
102
106
103 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Swap')}</a>
107 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Swap')}</a>
104 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Comment')}</a>
108 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Comment')}</a>
@@ -131,10 +135,9 b''
131
135
132 ## commit status form
136 ## commit status form
133 <div class="fieldset" id="compare_changeset_status" style="display: none; margin-bottom: -80px;">
137 <div class="fieldset" id="compare_changeset_status" style="display: none; margin-bottom: -80px;">
134 <div class="left-label">
138 <div class="left-label-summary">
135 ${_('Commit status')}:
139 <p class="spacing">${_('Commit status')}:</p>
136 </div>
140 <div class="right-label-summary">
137 <div class="right-content">
138 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
141 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
139 ## main comment form and it status
142 ## main comment form and it status
140 <%
143 <%
@@ -150,7 +153,8 b''
150 </div>
153 </div>
151 </div>
154 </div>
152 </div>
155 </div>
153
156 </div>
157 <div class="clear-fix"></div>
154 </div> <!-- end summary-detail -->
158 </div> <!-- end summary-detail -->
155 </div> <!-- end summary -->
159 </div> <!-- end summary -->
156
160
@@ -275,8 +279,6 b''
275
279
276 ## table diff data
280 ## table diff data
277 <div class="table">
281 <div class="table">
278
279
280 % if not c.compare_home:
282 % if not c.compare_home:
281 <div id="changeset_compare_view_content">
283 <div id="changeset_compare_view_content">
282 <div class="pull-left">
284 <div class="pull-left">
@@ -48,8 +48,8 b''
48 </a>
48 </a>
49 </li>
49 </li>
50 <li>
50 <li>
51 <a title="${_('Changelog')}" href="${h.route_path('repo_changelog',repo_name=repo_name)}">
51 <a title="${_('Commits')}" href="${h.route_path('repo_commits',repo_name=repo_name)}">
52 <span>${_('Changelog')}</span>
52 <span>${_('Commits')}</span>
53 </a>
53 </a>
54 </li>
54 </li>
55 <li>
55 <li>
@@ -205,7 +205,7 b''
205 <%def name="repo_group_name(repo_group_name, children_groups=None)">
205 <%def name="repo_group_name(repo_group_name, children_groups=None)">
206 <div>
206 <div>
207 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">
207 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">
208 <i class="icon-folder-close" title="${_('Repository group')}" style="font-size: 16px"></i>
208 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
209 %if children_groups:
209 %if children_groups:
210 ${h.literal(' &raquo; '.join(children_groups))}
210 ${h.literal(' &raquo; '.join(children_groups))}
211 %else:
211 %else:
@@ -377,6 +377,30 b''
377 </%def>
377 </%def>
378
378
379
379
380 ## ARTIFACT RENDERERS
381
382 <%def name="repo_artifact_uid(repo_name, file_uid)">
383 <code><a href="${h.route_path('repo_artifacts_get', repo_name=repo_name, uid=file_uid)}">${file_uid}</a></code>
384 </%def>
385
386 <%def name="repo_artifact_uid_action(repo_name, file_uid)">
387 <i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${h.route_url('repo_artifacts_get', repo_name=repo_name, uid=file_uid)}" title="${_('Copy the full url')}"></i>
388 </%def>
389
390 <%def name="repo_artifact_actions(repo_name, file_store_id, file_uid)">
391 ## <div class="grid_edit">
392 ## <a href="#Edit" title="${_('Edit')}">${_('Edit')}</a>
393 ## </div>
394 % if h.HasRepoPermissionAny('repository.admin')(c.repo_name):
395 <div class="grid_delete">
396 ${h.secure_form(h.route_path('repo_artifacts_delete', repo_name=repo_name, uid=file_store_id), request=request)}
397 ${h.submit('remove_',_('Delete'),id="remove_artifact_%s" % file_store_id, class_="btn btn-link btn-danger",
398 onclick="return confirm('"+_('Confirm to delete this artifact: %s') % file_uid+"');")}
399 ${h.end_form()}
400 </div>
401 % endif
402 </%def>
403
380 <%def name="markup_form(form_id, form_text='', help_text=None)">
404 <%def name="markup_form(form_id, form_text='', help_text=None)">
381
405
382 <div class="markup-form">
406 <div class="markup-form">
@@ -641,7 +641,7 b' File Edit'
641 <span class="item">1.2 KiB</span>
641 <span class="item">1.2 KiB</span>
642 <span class="item last">text/x-python</span>
642 <span class="item last">text/x-python</span>
643 <div class="buttons">
643 <div class="buttons">
644 <a class="btn btn-mini" href="/example/changelog/80ead1899f50a894889e19ffeb49c9cebf5bf045/rhodecode/websetup.py">
644 <a class="btn btn-mini" href="/example/commits/80ead1899f50a894889e19ffeb49c9cebf5bf045/rhodecode/websetup.py">
645 <i class="icon-time"></i> history
645 <i class="icon-time"></i> history
646 </a>
646 </a>
647
647
@@ -425,7 +425,7 b''
425 <tr>
425 <tr>
426 <td>td-active</td>
426 <td>td-active</td>
427 <td>Shows active state with icon-true/icon-false.</td>
427 <td>Shows active state with icon-true/icon-false.</td>
428 <td class="td-active"><i class="icon-false"></i></td>
428 <td class="td-active"><i class="icon-pr-merge-fail"></i></td>
429 </tr>
429 </tr>
430 <tr>
430 <tr>
431 <td>td-size</td>
431 <td>td-size</td>
@@ -1,4 +1,11 b''
1 <%def name="refs(commit)">
1 <%def name="refs(commit)">
2 ## Build a cache of refs for selector
3 <script>
4 fileTreeRefs = {
5
6 }
7 </script>
8
2 %if commit.merge:
9 %if commit.merge:
3 <span class="mergetag tag">
10 <span class="mergetag tag">
4 <i class="icon-merge">${_('merge')}</i>
11 <i class="icon-merge">${_('merge')}</i>
@@ -10,6 +17,9 b''
10 <span class="booktag tag" title="${h.tooltip(_('Bookmark %s') % book)}">
17 <span class="booktag tag" title="${h.tooltip(_('Bookmark %s') % book)}">
11 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=book))}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
18 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=book))}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
12 </span>
19 </span>
20 <script>
21 fileTreeRefs["${book}"] = {raw_id: "${commit.raw_id}", type:"book", text: "${book}"};
22 </script>
13 %endfor
23 %endfor
14 %endif
24 %endif
15
25
@@ -17,12 +27,18 b''
17 <span class="tagtag tag" title="${h.tooltip(_('Tag %s') % tag)}">
27 <span class="tagtag tag" title="${h.tooltip(_('Tag %s') % tag)}">
18 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=tag))}"><i class="icon-tag"></i>${tag}</a>
28 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=tag))}"><i class="icon-tag"></i>${tag}</a>
19 </span>
29 </span>
30 <script>
31 fileTreeRefs["${tag}"] = {raw_id: "${commit.raw_id}", type:"tag", text: "${tag}"};
32 </script>
20 %endfor
33 %endfor
21
34
22 %if commit.branch:
35 %if commit.branch:
23 <span class="branchtag tag" title="${h.tooltip(_('Branch %s') % commit.branch)}">
36 <span class="branchtag tag" title="${h.tooltip(_('Branch %s') % commit.branch)}">
24 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=commit.branch))}"><i class="icon-code-fork"></i>${h.shorter(commit.branch)}</a>
37 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=commit.branch))}"><i class="icon-code-fork"></i>${h.shorter(commit.branch)}</a>
25 </span>
38 </span>
39 <script>
40 fileTreeRefs["${commit.branch}"] = {raw_id: "${commit.raw_id}", type:"branch", text: "${commit.branch}"};
41 </script>
26 %endif
42 %endif
27
43
28 </%def>
44 </%def>
@@ -1,42 +1,38 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="summary-detail-header">
3 % if c.authors:
4 <h4 class="item">
4
5 % if c.file_author:
5 <table class="sidebar-right-content">
6 ${_('Last Author')}
6 % for email, user, commits in sorted(c.authors, key=lambda e: c.file_last_commit.author_email!=e[0]):
7 % else:
7 <tr class="file_author tooltip" title="${h.tooltip(h.author_string(email))}">
8 ${h.literal(_ungettext(u'File Author (%s)',u'File Authors (%s)',len(c.authors)) % ('<b>%s</b>' % len(c.authors))) }
9 % endif
10 </h4>
11 <a href="#" id="show_authors" class="action_link">${_('Show All')}</a>
12 </div>
13
8
14 % if c.authors:
9 <td>
15 <ul class="sidebar-right-content">
10 % if not c.file_author:
16 % for email, user, commits in sorted(c.authors, key=lambda e: c.file_last_commit.author_email!=e[0]):
17 <li class="file_author">
18 <div class="tooltip" title="${h.tooltip(h.author_string(email))}">
19 ${base.gravatar(email, 16)}
11 ${base.gravatar(email, 16)}
20 <div class="user">${h.link_to_user(user)}</div>
12 % endif
21
13 <span class="user commit-author">${h.link_to_user(user)}</span>
22 % if c.file_author:
14 % if c.file_author:
23 <span>- ${h.age_component(c.file_last_commit.date)}</span>
15 <span class="commit-date">- ${h.age_component(c.file_last_commit.date)}</span>
16 <a href="#ShowAuthors" onclick="showAuthors(this, ${("1" if c.annotate else "0")}); return false" class="action_link"> - ${_('Load All Authors')}</a>
24 % elif c.file_last_commit.author_email==email:
17 % elif c.file_last_commit.author_email==email:
25 <span> (${_('last author')})</span>
18 <span> (${_('last author')})</span>
26 % endif
19 % endif
20 </td>
27
21
22 <td>
28 % if not c.file_author:
23 % if not c.file_author:
29 <span>
24 <code>
30 % if commits == 1:
25 % if commits == 1:
31 ${commits} ${_('Commit')}
26 ${commits} ${_('Commit')}
32 % else:
27 % else:
33 ${commits} ${_('Commits')}
28 ${commits} ${_('Commits')}
34 % endif
29 % endif
35 </span>
30 </code>
31 % endif
32 </td>
33 </tr>
34
35 % endfor
36 </table>
36 % endif
37 % endif
37
38
38 </div>
39 </li>
40 % endfor
41 </ul>
42 % endif
This diff has been collapsed as it changes many lines, (559 lines changed) Show them Hide them
@@ -1,9 +1,9 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2
2
3 <%def name="title(*args)">
3 <%def name="title(*args)">
4 ${_('%s Files') % c.repo_name}
4 ${_('{} Files').format(c.repo_name)}
5 %if hasattr(c,'file'):
5 %if hasattr(c,'file'):
6 &middot; ${h.safe_unicode(c.file.path) or '\\'}
6 &middot; ${(h.safe_unicode(c.file.path) or '\\')}
7 %endif
7 %endif
8
8
9 %if c.rhodecode_name:
9 %if c.rhodecode_name:
@@ -27,113 +27,321 b''
27 </%def>
27 </%def>
28
28
29 <%def name="main()">
29 <%def name="main()">
30 <div class="title">
30 <script type="text/javascript">
31 ${self.repo_page_title(c.rhodecode_db_repo)}
31 var fileSourcePage = ${c.file_source_page};
32 </div>
32 var atRef = '${request.GET.get('at', '')}';
33
33
34 <div id="pjax-container" class="summary">
34 // global state for fetching metadata
35 metadataRequest = null;
36
37 // global metadata about URL
38 filesUrlData = ${h.files_url_data(request)|n};
39 </script>
40
41 <div>
35 <div id="files_data">
42 <div id="files_data">
36 <%include file='files_pjax.mako'/>
43 <%include file='files_pjax.mako'/>
37 </div>
44 </div>
38 </div>
45 </div>
39 <script>
46
40 var curState = {
47 <script type="text/javascript">
41 commit_id: "${c.commit.raw_id}"
48
49 var initFileJS = function () {
50 var state = getFileState();
51
52 // select code link event
53 $("#hlcode").mouseup(getSelectionLink);
54
55 // file history select2 used for history of file, and switch to
56 var initialCommitData = {
57 at_ref: atRef,
58 id: null,
59 text: '${c.commit.raw_id}',
60 type: 'sha',
61 raw_id: '${c.commit.raw_id}',
62 idx: ${c.commit.idx},
63 files_url: null,
42 };
64 };
43
65
44 var getState = function(context) {
66 // check if we have ref info.
45 var url = $(location).attr('href');
67 var selectedRef = fileTreeRefs[atRef];
46 var _base_url = '${h.route_path("repo_files",repo_name=c.repo_name,commit_id='',f_path='')}';
68 if (selectedRef !== undefined) {
47 var _annotate_url = '${h.route_path("repo_files:annotated",repo_name=c.repo_name,commit_id='',f_path='')}';
69 $.extend(initialCommitData, selectedRef)
48 _base_url = _base_url.replace('//', '/');
49 _annotate_url = _annotate_url.replace('//', '/');
50
51 //extract f_path from url.
52 var parts = url.split(_base_url);
53 if (parts.length != 2) {
54 parts = url.split(_annotate_url);
55 if (parts.length != 2) {
56 var rev = "tip";
57 var f_path = "";
58 } else {
59 var parts2 = parts[1].split('/');
60 var rev = parts2.shift(); // pop the first element which is the revision
61 var f_path = parts2.join('/');
62 }
63
64 } else {
65 var parts2 = parts[1].split('/');
66 var rev = parts2.shift(); // pop the first element which is the revision
67 var f_path = parts2.join('/');
68 }
70 }
69
71
70 var _node_list_url = pyroutes.url('repo_files_nodelist',
72 var loadUrl = pyroutes.url('repo_file_history', {'repo_name': templateContext.repo_name, 'commit_id': state.commit_id,'f_path': state.f_path});
71 {repo_name: templateContext.repo_name,
73 var cacheKey = '__SINGLE_FILE_REFS__';
72 commit_id: rev, f_path: f_path});
74 var cachedDataSource = {};
73 var _url_base = pyroutes.url('repo_files',
74 {repo_name: templateContext.repo_name,
75 commit_id: rev, f_path:'__FPATH__'});
76 return {
77 url: url,
78 f_path: f_path,
79 rev: rev,
80 commit_id: curState.commit_id,
81 node_list_url: _node_list_url,
82 url_base: _url_base
83 };
84 };
85
86 var metadataRequest = null;
87 var getFilesMetadata = function() {
88 if (metadataRequest && metadataRequest.readyState != 4) {
89 metadataRequest.abort();
90 }
91 if (fileSourcePage) {
92 return false;
93 }
94
75
95 if ($('#file-tree-wrapper').hasClass('full-load')) {
76 var loadRefsData = function (query) {
96 // in case our HTML wrapper has full-load class we don't
77 $.ajax({
97 // trigger the async load of metadata
78 url: loadUrl,
98 return false;
79 data: {},
99 }
80 dataType: 'json',
100
81 type: 'GET',
101 var state = getState('metadata');
82 success: function (data) {
102 var url_data = {
83 cachedDataSource[cacheKey] = data;
103 'repo_name': templateContext.repo_name,
84 query.callback({results: data.results});
104 'commit_id': state.commit_id,
105 'f_path': state.f_path
106 };
107
108 var url = pyroutes.url('repo_nodetree_full', url_data);
109
110 metadataRequest = $.ajax({url: url});
111
112 metadataRequest.done(function(data) {
113 $('#file-tree').html(data);
114 timeagoActivate();
115 });
116 metadataRequest.fail(function (data, textStatus, errorThrown) {
117 console.log(data);
118 if (data.status != 0) {
119 alert("Error while fetching metadata.\nError code {0} ({1}).Please consider reloading the page".format(data.status,data.statusText));
120 }
85 }
121 });
86 });
122 };
87 };
123
88
124 var callbacks = function() {
89 var feedRefsData = function (query, cachedData) {
125 var state = getState('callbacks');
90 var data = {results: []};
126 timeagoActivate();
91 //filter results
92 $.each(cachedData.results, function () {
93 var section = this.text;
94 var children = [];
95 $.each(this.children, function () {
96 if (query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
97 children.push(this)
98 }
99 });
100 data.results.push({
101 'text': section,
102 'children': children
103 })
104 });
105
106 query.callback(data);
107 };
108
109 var select2FileHistorySwitcher = function (targetElement, loadUrl, initialData) {
110 var formatResult = function (result, container, query) {
111 return formatSelect2SelectionRefs(result);
112 };
113
114 var formatSelection = function (data, container) {
115 var commit_ref = data;
116
117 var tmpl = '';
118 if (commit_ref.type === 'sha') {
119 tmpl = (commit_ref.raw_id || "").substr(0,8);
120 } else if (commit_ref.type === 'branch') {
121 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
122 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
123 } else if (commit_ref.type === 'tag') {
124 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
125 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
126 } else if (commit_ref.type === 'book') {
127 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
128 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
129 }
130 var idx = commit_ref.idx || 0;
131 if (idx !== 0) {
132 tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx));
133 }
134 return tmpl
135 };
127
136
128 // used for history, and switch to
137 $(targetElement).select2({
138 dropdownAutoWidth: true,
139 width: "resolve",
140 containerCssClass: "drop-menu",
141 dropdownCssClass: "drop-menu-dropdown",
142 query: function(query) {
143 var cachedData = cachedDataSource[cacheKey];
144 if (cachedData) {
145 feedRefsData(query, cachedData)
146 } else {
147 loadRefsData(query)
148 }
149 },
150 initSelection: function(element, callback) {
151 callback(initialData);
152 },
153 formatResult: formatResult,
154 formatSelection: formatSelection
155 });
156
157 };
158
159 select2FileHistorySwitcher('#file_refs_filter', loadUrl, initialCommitData);
160
161 $('#file_refs_filter').on('change', function(e) {
162 var data = $('#file_refs_filter').select2('data');
163 var commit_id = data.id;
164
165 if ("${c.annotate}" === "True") {
166 var url = pyroutes.url('repo_files:annotated',
167 {'repo_name': templateContext.repo_name,
168 'commit_id': commit_id, 'f_path': state.f_path});
169 } else {
170 var url = pyroutes.url('repo_files',
171 {'repo_name': templateContext.repo_name,
172 'commit_id': commit_id, 'f_path': state.f_path});
173 }
174 window.location = url;
175
176 });
177
178 // load file short history
179 $('#file_history_overview').on('click', function(e) {
180 e.preventDefault();
181 path = state.f_path;
182 if (path.indexOf("#") >= 0) {
183 path = path.slice(0, path.indexOf("#"));
184 }
185 var url = pyroutes.url('repo_commits_file',
186 {'repo_name': templateContext.repo_name,
187 'commit_id': state.commit_id, 'f_path': path, 'limit': 6});
188 $('#file_history_container').show();
189 $('#file_history_container').html('<div class="file-history-inner">{0}</div>'.format(_gettext('Loading ...')));
190
191 $.pjax({
192 url: url,
193 container: '#file_history_container',
194 push: false,
195 timeout: 5000
196 });
197 });
198
199 };
200
201 var initTreeJS = function () {
202 var state = getFileState();
203 getFilesMetadata();
204
205 // fuzzy file filter
206 fileBrowserListeners(state.node_list_url, state.url_base);
207
208 // switch to widget
129 var initialCommitData = {
209 var initialCommitData = {
210 at_ref: atRef,
130 id: null,
211 id: null,
131 text: '${_("Pick Commit")}',
212 text: '${c.commit.raw_id}',
213 type: 'sha',
214 raw_id: '${c.commit.raw_id}',
215 idx: ${c.commit.idx},
216 files_url: null,
217 };
218
219 // check if we have ref info.
220 var selectedRef = fileTreeRefs[atRef];
221 if (selectedRef !== undefined) {
222 $.extend(initialCommitData, selectedRef)
223 }
224
225 var loadUrl = pyroutes.url('repo_refs_data', {'repo_name': templateContext.repo_name});
226 var cacheKey = '__ALL_FILE_REFS__';
227 var cachedDataSource = {};
228
229 var loadRefsData = function (query) {
230 $.ajax({
231 url: loadUrl,
232 data: {},
233 dataType: 'json',
234 type: 'GET',
235 success: function (data) {
236 cachedDataSource[cacheKey] = data;
237 query.callback({results: data.results});
238 }
239 });
240 };
241
242 var feedRefsData = function (query, cachedData) {
243 var data = {results: []};
244 //filter results
245 $.each(cachedData.results, function () {
246 var section = this.text;
247 var children = [];
248 $.each(this.children, function () {
249 if (query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
250 children.push(this)
251 }
252 });
253 data.results.push({
254 'text': section,
255 'children': children
256 })
257 });
258
259 //push the typed in commit idx
260 if (!isNaN(query.term)) {
261 var files_url = pyroutes.url('repo_files',
262 {'repo_name': templateContext.repo_name,
263 'commit_id': query.term, 'f_path': state.f_path});
264
265 data.results.push({
266 'text': _gettext('go to numeric commit'),
267 'children': [{
268 at_ref: null,
269 id: null,
270 text: 'r{0}'.format(query.term),
132 type: 'sha',
271 type: 'sha',
133 raw_id: null,
272 raw_id: query.term,
134 files_url: null
273 idx: query.term,
274 files_url: files_url,
275 }]
276 });
277 }
278 query.callback(data);
279 };
280
281 var select2RefFileSwitcher = function (targetElement, loadUrl, initialData) {
282 var formatResult = function (result, container, query) {
283 return formatSelect2SelectionRefs(result);
135 };
284 };
136
285
286 var formatSelection = function (data, container) {
287 var commit_ref = data;
288
289 var tmpl = '';
290 if (commit_ref.type === 'sha') {
291 tmpl = (commit_ref.raw_id || "").substr(0,8);
292 } else if (commit_ref.type === 'branch') {
293 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
294 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
295 } else if (commit_ref.type === 'tag') {
296 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
297 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
298 } else if (commit_ref.type === 'book') {
299 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
300 tmpl = tmpl.concat(escapeHtml(commit_ref.text));
301 }
302
303 var idx = commit_ref.idx || 0;
304 if (idx !== 0) {
305 tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx));
306 }
307 return tmpl
308 };
309
310 $(targetElement).select2({
311 dropdownAutoWidth: true,
312 width: "resolve",
313 containerCssClass: "drop-menu",
314 dropdownCssClass: "drop-menu-dropdown",
315 query: function(query) {
316
317 var cachedData = cachedDataSource[cacheKey];
318 if (cachedData) {
319 feedRefsData(query, cachedData)
320 } else {
321 loadRefsData(query)
322 }
323 },
324 initSelection: function(element, callback) {
325 callback(initialData);
326 },
327 formatResult: formatResult,
328 formatSelection: formatSelection
329 });
330
331 };
332
333 select2RefFileSwitcher('#refs_filter', loadUrl, initialCommitData);
334
335 $('#refs_filter').on('change', function(e) {
336 var data = $('#refs_filter').select2('data');
337 window.location = data.files_url
338 });
339
340 };
341
342 $(document).ready(function() {
343 timeagoActivate();
344
137 if ($('#trimmed_message_box').height() < 50) {
345 if ($('#trimmed_message_box').height() < 50) {
138 $('#message_expand').hide();
346 $('#message_expand').hide();
139 }
347 }
@@ -144,181 +352,18 b''
144 });
352 });
145
353
146 if (fileSourcePage) {
354 if (fileSourcePage) {
147 // variants for with source code, not tree view
355 initFileJS()
148
149 // select code link event
150 $("#hlcode").mouseup(getSelectionLink);
151
152 // file history select2
153 select2FileHistorySwitcher('#diff1', initialCommitData, state);
154
155 // show at, diff to actions handlers
156 $('#diff1').on('change', function(e) {
157 $('#diff_to_commit').removeClass('disabled').removeAttr("disabled");
158 $('#diff_to_commit').val(_gettext('Diff to Commit ') + e.val.truncateAfter(8, '...'));
159
160 $('#show_at_commit').removeClass('disabled').removeAttr("disabled");
161 $('#show_at_commit').val(_gettext('Show at Commit ') + e.val.truncateAfter(8, '...'));
162 });
163
164 $('#diff_to_commit').on('click', function(e) {
165 var diff1 = $('#diff1').val();
166 var diff2 = $('#diff2').val();
167
168 var url_data = {
169 repo_name: templateContext.repo_name,
170 source_ref: diff1,
171 source_ref_type: 'rev',
172 target_ref: diff2,
173 target_ref_type: 'rev',
174 merge: 1,
175 f_path: state.f_path
176 };
177 window.location = pyroutes.url('repo_compare', url_data);
178 });
179
180 $('#show_at_commit').on('click', function(e) {
181 var diff1 = $('#diff1').val();
182
183 var annotate = $('#annotate').val();
184 if (annotate === "True") {
185 var url = pyroutes.url('repo_files:annotated',
186 {'repo_name': templateContext.repo_name,
187 'commit_id': diff1, 'f_path': state.f_path});
188 } else {
356 } else {
189 var url = pyroutes.url('repo_files',
357 initTreeJS()
190 {'repo_name': templateContext.repo_name,
191 'commit_id': diff1, 'f_path': state.f_path});
192 }
193 window.location = url;
194
195 });
196
197 // show more authors
198 $('#show_authors').on('click', function(e) {
199 e.preventDefault();
200 var url = pyroutes.url('repo_file_authors',
201 {'repo_name': templateContext.repo_name,
202 'commit_id': state.rev, 'f_path': state.f_path});
203
204 $.pjax({
205 url: url,
206 data: 'annotate=${"1" if c.annotate else "0"}',
207 container: '#file_authors',
208 push: false,
209 timeout: pjaxTimeout
210 }).complete(function(){
211 $('#show_authors').hide();
212 })
213 });
214
215 // load file short history
216 $('#file_history_overview').on('click', function(e) {
217 e.preventDefault();
218 path = state.f_path;
219 if (path.indexOf("#") >= 0) {
220 path = path.slice(0, path.indexOf("#"));
221 }
222 var url = pyroutes.url('repo_changelog_file',
223 {'repo_name': templateContext.repo_name,
224 'commit_id': state.rev, 'f_path': path, 'limit': 6});
225 $('#file_history_container').show();
226 $('#file_history_container').html('<div class="file-history-inner">{0}</div>'.format(_gettext('Loading ...')));
227
228 $.pjax({
229 url: url,
230 container: '#file_history_container',
231 push: false,
232 timeout: pjaxTimeout
233 })
234 });
235
236 }
237 else {
238 getFilesMetadata();
239
240 // fuzzy file filter
241 fileBrowserListeners(state.node_list_url, state.url_base);
242
243 // switch to widget
244 select2RefSwitcher('#refs_filter', initialCommitData);
245 $('#refs_filter').on('change', function(e) {
246 var data = $('#refs_filter').select2('data');
247 curState.commit_id = data.raw_id;
248 $.pjax({url: data.files_url, container: '#pjax-container', timeout: pjaxTimeout});
249 });
250
251 $("#prev_commit_link").on('click', function(e) {
252 var data = $(this).data();
253 curState.commit_id = data.commitId;
254 });
255
256 $("#next_commit_link").on('click', function(e) {
257 var data = $(this).data();
258 curState.commit_id = data.commitId;
259 });
260
261 $('#at_rev').on("keypress", function(e) {
262 /* ENTER PRESSED */
263 if (e.keyCode === 13) {
264 var rev = $('#at_rev').val();
265 // explicit reload page here. with pjax entering bad input
266 // produces not so nice results
267 window.location = pyroutes.url('repo_files',
268 {'repo_name': templateContext.repo_name,
269 'commit_id': rev, 'f_path': state.f_path});
270 }
271 });
272 }
273 };
274
275 var pjaxTimeout = 5000;
276
277 $(document).pjax(".pjax-link", "#pjax-container", {
278 "fragment": "#pjax-content",
279 "maxCacheLength": 1000,
280 "timeout": pjaxTimeout
281 });
282
283 // define global back/forward states
284 var isPjaxPopState = false;
285 $(document).on('pjax:popstate', function() {
286 isPjaxPopState = true;
287 });
288
289 $(document).on('pjax:end', function(xhr, options) {
290 if (isPjaxPopState) {
291 isPjaxPopState = false;
292 callbacks();
293 _NODEFILTER.resetFilter();
294 }
358 }
295
359
296 // run callback for tracking if defined for google analytics etc.
297 // this is used to trigger tracking on pjax
298 if (typeof window.rhodecode_statechange_callback !== 'undefined') {
299 var state = getState('statechange');
300 rhodecode_statechange_callback(state.url, null)
301 }
302 });
303
304 $(document).on('pjax:success', function(event, xhr, options) {
305 if (event.target.id == "file_history_container") {
306 $('#file_history_overview').hide();
307 $('#file_history_overview_full').show();
308 timeagoActivate();
309 } else {
310 callbacks();
311 }
312 });
313
314 $(document).ready(function() {
315 callbacks();
316 var search_GET = "${request.GET.get('search','')}";
360 var search_GET = "${request.GET.get('search','')}";
317 if (search_GET === "1") {
361 if (search_GET === "1") {
318 _NODEFILTER.initFilter();
362 NodeFilter.initFilter();
363 NodeFilter.focus();
319 }
364 }
320 });
365 });
321
366
322 </script>
367 </script>
323
368
324 </%def>
369 </%def> No newline at end of file
@@ -1,7 +1,7 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${_('%s Files Add') % c.repo_name}
4 ${_('{} Files Add').format(c.repo_name)}
5 %if c.rhodecode_name:
5 %if c.rhodecode_name:
6 &middot; ${h.branding(c.rhodecode_name)}
6 &middot; ${h.branding(c.rhodecode_name)}
7 %endif
7 %endif
@@ -11,79 +11,64 b''
11 ${self.menu_items(active='repositories')}
11 ${self.menu_items(active='repositories')}
12 </%def>
12 </%def>
13
13
14 <%def name="breadcrumbs_links()">
14 <%def name="breadcrumbs_links()"></%def>
15 ${_('Add new file')} @ ${h.show_id(c.commit)} ${_('Branch')}: ${c.commit.branch}
16 </%def>
17
15
18 <%def name="menu_bar_subnav()">
16 <%def name="menu_bar_subnav()">
19 ${self.repo_menu(active='files')}
17 ${self.repo_menu(active='files')}
20 </%def>
18 </%def>
21
19
22 <%def name="main()">
20 <%def name="main()">
21
23 <div class="box">
22 <div class="box">
24 <div class="title">
23
25 ${self.repo_page_title(c.rhodecode_db_repo)}
24 <div class="edit-file-title">
25 <span class="title-heading">${_('Add new file')} @ <code>${h.show_id(c.commit)}</code></span>
26 % if c.commit.branch:
27 <span class="tag branchtag">
28 <i class="icon-branch"></i> ${c.commit.branch}
29 </span>
30 % endif
26 </div>
31 </div>
27 <div class="edit-file-title">
32
28 ${self.breadcrumbs()}
33 ${h.secure_form(h.route_path('repo_files_create_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path), id='eform', request=request)}
29 </div>
30 ${h.secure_form(h.route_path('repo_files_create_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path), id='eform', enctype="multipart/form-data", class_="form-horizontal", request=request)}
31 <div class="edit-file-fieldset">
34 <div class="edit-file-fieldset">
32 <div class="fieldset">
35 <div class="path-items">
33 <div id="destination-label" class="left-label">
36 <ul>
34 ${_('Path')}:
37 <li class="breadcrumb-path">
38 <div>
39 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path='')}"><i class="icon-home"></i></a> /
40 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path)}">${c.f_path}</a> ${('/' if c.f_path else '')}
41 </div>
42 </li>
43 <li class="location-path">
44 <input class="file-name-input input-small" type="text" value="" name="filename" id="filename" placeholder="${_('Filename e.g example.py, or docs/readme.md')}">
45 </li>
46 </ul>
47 </div>
48
35 </div>
49 </div>
36 <div class="right-content">
50
37 <div id="specify-custom-path-container">
51 <div class="table">
38 <span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path)}</span>
52 <div id="files_data">
39 <a class="custom-path-link" id="specify-custom-path" href="#">${_('Specify Custom Path')}</a>
53
54 <div id="codeblock" class="codeblock">
55 <div class="editor-items">
56 <div class="editor-action active show-editor pull-left" onclick="fileEditor.showEditor(); return false">
57 ${_('Edit')}
40 </div>
58 </div>
41 <div id="remove-custom-path-container" style="display: none;">
59
42 ${c.repo_name}/
60 <div class="editor-action show-preview pull-left" onclick="fileEditor.showPreview(); return false">
43 <input type="input-small" value="${c.f_path}" size="46" name="location" id="location">
61 ${_('Preview')}
44 <a class="custom-path-link" id="remove-custom-path" href="#">${_('Remove Custom Path')}</a>
45 </div>
62 </div>
63
64 <div class="pull-right">
65 ${h.dropdownmenu('line_wrap', 'off', [('on', _('Line wraps on')), ('off', _('line wraps off'))], extra_classes=['last-item'])}
66 </div>
67 <div class="pull-right">
68 ${h.dropdownmenu('set_mode','plain',[('plain', _('plain'))], enable_filter=True)}
46 </div>
69 </div>
47 </div>
70 </div>
48 <div id="filename_container" class="fieldset">
49 <div class="filename-label left-label">
50 ${_('Filename')}:
51 </div>
52 <div class="right-content">
53 <input class="input-small" type="text" value="" size="46" name="filename" id="filename">
54 <p>${_('or')} <a id="upload_file_enable" href="#">${_('Upload File')}</a></p>
55 </div>
56 </div>
57 <div id="upload_file_container" class="fieldset" style="display: none;">
58 <div class="filename-label left-label">
59 ${_('Filename')}:
60 </div>
61 <div class="right-content">
62 <input class="input-small" type="text" value="" size="46" name="filename_upload" id="filename_upload" placeholder="${_('No file selected')}">
63 </div>
64 <div class="filename-label left-label file-upload-label">
65 ${_('Upload file')}:
66 </div>
67 <div class="right-content file-upload-input">
68 <label for="upload_file" class="btn btn-default">Browse</label>
69
71
70 <input type="file" name="upload_file" id="upload_file">
71 <p>${_('or')} <a id="file_enable" href="#">${_('Create New File')}</a></p>
72 </div>
73 </div>
74 </div>
75 <div class="table">
76 <div id="files_data">
77 <div id="codeblock" class="codeblock">
78 <div class="code-header form" id="set_mode_header">
79 <div class="fields">
80 ${h.dropdownmenu('set_mode','plain',[('plain',_('plain'))],enable_filter=True)}
81 <label for="line_wrap">${_('line wraps')}</label>
82 ${h.dropdownmenu('line_wrap', 'off', [('on', _('on')), ('off', _('off')),])}
83
84 <div id="render_preview" class="btn btn-small preview hidden" >${_('Preview')}</div>
85 </div>
86 </div>
87 <div id="editor_container">
72 <div id="editor_container">
88 <pre id="editor_pre"></pre>
73 <pre id="editor_pre"></pre>
89 <textarea id="editor" name="content" ></textarea>
74 <textarea id="editor" name="content" ></textarea>
@@ -95,144 +80,35 b''
95
80
96 <div class="edit-file-fieldset">
81 <div class="edit-file-fieldset">
97 <div class="fieldset">
82 <div class="fieldset">
98 <div id="commit-message-label" class="commit-message-label left-label">
99 ${_('Commit Message')}:
100 </div>
101 <div class="right-content">
102 <div class="message">
83 <div class="message">
103 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
84 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
104 </div>
85 </div>
105 </div>
86 </div>
106 </div>
87 <div class="pull-left">
107 <div class="pull-right">
108 ${h.reset('reset',_('Cancel'),class_="btn btn-small")}
109 ${h.submit('commit_btn',_('Commit changes'),class_="btn btn-small btn-success")}
88 ${h.submit('commit_btn',_('Commit changes'), class_="btn btn-small btn-success")}
110 </div>
89 </div>
111 </div>
90 </div>
112 ${h.end_form()}
91 ${h.end_form()}
113 </div>
92 </div>
93
114 <script type="text/javascript">
94 <script type="text/javascript">
115
95
116 $('#commit_btn').on('click', function() {
96 $(document).ready(function () {
117 var button = $(this);
118 if (button.hasClass('clicked')) {
119 button.attr('disabled', true);
120 } else {
121 button.addClass('clicked');
122 }
123 });
124
125 $('#specify-custom-path').on('click', function(e){
126 e.preventDefault();
127 $('#specify-custom-path-container').hide();
128 $('#remove-custom-path-container').show();
129 $('#destination-label').css('margin-top', '13px');
130 });
131
132 $('#remove-custom-path').on('click', function(e){
133 e.preventDefault();
134 $('#specify-custom-path-container').show();
135 $('#remove-custom-path-container').hide();
136 $('#location').val('${c.f_path}');
137 $('#destination-label').css('margin-top', '0');
138 });
139
140 var hide_upload = function(){
141 $('#files_data').show();
142 $('#upload_file_container').hide();
143 $('#filename_container').show();
144 };
145
146 $('#file_enable').on('click', function(e){
147 e.preventDefault();
148 hide_upload();
149 });
150
151 $('#upload_file_enable').on('click', function(e){
152 e.preventDefault();
153 $('#files_data').hide();
154 $('#upload_file_container').show();
155 $('#filename_container').hide();
156 if (detectIE() && detectIE() <= 9) {
157 $('#upload_file_container .file-upload-input label').hide();
158 $('#upload_file_container .file-upload-input span').hide();
159 $('#upload_file_container .file-upload-input input').show();
160 }
161 });
162
163 $('#upload_file').on('change', function() {
164 if (this.files && this.files[0]) {
165 $('#filename_upload').val(this.files[0].name);
166 }
167 });
168
169 hide_upload();
170
171 var renderer = "";
172 var reset_url = "${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}";
173 var myCodeMirror = initCodeMirror('editor', reset_url, false);
174
175 var modes_select = $('#set_mode');
97 var modes_select = $('#set_mode');
98 var filename_selector = '#filename';
176 fillCodeMirrorOptions(modes_select);
99 fillCodeMirrorOptions(modes_select);
177
100
178 var filename_selector = '#filename';
101 fileEditor = new FileEditor('#editor');
179 var callback = function(filename, mimetype, mode){
102
180 CodeMirrorPreviewEnable(mode);
181 };
182 // on change of select field set mode
103 // on change of select field set mode
183 setCodeMirrorModeFromSelect(
104 setCodeMirrorModeFromSelect(modes_select, filename_selector, fileEditor.cm, null);
184 modes_select, filename_selector, myCodeMirror, callback);
185
105
186 // on entering the new filename set mode, from given extension
106 // on entering the new filename set mode, from given extension
187 setCodeMirrorModeFromInput(
107 setCodeMirrorModeFromInput(modes_select, filename_selector, fileEditor.cm, null);
188 modes_select, filename_selector, myCodeMirror, callback);
189
190 // if the file is renderable set line wraps automatically
191 if (renderer !== ""){
192 var line_wrap = 'on';
193 $($('#line_wrap option[value="'+line_wrap+'"]')[0]).attr("selected", "selected");
194 setCodeMirrorLineWrap(myCodeMirror, true);
195 }
196
197 // on select line wraps change the editor
198 $('#line_wrap').on('change', function(e){
199 var selected = e.currentTarget;
200 var line_wraps = {'on': true, 'off': false}[selected.value];
201 setCodeMirrorLineWrap(myCodeMirror, line_wraps)
202 });
203
204 // render preview/edit button
205 $('#render_preview').on('click', function(e){
206 if($(this).hasClass('preview')){
207 $(this).removeClass('preview');
208 $(this).html("${_('Edit')}");
209 $('#editor_preview').show();
210 $(myCodeMirror.getWrapperElement()).hide();
211
108
212 var possible_renderer = {
109 $('#filename').focus();
213 'rst':'rst',
214 'markdown':'markdown',
215 'gfm': 'markdown'}[myCodeMirror.getMode().name];
216 var _text = myCodeMirror.getValue();
217 var _renderer = possible_renderer || DEFAULT_RENDERER;
218 var post_data = {'text': _text, 'renderer': _renderer, 'csrf_token': CSRF_TOKEN};
219 $('#editor_preview').html(_gettext('Loading ...'));
220 var url = pyroutes.url('repo_commit_comment_preview',
221 {'repo_name': '${c.repo_name}',
222 'commit_id': '${c.commit.raw_id}'});
223
110
224 ajaxPOST(url, post_data, function(o){
225 $('#editor_preview').html(o);
226 })
227 }
228 else{
229 $(this).addClass('preview');
230 $(this).html("${_('Preview')}");
231 $('#editor_preview').hide();
232 $(myCodeMirror.getWrapperElement()).show();
233 }
234 });
111 });
235 $('#filename').focus();
236
112
237 </script>
113 </script>
238 </%def>
114 </%def>
@@ -2,53 +2,60 b''
2 <div id="codeblock" class="browserblock">
2 <div id="codeblock" class="browserblock">
3 <div class="browser-header">
3 <div class="browser-header">
4 <div class="browser-nav">
4 <div class="browser-nav">
5 ${h.form(h.current_route_path(request), method='GET', id='at_rev_form')}
5
6 <div class="info_box">
6 <div class="info_box">
7 ${h.hidden('refs_filter')}
7
8 <div class="info_box_elem previous">
8 <div class="info_box_elem previous">
9 <a id="prev_commit_link" data-commit-id="${c.prev_commit.raw_id}" class="pjax-link ${'disabled' if c.url_prev == '#' else ''}" href="${c.url_prev}" title="${_('Previous commit')}"><i class="icon-left"></i></a>
9 <a id="prev_commit_link" data-commit-id="${c.prev_commit.raw_id}" class=" ${('disabled' if c.url_prev == '#' else '')}" href="${c.url_prev}" title="${_('Previous commit')}"><i class="icon-left"></i></a>
10 </div>
10 </div>
11 <div class="info_box_elem">${h.text('at_rev',value=c.commit.idx)}</div>
11
12 ${h.hidden('refs_filter')}
13
12 <div class="info_box_elem next">
14 <div class="info_box_elem next">
13 <a id="next_commit_link" data-commit-id="${c.next_commit.raw_id}" class="pjax-link ${'disabled' if c.url_next == '#' else ''}" href="${c.url_next}" title="${_('Next commit')}"><i class="icon-right"></i></a>
15 <a id="next_commit_link" data-commit-id="${c.next_commit.raw_id}" class=" ${('disabled' if c.url_next == '#' else '')}" href="${c.url_next}" title="${_('Next commit')}"><i class="icon-right"></i></a>
14 </div>
16 </div>
15 </div>
17 </div>
16 ${h.end_form()}
17
18
18 <div id="search_activate_id" class="search_activate">
19 <a class="btn btn-default" id="filter_activate" href="javascript:void(0)">${_('Search File List')}</a>
20 </div>
21 <div id="search_deactivate_id" class="search_activate hidden">
22 <a class="btn btn-default" id="filter_deactivate" href="javascript:void(0)">${_('Close File List')}</a>
23 </div>
24 % if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
19 % if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
25 <div title="${_('Add New File')}" class="btn btn-primary new-file">
20 <div>
26 <a href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _anchor='edit')}">
21 <a class="btn btn-primary new-file" href="${h.route_path('repo_files_upload_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
27 ${_('Add File')}</a>
22 ${_('Upload File')}
28 </div>
23 </a>
29 % endif
24 <a class="btn btn-primary new-file" href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
30 % if c.enable_downloads:
25 ${_('Add File')}
31 <% at_path = '{}.zip'.format(request.GET.get('at') or c.commit.raw_id[:6]) %>
32 <div title="${_('Download tree at {}').format(at_path)}" class="btn btn-default new-file">
33 <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id))}">
34 ${_('Download tree at {}').format(at_path)}
35 </a>
26 </a>
36 </div>
27 </div>
37 % endif
28 % endif
29
30 % if c.enable_downloads:
31 <% at_path = '{}'.format(request.GET.get('at') or c.commit.raw_id[:6]) %>
32 <div class="btn btn-default new-file">
33 % if c.f_path == '/':
34 <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id))}">
35 ${_('Download full tree ZIP')}
36 </a>
37 % else:
38 <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id), _query={'at_path':c.f_path})}">
39 ${_('Download this tree ZIP')}
40 </a>
41 % endif
42 </div>
43 % endif
44
45 <div class="files-quick-filter">
46 <ul class="files-filter-box">
47 <li class="files-filter-box-path">
48 <i class="icon-search"></i>
49 </li>
50 <li class="files-filter-box-input">
51 <input onkeydown="NodeFilter.initFilter(event)" class="init" type="text" placeholder="Quick filter" name="filter" size="25" id="node_filter" autocomplete="off">
52 </li>
53 </ul>
54 </div>
38 </div>
55 </div>
39
56
40 <div class="browser-search">
41 <div class="node-filter">
42 <div class="node_filter_box hidden" id="node_filter_box_loading" >${_('Loading file list...')}</div>
43 <div class="node_filter_box hidden" id="node_filter_box" >
44 <div class="node-filter-path">${h.get_last_path_part(c.file)}/</div>
45 <div class="node-filter-input">
46 <input class="init" type="text" name="filter" size="25" id="node_filter" autocomplete="off">
47 </div>
57 </div>
48 </div>
58
49 </div>
50 </div>
51 </div>
52 ## file tree is computed from caches, and filled in
59 ## file tree is computed from caches, and filled in
53 <div id="file-tree">
60 <div id="file-tree">
54 ${c.file_tree |n}
61 ${c.file_tree |n}
@@ -1,5 +1,11 b''
1 <div id="file-tree-wrapper" class="browser-body ${'full-load' if c.full_load else ''}">
1 <%
2 <table class="code-browser rctable">
2 if request.GET.get('at'):
3 query={'at': request.GET.get('at')}
4 else:
5 query=None
6 %>
7 <div id="file-tree-wrapper" class="browser-body ${('full-load' if c.full_load else '')}">
8 <table class="code-browser rctable repo_summary">
3 <thead>
9 <thead>
4 <tr>
10 <tr>
5 <th>${_('Name')}</th>
11 <th>${_('Name')}</th>
@@ -11,19 +17,13 b''
11 </thead>
17 </thead>
12
18
13 <tbody id="tbody">
19 <tbody id="tbody">
14 %if c.file.parent:
20 <tr>
15 <tr class="parity0">
21 <td colspan="5">
16 <td class="td-componentname">
22
17 <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.file.parent.path)}" class="pjax-link">
23 ${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path, request.GET.get('at'), limit_items=True)}
18 <i class="icon-directory"></i>..
24
19 </a>
20 </td>
25 </td>
21 <td></td>
22 <td></td>
23 <td></td>
24 <td></td>
25 </tr>
26 </tr>
26 %endif
27 %for cnt,node in enumerate(c.file):
27 %for cnt,node in enumerate(c.file):
28 <tr class="parity${cnt%2}">
28 <tr class="parity${cnt%2}">
29 <td class="td-componentname">
29 <td class="td-componentname">
@@ -38,8 +38,9 b''
38 % endif
38 % endif
39 </span>
39 </span>
40 % else:
40 % else:
41 <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=h.safe_unicode(node.path))}" class="pjax-link">
41
42 <i class="${'icon-file-text browser-file' if node.is_file() else 'icon-directory browser-dir'}"></i>${node.name}
42 <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=h.safe_unicode(node.path), _query=query)}">
43 <i class="${('icon-file-text browser-file' if node.is_file() else 'icon-directory browser-dir')}"></i>${node.name}
43 </a>
44 </a>
44 % endif
45 % endif
45 </td>
46 </td>
@@ -1,7 +1,7 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${_('%s Files Delete') % c.repo_name}
4 ${_('{} Files Delete').format(c.repo_name)}
5 %if c.rhodecode_name:
5 %if c.rhodecode_name:
6 &middot; ${h.branding(c.rhodecode_name)}
6 &middot; ${h.branding(c.rhodecode_name)}
7 %endif
7 %endif
@@ -11,32 +11,40 b''
11 ${self.menu_items(active='repositories')}
11 ${self.menu_items(active='repositories')}
12 </%def>
12 </%def>
13
13
14 <%def name="breadcrumbs_links()">
14 <%def name="breadcrumbs_links()"></%def>
15 ${_('Delete file')} @ ${h.show_id(c.commit)}
16 </%def>
17
15
18 <%def name="menu_bar_subnav()">
16 <%def name="menu_bar_subnav()">
19 ${self.repo_menu(active='files')}
17 ${self.repo_menu(active='files')}
20 </%def>
18 </%def>
21
19
22 <%def name="main()">
20 <%def name="main()">
21
23 <div class="box">
22 <div class="box">
24 <div class="title">
23
25 ${self.repo_page_title(c.rhodecode_db_repo)}
24 <div class="edit-file-title">
25 <span class="title-heading">${_('Delete file')} @ <code>${h.show_id(c.commit)}</code></span>
26 % if c.commit.branch:
27 <span class="tag branchtag">
28 <i class="icon-branch"></i> ${c.commit.branch}
29 </span>
30 % endif
26 </div>
31 </div>
27 <div class="edit-file-title">
32
28 ${self.breadcrumbs()}
33 ${h.secure_form(h.route_path('repo_files_delete_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path), id='eform', request=request)}
29 </div>
30 ${h.secure_form(h.route_path('repo_files_delete_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path), id='eform', class_="form-horizontal", request=request)}
31 <div class="edit-file-fieldset">
34 <div class="edit-file-fieldset">
32 <div class="fieldset">
35 <div class="path-items">
33 <div id="destination-label" class="left-label">
36 <li class="breadcrumb-path">
34 ${_('Path')}:
37 <div>
38 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path='')}"><i class="icon-home"></i></a> /
39 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.file.dir_path)}">${c.file.dir_path}</a> ${('/' if c.file.dir_path else '')}
35 </div>
40 </div>
36 <div class="right-content">
41 </li>
37 <span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path)}</span>
42 <li class="location-path">
43 <input type="hidden" value="${c.f_path}" name="root_path">
44 <input class="file-name-input input-small" type="text" value="${c.file.name}" name="filename" id="filename" disabled="disabled">
45 </li>
38 </div>
46 </div>
39 </div>
47
40 </div>
48 </div>
41
49
42 <div id="codeblock" class="codeblock delete-file-preview">
50 <div id="codeblock" class="codeblock delete-file-preview">
@@ -56,20 +64,26 b''
56
64
57 <div class="edit-file-fieldset">
65 <div class="edit-file-fieldset">
58 <div class="fieldset">
66 <div class="fieldset">
59 <div id="commit-message-label" class="commit-message-label left-label">
60 ${_('Commit Message')}:
61 </div>
62 <div class="right-content">
63 <div class="message">
67 <div class="message">
64 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
68 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
65 </div>
69 </div>
66 </div>
70 </div>
67 </div>
71 <div class="pull-left">
68 <div class="pull-right">
72 ${h.submit('commit',_('Commit changes'),class_="btn btn-small btn-danger-action")}
69 ${h.reset('reset',_('Cancel'),class_="btn btn-small btn-danger")}
70 ${h.submit('commit',_('Delete File'),class_="btn btn-small btn-danger-action")}
71 </div>
73 </div>
72 </div>
74 </div>
73 ${h.end_form()}
75 ${h.end_form()}
74 </div>
76 </div>
77
78
79 <script type="text/javascript">
80
81 $(document).ready(function () {
82
83 fileEditor = new FileEditor('#editor');
84
85 });
86
87 </script>
88
75 </%def>
89 </%def>
@@ -1,7 +1,7 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${_('%s File Edit') % c.repo_name}
4 ${_('{} Files Edit').format(c.repo_name)}
5 %if c.rhodecode_name:
5 %if c.rhodecode_name:
6 &middot; ${h.branding(c.rhodecode_name)}
6 &middot; ${h.branding(c.rhodecode_name)}
7 %endif
7 %endif
@@ -11,80 +11,65 b''
11 ${self.menu_items(active='repositories')}
11 ${self.menu_items(active='repositories')}
12 </%def>
12 </%def>
13
13
14 <%def name="breadcrumbs_links()">
14 <%def name="breadcrumbs_links()"></%def>
15 ${_('Edit file')} @ ${h.show_id(c.commit)}
16 </%def>
17
15
18 <%def name="menu_bar_subnav()">
16 <%def name="menu_bar_subnav()">
19 ${self.repo_menu(active='files')}
17 ${self.repo_menu(active='files')}
20 </%def>
18 </%def>
21
19
22 <%def name="main()">
20 <%def name="main()">
23 <% renderer = h.renderer_from_filename(c.f_path)%>
21
24 <div class="box">
22 <div class="box">
25 <div class="title">
23
26 ${self.repo_page_title(c.rhodecode_db_repo)}
24 <div class="edit-file-title">
25 <span class="title-heading">${_('Edit file')} @ <code>${h.show_id(c.commit)}</code></span>
26 % if c.commit.branch:
27 <span class="tag branchtag">
28 <i class="icon-branch"></i> ${c.commit.branch}
29 </span>
30 % endif
27 </div>
31 </div>
28 <div class="edit-file-title">
32
29 ${self.breadcrumbs()}
33 ${h.secure_form(h.route_path('repo_files_update_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path), id='eform', request=request)}
30 </div>
31 <div class="edit-file-fieldset">
34 <div class="edit-file-fieldset">
32 <div class="fieldset">
35 <div class="path-items">
33 <div id="destination-label" class="left-label">
36 <ul>
34 ${_('Path')}:
37 <li class="breadcrumb-path">
38 <div>
39 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path='')}"><i class="icon-home"></i></a> /
40 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.file.dir_path)}">${c.file.dir_path}</a> ${('/' if c.file.dir_path else '')}
35 </div>
41 </div>
36 <div class="right-content">
42 </li>
37 <div id="specify-custom-path-container">
43 <li class="location-path">
38 <span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path)}</span>
44 <input type="hidden" value="${c.f_path}" name="root_path">
45 <input class="file-name-input input-small" type="text" value="${c.file.name}" name="filename" id="filename" placeholder="${_('Filename e.g example.py, or docs/readme.md')}">
46 </li>
47 </ul>
39 </div>
48 </div>
40 </div>
49
41 </div>
42 </div>
50 </div>
43
51
44 <div class="table">
52 <div class="table">
45 ${h.secure_form(h.route_path('repo_files_update_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path), id='eform', request=request)}
53 <div id="files_data">
54
46 <div id="codeblock" class="codeblock" >
55 <div id="codeblock" class="codeblock">
47 <div class="code-header">
56 <div class="editor-items">
48 <div class="stats">
57 <div class="editor-action active show-editor pull-left" onclick="fileEditor.showEditor(); return false">
49 <i class="icon-file"></i>
58 ${_('Edit')}
50 <span class="item">${h.link_to("r%s:%s" % (c.file.commit.idx,h.short_id(c.file.commit.raw_id)),h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.file.commit.raw_id))}</span>
59 </div>
51 <span class="item">${h.format_byte_size_binary(c.file.size)}</span>
52 <span class="item last">${c.file.mimetype}</span>
53 <div class="buttons">
54 <a class="btn btn-mini" href="${h.route_path('repo_changelog_file',repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path)}">
55 <i class="icon-time"></i> ${_('history')}
56 </a>
57
60
58 % if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
61 <div class="editor-action show-preview pull-left" onclick="fileEditor.showPreview(); return false">
59 % if not c.file.is_binary:
62 ${_('Preview')}
60 %if True:
63 </div>
61 ${h.link_to(_('source'), h.route_path('repo_files', repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path),class_="btn btn-mini")}
62 %else:
63 ${h.link_to(_('annotation'),h.route_path('repo_files:annotated',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path),class_="btn btn-mini")}
64 %endif
65
64
66 <a class="btn btn-mini" href="${h.route_path('repo_file_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
65 <div class="pull-right">
67 ${_('raw')}
66 ${h.dropdownmenu('line_wrap', 'off', [('on', _('Line wraps on')), ('off', _('line wraps off')),])}
68 </a>
67 </div>
69 <a class="btn btn-mini" href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
68 <div class="pull-right">
70 <i class="icon-archive"></i> ${_('download')}
69 ${h.dropdownmenu('set_mode','plain',[('plain', _('plain'))],enable_filter=True)}
71 </a>
72 % endif
73 % endif
74 </div>
70 </div>
75 </div>
71 </div>
76 <div class="form">
77 <label for="set_mode">${_('Editing file')}:</label>
78 ${'%s /' % c.file.dir_path if c.file.dir_path else c.file.dir_path}
79 <input id="filename" type="text" name="filename" value="${c.file.name}">
80
72
81 ${h.dropdownmenu('set_mode','plain',[('plain',_('plain'))],enable_filter=True)}
82 <label for="line_wrap">${_('line wraps')}</label>
83 ${h.dropdownmenu('line_wrap', 'off', [('on', _('on')), ('off', _('off')),])}
84
85 <div id="render_preview" class="btn btn-small preview hidden">${_('Preview')}</div>
86 </div>
87 </div>
88 <div id="editor_container">
73 <div id="editor_container">
89 <pre id="editor_pre"></pre>
74 <pre id="editor_pre"></pre>
90 <textarea id="editor" name="content" >${h.escape(c.file.content)|n}</textarea>
75 <textarea id="editor" name="content" >${h.escape(c.file.content)|n}</textarea>
@@ -92,106 +77,48 b''
92 </div>
77 </div>
93 </div>
78 </div>
94 </div>
79 </div>
80 </div>
95
81
96 <div class="edit-file-fieldset">
82 <div class="edit-file-fieldset">
97 <div class="fieldset">
83 <div class="fieldset">
98 <div id="commit-message-label" class="commit-message-label left-label">
99 ${_('Commit Message')}:
100 </div>
101 <div class="right-content">
102 <div class="message">
84 <div class="message">
103 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
85 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
104 </div>
86 </div>
105 </div>
87 </div>
106 </div>
88 <div class="pull-left">
107 <div class="pull-right">
89 ${h.submit('commit_btn',_('Commit changes'), class_="btn btn-small btn-success")}
108 ${h.reset('reset',_('Cancel'),class_="btn btn-small")}
109 ${h.submit('commit',_('Commit changes'),class_="btn btn-small btn-success")}
110 </div>
90 </div>
111 </div>
91 </div>
112 ${h.end_form()}
92 ${h.end_form()}
113 </div>
93 </div>
114
94
115 <script type="text/javascript">
95 <script type="text/javascript">
96
116 $(document).ready(function(){
97 $(document).ready(function() {
117 var renderer = "${renderer}";
118 var reset_url = "${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.file.path)}";
119 var myCodeMirror = initCodeMirror('editor', reset_url);
120
121 var modes_select = $('#set_mode');
98 var modes_select = $('#set_mode');
99 var filename_selector = '#filename';
122 fillCodeMirrorOptions(modes_select);
100 fillCodeMirrorOptions(modes_select);
123
101
102 fileEditor = new FileEditor('#editor');
103
124 // try to detect the mode based on the file we edit
104 // try to detect the mode based on the file we edit
125 var mimetype = "${c.file.mimetype}";
105 var detected_mode = detectCodeMirrorMode("${c.file.name}", "${c.file.mimetype}");
126 var detected_mode = detectCodeMirrorMode(
127 "${c.file.name}", mimetype);
128
106
129 if(detected_mode){
107 if (detected_mode) {
130 setCodeMirrorMode(myCodeMirror, detected_mode);
108 setCodeMirrorMode(fileEditor.cm, detected_mode);
131 $(modes_select).select2("val", mimetype);
109
132 $(modes_select).change();
110 var mimetype = $(modes_select).find("option[mode={0}]".format(detected_mode)).val();
133 setCodeMirrorMode(myCodeMirror, detected_mode);
111 $(modes_select).select2("val", mimetype).trigger('change');
134 }
112 }
135
113
136 var filename_selector = '#filename';
137 var callback = function(filename, mimetype, mode){
138 CodeMirrorPreviewEnable(mode);
139 };
140 // on change of select field set mode
114 // on change of select field set mode
141 setCodeMirrorModeFromSelect(
115 setCodeMirrorModeFromSelect(modes_select, filename_selector, fileEditor.cm, null);
142 modes_select, filename_selector, myCodeMirror, callback);
143
116
144 // on entering the new filename set mode, from given extension
117 // on entering the new filename set mode, from given extension
145 setCodeMirrorModeFromInput(
118 setCodeMirrorModeFromInput(modes_select, filename_selector, fileEditor.cm, null);
146 modes_select, filename_selector, myCodeMirror, callback);
147
119
148 // if the file is renderable set line wraps automatically
149 if (renderer !== ""){
150 var line_wrap = 'on';
151 $($('#line_wrap option[value="'+line_wrap+'"]')[0]).attr("selected", "selected");
152 setCodeMirrorLineWrap(myCodeMirror, true);
153 }
154 // on select line wraps change the editor
155 $('#line_wrap').on('change', function(e){
156 var selected = e.currentTarget;
157 var line_wraps = {'on': true, 'off': false}[selected.value];
158 setCodeMirrorLineWrap(myCodeMirror, line_wraps)
159 });
120 });
160
121
161 // render preview/edit button
162 if (mimetype === 'text/x-rst' || mimetype === 'text/plain') {
163 $('#render_preview').removeClass('hidden');
164 }
165 $('#render_preview').on('click', function(e){
166 if($(this).hasClass('preview')){
167 $(this).removeClass('preview');
168 $(this).html("${_('Edit')}");
169 $('#editor_preview').show();
170 $(myCodeMirror.getWrapperElement()).hide();
171
122
172 var possible_renderer = {
173 'rst':'rst',
174 'markdown':'markdown',
175 'gfm': 'markdown'}[myCodeMirror.getMode().name];
176 var _text = myCodeMirror.getValue();
177 var _renderer = possible_renderer || DEFAULT_RENDERER;
178 var post_data = {'text': _text, 'renderer': _renderer, 'csrf_token': CSRF_TOKEN};
179 $('#editor_preview').html(_gettext('Loading ...'));
180 var url = pyroutes.url('repo_commit_comment_preview',
181 {'repo_name': '${c.repo_name}',
182 'commit_id': '${c.commit.raw_id}'});
183 ajaxPOST(url, post_data, function(o){
184 $('#editor_preview').html(o);
185 })
186 }
187 else{
188 $(this).addClass('preview');
189 $(this).html("${_('Preview')}");
190 $('#editor_preview').hide();
191 $(myCodeMirror.getWrapperElement()).show();
192 }
193 });
194
195 })
196 </script>
123 </script>
197 </%def>
124 </%def>
@@ -1,7 +1,7 b''
1 <%def name="title(*args)">
1 <%def name="title(*args)">
2 ${_('%s Files') % c.repo_name}
2 ${_('{} Files').format(c.repo_name)}
3 %if hasattr(c,'file'):
3 %if hasattr(c,'file'):
4 &middot; ${h.safe_unicode(c.file.path) or '\\'}
4 &middot; ${(h.safe_unicode(c.file.path) or '\\')}
5 %endif
5 %endif
6
6
7 %if c.rhodecode_name:
7 %if c.rhodecode_name:
@@ -9,47 +9,26 b''
9 %endif
9 %endif
10 </%def>
10 </%def>
11
11
12 <div id="pjax-content" data-title="${self.title()}">
12 <div>
13
13 <div class="summary-detail">
14 <div class="summary-detail">
14 <div class="summary-detail-header">
15 <div class="summary-detail-header">
15 <div class="breadcrumbs files_location">
16
16 <h4>
17 ${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path)}
18 %if c.annotate:
19 - ${_('annotation')}
20 %endif
21 </h4>
22 </div>
23 <div class="btn-collapse" data-toggle="summary-details">
24 ${_('Show More')}
25 </div>
26 </div><!--end summary-detail-header-->
17 </div><!--end summary-detail-header-->
27
18
28 % if c.file.is_submodule():
19 % if c.file.is_submodule():
29 <span class="submodule-dir">Submodule ${h.escape(c.file.name)}</span>
20 <span class="submodule-dir">Submodule ${h.escape(c.file.name)}</span>
30 % elif c.file.is_dir():
21 % elif c.file.is_dir():
31 <%include file='file_tree_detail.mako'/>
22 <%include file='files_tree_header.mako'/>
32 % else:
23 % else:
33 <%include file='files_detail.mako'/>
24 <%include file='files_source_header.mako'/>
34 % endif
25 % endif
35
26
36 </div> <!--end summary-detail-->
27 </div> <!--end summary-detail-->
37 <script>
38 // set the pageSource variable
39 var fileSourcePage = ${c.file_source_page};
40 </script>
41 % if c.file.is_dir():
28 % if c.file.is_dir():
42 <div id="commit-stats" class="sidebar-right">
43 <%include file='file_tree_author_box.mako'/>
44 </div>
45
46 <%include file='files_browser.mako'/>
29 <%include file='files_browser.mako'/>
47 % else:
30 % else:
48 <div id="file_authors" class="sidebar-right">
49 <%include file='file_authors_box.mako'/>
50 </div>
51
52 <%include file='files_source.mako'/>
31 <%include file='files_source.mako'/>
53 % endif
32 % endif
54
33
55 </div> No newline at end of file
34 </div>
@@ -1,71 +1,100 b''
1 <%namespace name="sourceblock" file="/codeblocks/source.mako"/>
1 <%namespace name="sourceblock" file="/codeblocks/source.mako"/>
2
2
3 <div id="codeblock" class="codeblock">
3 <div id="codeblock" class="browserblock">
4 <div class="browser-header">
5 <div class="browser-nav">
6 <div class="pull-left">
7 ## loads the history for a file
8 ${h.hidden('file_refs_filter')}
9 </div>
10
11 <div class="pull-right">
12
13 ## Download
14 % if c.lf_node:
15 <a class="btn btn-default" href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _query=dict(lf=1))}">
16 ${_('Download largefile')}
17 </a>
18 % else:
19 <a class="btn btn-default" href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
20 ${_('Download file')}
21 </a>
22 % endif
23
24 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
25 ## on branch head, can edit files
26 %if c.on_branch_head and c.branch_or_raw_id:
27 ## binary files are delete only
28 % if c.file.is_binary:
29 ${h.link_to(_('Edit'), '#Edit', class_="btn btn-default disabled tooltip", title=_('Editing binary files not allowed'))}
30 ${h.link_to(_('Delete'), h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path),class_="btn btn-danger")}
31 % else:
32 <a class="btn btn-default" href="${h.route_path('repo_files_edit_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path)}">
33 ${_('Edit on branch: ')}<code>${c.branch_name}</code>
34 </a>
35
36 <a class="btn btn-danger" href="${h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path)}">
37 ${_('Delete')}
38 </a>
39 % endif
40 ## not on head, forbid all
41 % else:
42 ${h.link_to(_('Edit'), '#Edit', class_="btn btn-default disabled tooltip", title=_('Editing files allowed only when on branch head commit'))}
43 ${h.link_to(_('Delete'), '#Delete', class_="btn btn-default btn-danger disabled tooltip", title=_('Deleting files allowed only when on branch head commit'))}
44 % endif
45 %endif
46
47 </div>
48 </div>
49 <div id="file_history_container"></div>
50
51 </div>
52 </div>
53
54 <div class="codeblock">
4 <div class="codeblock-header">
55 <div class=" codeblock-header">
5 <div class="stats">
56 <div class="file-filename">
6 <span class="stats-filename">
57 <i class="icon-file"></i> ${c.file}
7 <strong>
58 </div>
8 <i class="icon-file-text"></i>
9 ${c.file.unicode_path_safe}
10 </strong>
11 </span>
12 <span class="item last"><i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${c.f_path}" title="${_('Copy the full path')}"></i></span>
13 <br/>
14
59
60 <div class="file-stats">
61
62 <div class="stats-info">
63 <span class="stats-first-item">${c.file.lines()[0]} ${_ungettext('line', 'lines', c.file.lines()[0])}</span>
64
65 <span> | ${h.format_byte_size_binary(c.file.size)}</span>
15 % if c.lf_node:
66 % if c.lf_node:
16 <span title="${_('This file is a pointer to large binary file')}"> | ${_('LargeFile')} ${h.format_byte_size_binary(c.lf_node.size)} </span>
67 <span title="${_('This file is a pointer to large binary file')}"> | ${_('LargeFile')} ${h.format_byte_size_binary(c.lf_node.size)} </span>
17 % endif
68 % endif
18
19 <span class="stats-first-item">${c.file.lines()[0]} ${_ungettext('line', 'lines', c.file.lines()[0])}</span>
20 <span> | ${h.format_byte_size_binary(c.file.size)}</span>
21 <span> | ${c.file.mimetype} </span>
69 <span> | ${c.file.mimetype} </span>
22 <span> | ${h.get_lexer_for_filenode(c.file).__class__.__name__}</span>
70 <span> | ${h.get_lexer_for_filenode(c.file).__class__.__name__}</span>
23
71 </div>
72 </div>
24 </div>
73 </div>
25 <div class="buttons">
74
26 <a id="file_history_overview" href="#">
75 <div class="path clear-fix">
76 <div class="pull-left">
77 ${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path, request.GET.get('at'))}
78 </div>
79
80 <div class="pull-right stats">
81 <a id="file_history_overview" href="#loadHistory">
27 ${_('History')}
82 ${_('History')}
28 </a>
83 </a>
29 <a id="file_history_overview_full" style="display: none" href="${h.route_path('repo_changelog_file',repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path)}">
84 |
30 ${_('Show Full History')}
31 </a> |
32 %if c.annotate:
85 %if c.annotate:
33 ${h.link_to(_('Source'), h.route_path('repo_files', repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))}
86 ${h.link_to(_('Source'), h.route_path('repo_files', repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))}
34 %else:
87 %else:
35 ${h.link_to(_('Annotation'), h.route_path('repo_files:annotated',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))}
88 ${h.link_to(_('Annotation'), h.route_path('repo_files:annotated',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))}
36 %endif
89 %endif
37 | ${h.link_to(_('Raw'), h.route_path('repo_file_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))}
90 | ${h.link_to(_('Raw'), h.route_path('repo_file_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))}
38 |
39 % if c.lf_node:
40 <a href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _query=dict(lf=1))}">
41 ${_('Download largefile')}
42 </a>
43 % else:
44 <a href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
45 ${_('Download')}
46 </a>
47 % endif
48
91
49 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
92 </div>
50 |
93 <div class="clear-fix"></div>
51 %if c.on_branch_head and c.branch_or_raw_id and not c.file.is_binary:
52 <a href="${h.route_path('repo_files_edit_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit')}">
53 ${_('Edit on Branch:{}').format(c.branch_name)}
54 </a>
55 | <a class="btn-danger btn-link" href="${h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit')}">${_('Delete')}
56 </a>
57 %elif c.on_branch_head and c.branch_or_raw_id and c.file.is_binary:
58 ${h.link_to(_('Edit'), '#', class_="btn btn-link disabled tooltip", title=_('Editing binary files not allowed'))}
59 | ${h.link_to(_('Delete'), h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit'),class_="btn-danger btn-link")}
60 %else:
61 ${h.link_to(_('Edit'), '#', class_="btn btn-link disabled tooltip", title=_('Editing files allowed only when on branch head commit'))}
62 | ${h.link_to(_('Delete'), '#', class_="btn btn-danger btn-link disabled tooltip", title=_('Deleting files allowed only when on branch head commit'))}
63 %endif
64 %endif
65 </div>
94 </div>
66 </div>
95
67 <div id="file_history_container"></div>
96 <div class="code-body clear-fix ">
68 <div class="code-body">
97
69 %if c.file.is_binary:
98 %if c.file.is_binary:
70 <% rendered_binary = h.render_binary(c.repo_name, c.file)%>
99 <% rendered_binary = h.render_binary(c.repo_name, c.file)%>
71 % if rendered_binary:
100 % if rendered_binary:
@@ -106,6 +135,7 b''
106 %endif
135 %endif
107 %endif
136 %endif
108 </div>
137 </div>
138
109 </div>
139 </div>
110
140
111 <script type="text/javascript">
141 <script type="text/javascript">
@@ -1,69 +1,61 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="file_base" file="/files/base.mako"/>
2 <%namespace name="file_base" file="/files/base.mako"/>
2
3
4 <div class="summary">
5 <div class="fieldset">
6 <div class="left-content">
7
8 <div class="left-content-avatar">
9 ${base.gravatar(c.file_last_commit.author_email, 30)}
10 </div>
11
12 <div class="left-content-message">
3 <div class="fieldset collapsable-content no-hide" data-toggle="summary-details">
13 <div class="fieldset collapsable-content no-hide" data-toggle="summary-details">
4 <div class="left-label">
14 <div class="commit truncate-wrap">${h.urlify_commit_message(h.chop_at_smart(c.commit.message, '\n', suffix_if_chopped='...'), c.repo_name)}</div>
5 ${_('Commit Description')}:
6 </div>
7 <div class="commit right-content truncate-wrap">${h.urlify_commit_message(h.chop_at_smart(c.commit.message, '\n', suffix_if_chopped='...'), c.repo_name)}</div>
8 </div>
15 </div>
9
16
10 <div class="fieldset collapsable-content" data-toggle="summary-details">
17 <div class="fieldset collapsable-content" data-toggle="summary-details">
11 <div class="left-label">
18 <div class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
12 ${_('Commit Description')}:
13 </div>
19 </div>
14 <div class="commit right-content">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
20
21 <div class="fieldset" data-toggle="summary-details">
22 <div class="" id="file_authors">
23 ## loads single author, or ALL
24 <%include file='file_authors_box.mako'/>
25 </div>
26 </div>
15 </div>
27 </div>
16
28
29 <div class="fieldset collapsable-content" data-toggle="summary-details">
30 <div class="left-label-summary-files">
31 <p>${_('File last commit')}</p>
32 <div class="right-label-summary">
33 <code><a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.file_last_commit.raw_id)}">${h.show_id(c.file_last_commit)}</a></code>
17
34
18 <div class="fieldset " data-toggle="summary-details">
35 ${file_base.refs(c.file_last_commit)}
19 <div class="left-label">
36 </div>
20 ${_('References')}:
37 </div>
38 </div>
21 </div>
39 </div>
40
22 <div class="right-content">
41 <div class="right-content">
23 <div class="tags tags-main">
42 <div data-toggle="summary-details">
43 <div class="tags commit-info tags-main">
24 <code><a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">${h.show_id(c.commit)}</a></code>
44 <code><a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">${h.show_id(c.commit)}</a></code>
25 ${file_base.refs(c.commit)}
45 ${file_base.refs(c.commit)}
26 </div>
46 </div>
27 </div>
47 </div>
28 </div>
48 </div>
29
49
30 <div class="fieldset collapsable-content" data-toggle="summary-details">
50 <div class="clear-fix"></div>
31 <div class="left-label">
51
32 ${_('File last commit')}:
52 <div class="btn-collapse" data-toggle="summary-details">
53 ${_('Show More')}
33 </div>
54 </div>
34 <div class="right-content">
35 <div class="tags">
36 <code><a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.file_last_commit.raw_id)}">${h.show_id(c.file_last_commit)}</a></code>
37
55
38 ${file_base.refs(c.file_last_commit)}
39 </div>
40 </div>
56 </div>
41 </div>
57 </div>
42
58
43
44 <div class="fieldset collapsable-content" data-toggle="summary-details">
45 <div class="left-label">
46 ${_('Show/Diff file')}:
47 </div>
48 <div class="right-content">
49 ${h.hidden('diff1')}
50 ${h.hidden('diff2',c.commit.raw_id)}
51 ${h.hidden('annotate', c.annotate)}
52 </div>
53 </div>
54
55
56 <div class="fieldset collapsable-content" data-toggle="summary-details">
57 <div class="left-label">
58 ${_('Action')}:
59 </div>
60 <div class="right-content">
61 ${h.submit('diff_to_commit',_('Diff to Commit'),class_="btn disabled",disabled="true")}
62 ${h.submit('show_at_commit',_('Show at Commit'),class_="btn disabled",disabled="true")}
63 </div>
64 </div>
65
66
67 <script>
59 <script>
68 collapsableContent();
60 collapsableContent();
69 </script> No newline at end of file
61 </script>
@@ -1,27 +1,31 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="file_base" file="/files/base.mako"/>
2 <%namespace name="file_base" file="/files/base.mako"/>
2
3
4 <div class="summary">
5 <div class="fieldset">
6 <div class="left-content">
7
8 <div class="left-content-avatar">
9 ${base.gravatar(c.commit.author_email, 30)}
10 </div>
11
12 <div class="left-content-message">
3 <div class="fieldset collapsable-content no-hide" data-toggle="summary-details">
13 <div class="fieldset collapsable-content no-hide" data-toggle="summary-details">
4 <div class="left-label">
14 <div class="commit truncate-wrap">${h.urlify_commit_message(h.chop_at_smart(c.commit.message, '\n', suffix_if_chopped='...'), c.repo_name)}</div>
5 ${_('Description')}:
6 </div>
7 <div class="commit right-content truncate-wrap">${h.urlify_commit_message(h.chop_at_smart(c.commit.message, '\n', suffix_if_chopped='...'), c.repo_name)}</div>
8 </div>
15 </div>
9
16
10 <div class="fieldset collapsable-content" data-toggle="summary-details">
17 <div class="fieldset collapsable-content" data-toggle="summary-details">
11 <div class="left-label">
18 <div class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
12 ${_('Description')}:
13 </div>
14 <div class="commit right-content">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
15 </div>
19 </div>
16
20
17
21 <div class="fieldset clear-fix">
22 <span class="commit-author">${h.link_to_user(c.commit.author)}</span><span class="commit-date"> - ${h.age_component(c.commit.date)}</span>
23 </div>
24 </div>
25 </div>
18
26
19 <div class="fieldset">
20 <div class="left-label">
21 ${_('References')}:
22 </div>
23 <div class="right-content">
27 <div class="right-content">
24 <div class="tags">
28 <div class="tags commit-info">
25 <code>
29 <code>
26 <a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">${h.show_id(c.commit)}</a>
30 <a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">${h.show_id(c.commit)}</a>
27 </code>
31 </code>
@@ -29,9 +33,14 b''
29 ${file_base.refs(c.commit)}
33 ${file_base.refs(c.commit)}
30 </div>
34 </div>
31 </div>
35 </div>
32 </div>
36
37 <div class="clear-fix"></div>
33
38
34
39 <div class="btn-collapse" data-toggle="summary-details">
40 ${_('Show More')}
41 </div>
42 </div>
43 </div>
35 <script>
44 <script>
36 collapsableContent();
45 collapsableContent();
37 </script>
46 </script>
@@ -20,10 +20,6 b''
20
20
21 <%def name="main()">
21 <%def name="main()">
22 <div class="box">
22 <div class="box">
23 <div class="title">
24 ${self.repo_page_title(c.rhodecode_db_repo)}
25 </div>
26
27 ${h.secure_form(h.route_path('repo_fork_create',repo_name=c.rhodecode_db_repo.repo_name), request=request)}
23 ${h.secure_form(h.route_path('repo_fork_create',repo_name=c.rhodecode_db_repo.repo_name), request=request)}
28 <div class="form">
24 <div class="form">
29 <!-- fields -->
25 <!-- fields -->
@@ -8,9 +8,7 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 ${_('Forks')}
13 </%def>
14
12
15 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
16 ${self.menu_items(active='repositories')}
14 ${self.menu_items(active='repositories')}
@@ -23,7 +21,7 b''
23 <%def name="main()">
21 <%def name="main()">
24 <div class="box">
22 <div class="box">
25 <div class="title">
23 <div class="title">
26 ${self.repo_page_title(c.rhodecode_db_repo)}
24
27 <ul class="links">
25 <ul class="links">
28 <li>
26 <li>
29 <a class="btn btn-small btn-success" href="${h.route_path('repo_fork_new',repo_name=c.repo_name)}">
27 <a class="btn btn-small btn-success" href="${h.route_path('repo_fork_new',repo_name=c.repo_name)}">
@@ -12,32 +12,15 b''
12 <div class="box">
12 <div class="box">
13 <!-- box / title -->
13 <!-- box / title -->
14 <div class="title">
14 <div class="title">
15 % if c.repo_group:
16 ${self.repo_group_page_title(c.repo_group)}
17 ## context actions
18 <div>
19 <ul class="links icon-only-links block-right">
20 <li></li>
21 </ul>
22 </div>
23 % endif
24
25 %if c.rhodecode_user.username != h.DEFAULT_USER:
15 %if c.rhodecode_user.username != h.DEFAULT_USER:
26 <div class="block-right">
16 <div class="block-right">
27 <%
28 is_admin = h.HasPermissionAny('hg.admin')('can create repos index page')
29 create_repo = h.HasPermissionAny('hg.create.repository')('can create repository index page')
30 create_repo_group = h.HasPermissionAny('hg.repogroup.create.true')('can create repository groups index page')
31 create_user_group = h.HasPermissionAny('hg.usergroup.create.true')('can create user groups index page')
32 %>
33
34 %if not c.repo_group:
17 %if not c.repo_group:
35 ## no repository group context here
18 ## no repository group context here
36 %if is_admin or create_repo:
19 %if c.is_super_admin or c.can_create_repo:
37 <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success btn-primary">${_('Add Repository')}</a>
20 <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success btn-primary">${_('Add Repository')}</a>
38 %endif
21 %endif
39
22
40 %if is_admin or create_repo_group:
23 %if c.is_super_admin or c.can_create_repo_group:
41 <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-default">${_(u'Add Repository Group')}</a>
24 <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-default">${_(u'Add Repository Group')}</a>
42 %endif
25 %endif
43 %endif
26 %endif
@@ -79,13 +62,16 b''
79 order: [[ 0, "asc" ]],
62 order: [[ 0, "asc" ]],
80 columns: [
63 columns: [
81 { data: {"_": "name",
64 { data: {"_": "name",
82 "sort": "name_raw"}, title: "${_('Name')}", className: "td-componentname" },
65 "sort": "name_raw"}, title: "${_('Name')}", className: "truncate-wrap td-grid-name" },
83 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
66 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
84 { data: {"_": "desc",
67 { data: {"_": "desc",
85 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
68 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
86 { data: {"_": "last_change",
69 { data: {"_": "last_change",
87 "sort": "last_change_raw",
70 "sort": "last_change_raw",
88 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
71 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
72 { data: {"_": "last_changeset",
73 "sort": "last_changeset_raw",
74 "type": Number}, title: "", className: "td-hash" },
89 { data: {"_": "owner",
75 { data: {"_": "owner",
90 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" }
76 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" }
91 ],
77 ],
@@ -109,7 +95,7 b''
109 pageLength: ${c.visual.dashboard_items},
95 pageLength: ${c.visual.dashboard_items},
110 columns: [
96 columns: [
111 { data: {"_": "name",
97 { data: {"_": "name",
112 "sort": "name_raw"}, title: "${_('Name')}", className: "truncate-wrap td-componentname" },
98 "sort": "name_raw"}, title: "${_('Name')}", className: "truncate-wrap td-grid-name" },
113 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
99 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
114 { data: {"_": "desc",
100 { data: {"_": "desc",
115 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
101 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
@@ -14,10 +14,12 b''
14 <div id="header-inner" class="title">
14 <div id="header-inner" class="title">
15 <div id="logo">
15 <div id="logo">
16 <div class="logo-wrapper">
16 <div class="logo-wrapper">
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a>
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 </div>
18 </div>
19 %if c.rhodecode_name:
19 % if c.rhodecode_name:
20 <div class="branding">- ${h.branding(c.rhodecode_name)}</div>
20 <div class="branding">
21 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 </div>
21 %endif
23 % endif
22 </div>
24 </div>
23 </div>
25 </div>
@@ -14,10 +14,12 b''
14 <div id="header-inner" class="title">
14 <div id="header-inner" class="title">
15 <div id="logo">
15 <div id="logo">
16 <div class="logo-wrapper">
16 <div class="logo-wrapper">
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a>
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 </div>
18 </div>
19 %if c.rhodecode_name:
19 % if c.rhodecode_name:
20 <div class="branding">- ${h.branding(c.rhodecode_name)}</div>
20 <div class="branding">
21 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 </div>
21 %endif
23 % endif
22 </div>
24 </div>
23 </div>
25 </div>
@@ -5,9 +5,7 b''
5 ${c.repo_name} ${_('New pull request')}
5 ${c.repo_name} ${_('New pull request')}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()"></%def>
9 ${_('New pull request')}
10 </%def>
11
9
12 <%def name="menu_bar_nav()">
10 <%def name="menu_bar_nav()">
13 ${self.menu_items(active='repositories')}
11 ${self.menu_items(active='repositories')}
@@ -19,13 +17,9 b''
19
17
20 <%def name="main()">
18 <%def name="main()">
21 <div class="box">
19 <div class="box">
22 <div class="title">
23 ${self.repo_page_title(c.rhodecode_db_repo)}
24 </div>
25
26 ${h.secure_form(h.route_path('pullrequest_create', repo_name=c.repo_name, _query=request.GET.mixed()), id='pull_request_form', request=request)}
20 ${h.secure_form(h.route_path('pullrequest_create', repo_name=c.repo_name, _query=request.GET.mixed()), id='pull_request_form', request=request)}
27
21
28 ${self.breadcrumbs()}
22 ${_('New pull request')}
29
23
30 <div class="box pr-summary">
24 <div class="box pr-summary">
31
25
@@ -28,6 +28,9 b''
28 </span>
28 </span>
29 </li>
29 </li>
30 % endfor
30 % endfor
31 <li>
32 Try <a href="${h.current_route_path(request, force_refresh=1)}">forced recheck</a> of the merge workspace in case current status seems wrong.
33 </li>
31 </ul>
34 </ul>
32 % endif
35 % endif
33
36
@@ -38,10 +38,6 b''
38 </script>
38 </script>
39 <div class="box">
39 <div class="box">
40
40
41 <div class="title">
42 ${self.repo_page_title(c.rhodecode_db_repo)}
43 </div>
44
45 ${self.breadcrumbs()}
41 ${self.breadcrumbs()}
46
42
47 <div class="box pr-summary">
43 <div class="box pr-summary">
@@ -76,7 +72,7 b''
76 ## branch link is only valid if it is a branch
72 ## branch link is only valid if it is a branch
77 <span class="tag">
73 <span class="tag">
78 %if c.pull_request.source_ref_parts.type == 'branch':
74 %if c.pull_request.source_ref_parts.type == 'branch':
79 <a href="${h.route_path('repo_changelog', repo_name=c.pull_request.source_repo.repo_name, _query=dict(branch=c.pull_request.source_ref_parts.name))}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a>
75 <a href="${h.route_path('repo_commits', repo_name=c.pull_request.source_repo.repo_name, _query=dict(branch=c.pull_request.source_ref_parts.name))}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a>
80 %else:
76 %else:
81 ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}
77 ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}
82 %endif
78 %endif
@@ -112,7 +108,7 b''
112 ## branch link is only valid if it is a branch
108 ## branch link is only valid if it is a branch
113 <span class="tag">
109 <span class="tag">
114 %if c.pull_request.target_ref_parts.type == 'branch':
110 %if c.pull_request.target_ref_parts.type == 'branch':
115 <a href="${h.route_path('repo_changelog', repo_name=c.pull_request.target_repo.repo_name, _query=dict(branch=c.pull_request.target_ref_parts.name))}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a>
111 <a href="${h.route_path('repo_commits', repo_name=c.pull_request.target_repo.repo_name, _query=dict(branch=c.pull_request.target_ref_parts.name))}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a>
116 %else:
112 %else:
117 ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}
113 ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}
118 %endif
114 %endif
@@ -7,9 +7,7 b''
7 %endif
7 %endif
8 </%def>
8 </%def>
9
9
10 <%def name="breadcrumbs_links()">
10 <%def name="breadcrumbs_links()"></%def>
11
12 </%def>
13
11
14 <%def name="menu_bar_nav()">
12 <%def name="menu_bar_nav()">
15 ${self.menu_items(active='repositories')}
13 ${self.menu_items(active='repositories')}
@@ -22,63 +20,36 b''
22
20
23
21
24 <%def name="main()">
22 <%def name="main()">
23
25 <div class="box">
24 <div class="box">
26 <div class="title">
25 <div class="title">
27 ${self.repo_page_title(c.rhodecode_db_repo)}
26 <ul class="button-links">
27 <li class="btn ${('active' if c.active=='open' else '')}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0})}">${_('Opened')}</a></li>
28 <li class="btn ${('active' if c.active=='my' else '')}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'my':1})}">${_('Opened by me')}</a></li>
29 <li class="btn ${('active' if c.active=='awaiting' else '')}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'awaiting_review':1})}">${_('Awaiting review')}</a></li>
30 <li class="btn ${('active' if c.active=='awaiting_my' else '')}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'awaiting_my_review':1})}">${_('Awaiting my review')}</a></li>
31 <li class="btn ${('active' if c.active=='closed' else '')}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'closed':1})}">${_('Closed')}</a></li>
32 <li class="btn ${('active' if c.active=='source' else '')}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':1})}">${_('From this repo')}</a></li>
33 </ul>
28
34
29 <ul class="links">
35 <ul class="links">
36 % if c.rhodecode_user.username != h.DEFAULT_USER:
30 <li>
37 <li>
31 %if c.rhodecode_user.username != h.DEFAULT_USER:
32 <span>
38 <span>
33 <a id="open_new_pull_request" class="btn btn-small btn-success" href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">
39 <a id="open_new_pull_request" class="btn btn-small btn-success" href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">
34 ${_('Open new Pull Request')}
40 ${_('Open new Pull Request')}
35 </a>
41 </a>
36 </span>
42 </span>
43 </li>
37 %endif
44 % endif
38 </li>
39 </ul>
45 </ul>
40
46
41 ${self.breadcrumbs()}
42 </div>
43
44 <div class="sidebar-col-wrapper">
45 ##main
46 <div class="sidebar">
47 <ul class="nav nav-pills nav-stacked">
48 <li class="${'active' if c.active=='open' else ''}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0})}">${_('Opened')}</a></li>
49 <li class="${'active' if c.active=='my' else ''}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'my':1})}">${_('Opened by me')}</a></li>
50 <li class="${'active' if c.active=='awaiting' else ''}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'awaiting_review':1})}">${_('Awaiting review')}</a></li>
51 <li class="${'active' if c.active=='awaiting_my' else ''}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'awaiting_my_review':1})}">${_('Awaiting my review')}</a></li>
52 <li class="${'active' if c.active=='closed' else ''}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':0,'closed':1})}">${_('Closed')}</a></li>
53 <li class="${'active' if c.active=='source' else ''}"><a href="${h.route_path('pullrequest_show_all',repo_name=c.repo_name, _query={'source':1})}">${_('From this repo')}</a></li>
54 </ul>
55 </div>
47 </div>
56
48
57 <div class="main-content-full-width">
49 <div class="main-content-full-width">
58 <div class="panel panel-default">
59 <div class="panel-heading">
60 <h3 class="panel-title">
61 %if c.source:
62 ${_('Pull Requests from %(repo_name)s repository') % {'repo_name': c.repo_name}}
63 %elif c.closed:
64 ${_('Closed Pull Requests to repository %(repo_name)s') % {'repo_name': c.repo_name}}
65 %elif c.my:
66 ${_('Pull Requests to %(repo_name)s repository opened by me') % {'repo_name': c.repo_name}}
67 %elif c.awaiting_review:
68 ${_('Pull Requests to %(repo_name)s repository awaiting review') % {'repo_name': c.repo_name}}
69 %elif c.awaiting_my_review:
70 ${_('Pull Requests to %(repo_name)s repository awaiting my review') % {'repo_name': c.repo_name}}
71 %else:
72 ${_('Pull Requests to %(repo_name)s repository') % {'repo_name': c.repo_name}}
73 %endif
74 </h3>
75 </div>
76 <div class="panel-body panel-body-min-height">
77 <table id="pull_request_list_table" class="display"></table>
50 <table id="pull_request_list_table" class="display"></table>
78 </div>
51 </div>
79 </div>
52
80 </div>
81 </div>
82 </div>
53 </div>
83
54
84 <script type="text/javascript">
55 <script type="text/javascript">
@@ -14,10 +14,12 b''
14 <div id="header-inner" class="title">
14 <div id="header-inner" class="title">
15 <div id="logo">
15 <div id="logo">
16 <div class="logo-wrapper">
16 <div class="logo-wrapper">
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a>
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 </div>
18 </div>
19 %if c.rhodecode_name:
19 % if c.rhodecode_name:
20 <div class="branding">- ${h.branding(c.rhodecode_name)}</div>
20 <div class="branding">
21 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 </div>
21 %endif
23 % endif
22 </div>
24 </div>
23 </div>
25 </div>
@@ -37,9 +37,10 b''
37
37
38 <%def name="menu_bar_subnav()">
38 <%def name="menu_bar_subnav()">
39 %if c.repo_name:
39 %if c.repo_name:
40 ${self.repo_menu(active='search')}
40 <% active_entry = {'content':'files', 'path':'files', 'commit':'commits'}.get(c.search_type, 'summary')%>
41 ${self.repo_menu(active=active_entry)}
41 %elif c.repo_group_name:
42 %elif c.repo_group_name:
42 ${self.repo_group_menu(active='search')}
43 ${self.repo_group_menu(active='home')}
43 %endif
44 %endif
44 </%def>
45 </%def>
45
46
@@ -56,22 +57,16 b''
56 </%def>
57 </%def>
57
58
58 <%def name="repo_group_icon()">
59 <%def name="repo_group_icon()">
59 <i class="icon-folder-close"></i>
60 <i class="icon-repo-group"></i>
60 </%def>
61 </%def>
61
62
62 <%def name="main()">
63 <%def name="main()">
63 <div class="box">
64 <div class="box">
64 %if c.repo_name:
65 %if c.repo_name:
65 <!-- box / title -->
66 <!-- box / title -->
66 <div class="title">
67 ${self.repo_page_title(c.rhodecode_db_repo)}
68 </div>
69 ${h.form(h.route_path('search_repo',repo_name=c.repo_name),method='get')}
67 ${h.form(h.route_path('search_repo',repo_name=c.repo_name),method='get')}
70 %elif c.repo_group_name:
68 %elif c.repo_group_name:
71 <!-- box / title -->
69 <!-- box / title -->
72 <div class="title">
73 ${self.repo_group_page_title(c.repo_group)}
74 </div>
75 ${h.form(h.route_path('search_repo_group',repo_group_name=c.repo_group_name),method='get')}
70 ${h.form(h.route_path('search_repo_group',repo_group_name=c.repo_group_name),method='get')}
76 %else:
71 %else:
77 <!-- box / title -->
72 <!-- box / title -->
@@ -58,65 +58,50 b''
58 %>
58 %>
59 ## search results are additionally filtered, and this check is just a safe gate
59 ## search results are additionally filtered, and this check is just a safe gate
60 % if c.rhodecode_user.is_admin or h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(entry['repository'], 'search results content check'):
60 % if c.rhodecode_user.is_admin or h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(entry['repository'], 'search results content check'):
61 <div id="codeblock" class="codeblock">
61 <div class="codeblock">
62 <div class="codeblock-header">
63 <h1>
62 <h1>
64 <% repo_type = entry.get('repo_type') or h.get_repo_type_by_name(entry.get('repository')) %>
63 <% repo_type = entry.get('repo_type') or h.get_repo_type_by_name(entry.get('repository')) %>
65 ${search.repo_icon(repo_type)}
64 ${search.repo_icon(repo_type)}
66 ${h.link_to(entry['repository'], h.route_path('repo_summary',repo_name=entry['repository']))}
65 ${h.link_to(entry['repository'], h.route_path('repo_summary', repo_name=entry['repository']))}
67 </h1>
66 </h1>
68 ## level 1
67
69 <div class="file-container">
68 <div class="codeblock-header">
70
69
71 <div class="pull-left">
70 <div class="file-filename">
72 <span class="stats-filename">
71 <i class="icon-file"></i> ${entry['f_path'].split('/')[-1]}
73 <strong>
74 <i class="icon-file-text"></i>
75 ${h.link_to(h.literal(entry['f_path']), h.route_path('repo_files',repo_name=entry['repository'],commit_id=entry.get('commit_id', 'tip'),f_path=entry['f_path']))}
76 </strong>
77 </span>
78 <span class="item last">
79 <i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${entry['f_path']}" title="${_('Copy the full path')}"></i>
80 </span>
81 </div>
72 </div>
82
73
83 <div class="pull-right">
74 <div class="file-stats">
84 <div class="buttons">
75 <div class="stats-info">
85 <a id="file_history_overview_full" href="${h.route_path('repo_changelog_file',repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path',''))}">
86 ${_('Show Full History')}
87 </a>
88 | ${h.link_to(_('Annotation'), h.route_path('repo_files:annotated', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
89 | ${h.link_to(_('Raw'), h.route_path('repo_file_raw', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
90 | ${h.link_to(_('Download'), h.route_path('repo_file_download',repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
91 </div>
92 </div>
93
94 </div>
95 ## level 2
96 <div class="file-container">
97
98 <div class="pull-left">
99 <span class="stats-first-item">
76 <span class="stats-first-item">
100 %if entry.get('lines'):
101 ${entry.get('lines', 0.)} ${_ungettext('line', 'lines', entry.get('lines', 0.))}
77 ${entry.get('lines', 0.)} ${_ungettext('line', 'lines', entry.get('lines', 0.))}
102 (${len(matching_lines)} ${_ungettext('matched', 'matched', len(matching_lines))})
78 (${len(matching_lines)} ${_ungettext('matched', 'matched', len(matching_lines))})
103 %endif
104 </span>
79 </span>
105
106 <span>
80 <span>
107 %if entry.get('size'):
81 % if entry.get('size'):
108 | ${h.format_byte_size_binary(entry['size'])}
82 | ${h.format_byte_size_binary(entry['size'])}
109 %endif
83 % endif
110 </span>
84 </span>
111
112 <span>
85 <span>
113 %if entry.get('mimetype'):
86 % if entry.get('mimetype'):
114 | ${entry.get('mimetype', "unknown mimetype")}
87 | ${entry.get('mimetype', "unknown mimetype")}
115 %endif
88 % endif
116 </span>
89 </span>
117 </div>
90 </div>
91 </div>
92 </div>
118
93
119 <div class="pull-right">
94 <div class="path clear-fix">
95 <div class="pull-left">
96 ${h.files_breadcrumbs(entry['repository'],entry.get('commit_id', 'tip'),entry['f_path'], linkify_last_item=True)}
97 </div>
98
99 <div class="pull-right stats">
100 ## <a id="file_history_overview_full" href="${h.route_path('repo_commits_file',repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path',''))}">
101 ## ${_('Show Full History')}
102 ## </a>
103 ## | ${h.link_to(_('Annotation'), h.route_path('repo_files:annotated', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
104 ## | ${h.link_to(_('Raw'), h.route_path('repo_file_raw', repo_name=entry.get('repository',''),commit_id=entry.get('commit_id', 'tip'),f_path=entry.get('f_path','')))}
120 <div class="search-tags">
105 <div class="search-tags">
121
106
122 <% repo_group = entry.get('repository_group')%>
107 <% repo_group = entry.get('repository_group')%>
@@ -135,13 +120,13 b''
135 </span>
120 </span>
136 % endif
121 % endif
137 </div>
122 </div>
123
138 </div>
124 </div>
139
125 <div class="clear-fix"></div>
140 </div>
126 </div>
141
127
142 </div>
143 <div class="code-body search-code-body">
144
128
129 <div class="code-body search-code-body clear-fix">
145 ${highlight_text_file(
130 ${highlight_text_file(
146 has_matched_content=has_matched_content,
131 has_matched_content=has_matched_content,
147 file_content=file_content,
132 file_content=file_content,
@@ -1,29 +1,51 b''
1 <%namespace name="base" file="/base/base.mako"/>
2
1 <%def name="refs_counters(branches, closed_branches, tags, bookmarks)">
3 <%def name="refs_counters(branches, closed_branches, tags, bookmarks)">
2 <span class="branchtag tag">
4 <span class="summary-branchtag summary-tag">
3 <a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
5 <a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
4 <i class="icon-branch"></i>${_ungettext(
6 <i class="icon-branch"></i>
5 '%(num)s Branch','%(num)s Branches', len(branches)) % {'num': len(branches)}}</a>
7 % if len(branches) == 1:
8 <span>${len(branches)}</span> ${_('Branch')}
9 % else:
10 <span>${len(branches)}</span> ${_('Branches')}
11 % endif
12 </a>
6 </span>
13 </span>
7
14
8 %if closed_branches:
15 %if closed_branches:
9 <span class="branchtag tag">
16 <span class="summary-branchtag summary-tag">
10 <a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
17 <a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
11 <i class="icon-branch"></i>${_ungettext(
18 <i class="icon-branch"></i>
12 '%(num)s Closed Branch', '%(num)s Closed Branches', len(closed_branches)) % {'num': len(closed_branches)}}</a>
19 % if len(closed_branches) == 1:
20 <span>${len(closed_branches)}</span> ${_('Closed Branch')}
21 % else:
22 <span>${len(closed_branches)}</span> ${_('Closed Branches')}
23 % endif
24 </a>
13 </span>
25 </span>
14 %endif
26 %endif
15
27
16 <span class="tagtag tag">
28 <span class="summary-tagtag summary-tag">
17 <a href="${h.route_path('tags_home',repo_name=c.repo_name)}" class="childs">
29 <a href="${h.route_path('tags_home',repo_name=c.repo_name)}" class="childs">
18 <i class="icon-tag"></i>${_ungettext(
30 <i class="icon-tag"></i>
19 '%(num)s Tag', '%(num)s Tags', len(tags)) % {'num': len(tags)}}</a>
31 % if len(tags) == 1:
32 <span>${len(tags)}</span> ${_('Tag')}
33 % else:
34 <span>${len(tags)}</span> ${_('Tags')}
35 % endif
36 </a>
20 </span>
37 </span>
21
38
22 %if bookmarks:
39 %if bookmarks:
23 <span class="booktag tag">
40 <span class="summary-booktag summary-tag">
24 <a href="${h.route_path('bookmarks_home',repo_name=c.repo_name)}" class="childs">
41 <a href="${h.route_path('bookmarks_home',repo_name=c.repo_name)}" class="childs">
25 <i class="icon-bookmark"></i>${_ungettext(
42 <i class="icon-bookmark"></i>
26 '%(num)s Bookmark', '%(num)s Bookmarks', len(bookmarks)) % {'num': len(bookmarks)}}</a>
43 % if len(bookmarks) == 1:
44 <span>${len(bookmarks)}</span> ${_('Bookmark')}
45 % else:
46 <span>${len(bookmarks)}</span> ${_('Bookmarks')}
47 % endif
48 </a>
27 </span>
49 </span>
28 %endif
50 %endif
29 </%def>
51 </%def>
@@ -32,19 +54,8 b''
32 <% summary = lambda n:{False:'summary-short'}.get(n) %>
54 <% summary = lambda n:{False:'summary-short'}.get(n) %>
33
55
34 <div id="summary-menu-stats" class="summary-detail">
56 <div id="summary-menu-stats" class="summary-detail">
35 <div class="summary-detail-header">
36 <div class="breadcrumbs files_location">
37 <h4>
38 ${breadcrumbs_links}
39 </h4>
40 </div>
41 <div id="summary_details_expand" class="btn-collapse" data-toggle="summary-details">
42 ${_('Show More')}
43 </div>
44 </div>
45
46 <div class="fieldset">
57 <div class="fieldset">
47
58 <div class="left-content">
48 <div class="left-clone">
59 <div class="left-clone">
49 <select id="clone_option" name="clone_option">
60 <select id="clone_option" name="clone_option">
50 <option value="http" selected="selected">HTTP</option>
61 <option value="http" selected="selected">HTTP</option>
@@ -54,6 +65,7 b''
54 % endif
65 % endif
55 </select>
66 </select>
56 </div>
67 </div>
68
57 <div class="right-clone">
69 <div class="right-clone">
58 <%
70 <%
59 maybe_disabled = ''
71 maybe_disabled = ''
@@ -79,14 +91,9 b''
79 % if maybe_disabled:
91 % if maybe_disabled:
80 <p class="help-block">${_('SVN Protocol is disabled. To enable it, see the')} <a href="${h.route_url('enterprise_svn_setup')}" target="_blank">${_('documentation here')}</a>.</p>
92 <p class="help-block">${_('SVN Protocol is disabled. To enable it, see the')} <a href="${h.route_url('enterprise_svn_setup')}" target="_blank">${_('documentation here')}</a>.</p>
81 % endif
93 % endif
82
83 </div>
94 </div>
84 </div>
95 </div>
85
96
86 <div class="fieldset">
87 <div class="left-label-summary">
88 &nbsp;
89 </div>
90 <div class="right-content">
97 <div class="right-content">
91 <div class="commit-info">
98 <div class="commit-info">
92 <div class="tags">
99 <div class="tags">
@@ -103,32 +110,99 b''
103 % endif
110 % endif
104
111
105 ## commits
112 ## commits
106 <span class="tag">
113 <span class="summary-tag">
114 % if commit_rev == -1:
115 <i class="icon-history"></i>
107 % if commit_rev == -1:
116 % if commit_rev == -1:
108 ${_ungettext('%(num)s Commit', '%(num)s Commits', 0) % {'num': 0}}
117 <span>0</span> ${_('Commit')}
118 % else:
119 <span>0</span> ${_('Commits')}
120 % endif
109 % else:
121 % else:
110 <a href="${h.route_path('repo_changelog', repo_name=c.repo_name)}">
122 <a href="${h.route_path('repo_commits', repo_name=c.repo_name)}">
111 ${_ungettext('%(num)s Commit', '%(num)s Commits', commit_rev) % {'num': commit_rev}}</a>
123 <i class="icon-history"></i>
124 % if commit_rev == 1:
125 <span>${commit_rev}</span> ${_('Commit')}
126 % else:
127 <span>${commit_rev}</span> ${_('Commits')}
128 % endif
129 </a>
112 % endif
130 % endif
113 </span>
131 </span>
114
132
115 ## forks
133 ## forks
116 <span class="tag">
134 <span class="summary-tag">
117 <a title="${_('Number of Repository Forks')}" href="${h.route_path('repo_forks_show_all', repo_name=c.repo_name)}">
135 <a title="${_('Number of Repository Forks')}" href="${h.route_path('repo_forks_show_all', repo_name=c.repo_name)}">
118 ${c.repository_forks} ${_ungettext('Fork', 'Forks', c.repository_forks)}</a>
136 <i class="icon-code-fork"></i>
137 <span>${c.repository_forks}</span> ${_ungettext('Fork', 'Forks', c.repository_forks)}</a>
119 </span>
138 </span>
120
121 </div>
139 </div>
122 </div>
140 </div>
123 </div>
141 </div>
124 </div>
142 </div>
143 ## owner, description, downloads, statistics
125
144
145 ## Owner
146 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
147 <div class="left-label-summary">
148 <p>${_('Owner')}</p>
149 <div class="right-label-summary">
150 ${base.gravatar_with_user(c.rhodecode_db_repo.user.email, 16)}
151 </div>
152
153 </div>
154 </div>
155
156 ## Description
157 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
158 <div class="left-label-summary">
159 <p>${_('Description')}</p>
160
161 <div class="right-label-summary input ${summary(c.show_stats)}">
162 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
163 ${dt.repo_desc(c.rhodecode_db_repo.description_safe, c.visual.stylify_metatags)}
164 </div>
165 </div>
166 </div>
167
168 ## Downloads
169 % if show_downloads:
126 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
170 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
127 <div class="left-label-summary">
171 <div class="left-label-summary">
128 ${_('Repository size')}:
172 <p>${_('Downloads')}</p>
173
174 <div class="right-label-summary input ${summary(c.show_stats)} downloads">
175 % if c.rhodecode_repo and len(c.rhodecode_repo.commit_ids) == 0:
176 <span class="disabled">
177 ${_('There are no downloads yet')}
178 </span>
179 % elif not c.enable_downloads:
180 <span class="disabled">
181 ${_('Downloads are disabled for this repository')}.
182 </span>
183 % if c.is_super_admin:
184 ${h.link_to(_('Enable downloads'),h.route_path('edit_repo',repo_name=c.repo_name, _anchor='repo_enable_downloads'))}
185 % endif
186 % else:
187 <span class="enabled">
188 <a id="archive_link" class="btn btn-small" href="${h.route_path('repo_archivefile',repo_name=c.rhodecode_db_repo.repo_name,fname='tip.zip')}">
189 <i class="icon-archive"></i> tip.zip
190 ## replaced by some JS on select
191 </a>
192 </span>
193 ${h.hidden('download_options')}
194 % endif
129 </div>
195 </div>
130 <div class="right-content">
196 </div>
131 <div class="commit-info">
197 </div>
198 % endif
199
200 ## Repo size
201 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
202 <div class="left-label-summary">
203 <p>${_('Repository size')}</p>
204
205 <div class="right-label-summary">
132 <div class="tags">
206 <div class="tags">
133 ## repo size
207 ## repo size
134 % if commit_rev == -1:
208 % if commit_rev == -1:
@@ -146,66 +220,21 b''
146 </div>
220 </div>
147 </div>
221 </div>
148
222
149 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
150 <div class="left-label-summary">
151 ${_('Description')}:
152 </div>
153 <div class="right-content">
154 <div class="input ${summary(c.show_stats)}">
155 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
156 ${dt.repo_desc(c.rhodecode_db_repo.description_safe, c.visual.stylify_metatags)}
157 </div>
158 </div>
159 </div>
160
161 % if show_downloads:
162 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
163 <div class="left-label-summary">
164 ${_('Downloads')}:
165 </div>
166 <div class="right-content">
167 <div class="input ${summary(c.show_stats)} downloads">
168 % if c.rhodecode_repo and len(c.rhodecode_repo.commit_ids) == 0:
169 <span class="disabled">
170 ${_('There are no downloads yet')}
171 </span>
172 % elif not c.enable_downloads:
173 <span class="disabled">
174 ${_('Downloads are disabled for this repository')}.
175 </span>
176 % if h.HasPermissionAll('hg.admin')('enable downloads on from summary'):
177 ${h.link_to(_('Enable downloads'),h.route_path('edit_repo',repo_name=c.repo_name, _anchor='repo_enable_downloads'))}
178 % endif
179 % else:
180 <span class="enabled">
181 <a id="archive_link" class="btn btn-small" href="${h.route_path('repo_archivefile',repo_name=c.rhodecode_db_repo.repo_name,fname='tip.zip')}">
182 <i class="icon-archive"></i> tip.zip
183 ## replaced by some JS on select
184 </a>
185 </span>
186 ${h.hidden('download_options')}
187 % endif
188 </div>
189 </div>
190 </div>
191 % endif
192
193 ## Statistics
223 ## Statistics
194 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
224 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
195 <div class="left-label-summary">
225 <div class="left-label-summary">
196 ${_('Statistics')}:
226 <p>${_('Code Statistics')}</p>
197 </div>
227
198 <div class="right-content">
228 <div class="right-label-summary input ${summary(c.show_stats)} statistics">
199 <div class="input ${summary(c.show_stats)} statistics">
200 % if c.show_stats:
229 % if c.show_stats:
201 <div id="lang_stats" class="enabled">
230 <div id="lang_stats" class="enabled">
202 ${_('Calculating Code Statistics...')}
231 <a href="#showSize" onclick="calculateSize(); $('#show-repo-size').hide(); $(this).hide(); return false" id="show-repo-size">Show code statistics</a>
203 </div>
232 </div>
204 % else:
233 % else:
205 <span class="disabled">
234 <span class="disabled">
206 ${_('Statistics are disabled for this repository')}.
235 ${_('Statistics are disabled for this repository')}.
207 </span>
236 </span>
208 % if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
237 % if c.is_super_admin:
209 ${h.link_to(_('Enable statistics'),h.route_path('edit_repo',repo_name=c.repo_name, _anchor='repo_enable_statistics'))}
238 ${h.link_to(_('Enable statistics'),h.route_path('edit_repo',repo_name=c.repo_name, _anchor='repo_enable_statistics'))}
210 % endif
239 % endif
211 % endif
240 % endif
@@ -214,18 +243,10 b''
214 </div>
243 </div>
215 </div>
244 </div>
216
245
246
217 </div><!--end summary-detail-->
247 </div><!--end summary-detail-->
218 </%def>
219
248
220 <%def name="summary_stats(gravatar_function)">
249 <div id="summary_details_expand" class="btn-collapse" data-toggle="summary-details">
221 <div class="sidebar-right">
250 ${_('Show More')}
222 <div class="summary-detail-header">
223 <h4 class="item">
224 ${_('Owner')}
225 </h4>
226 </div>
251 </div>
227 <div class="sidebar-right-content">
228 ${gravatar_function(c.rhodecode_db_repo.user.email, 16)}
229 </div>
230 </div><!--end sidebar-right-->
231 </%def>
252 </%def>
@@ -3,13 +3,9 b''
3 <%namespace name="components" file="/summary/components.mako"/>
3 <%namespace name="components" file="/summary/components.mako"/>
4
4
5 <%def name="main()">
5 <%def name="main()">
6 <div class="title">
7 ${self.repo_page_title(c.rhodecode_db_repo)}
8 </div>
9
6
10 <div id="repo-summary" class="summary">
7 <div id="repo-summary" class="summary">
11 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=False)}
8 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=False)}
12 ${components.summary_stats(gravatar_function=self.gravatar_with_user)}
13 </div><!--end repo-summary-->
9 </div><!--end repo-summary-->
14
10
15 <div class="alert alert-dismissable alert-warning">
11 <div class="alert alert-dismissable alert-warning">
@@ -9,33 +9,19 b''
9
9
10 <%def name="main()">
10 <%def name="main()">
11
11
12 <div class="title">
13 ${self.repo_page_title(c.rhodecode_db_repo)}
14 ## Context Action
15 <div>
16 <ul class="links icon-only-links block-right">
17 <li>
18 %if c.rhodecode_user.username != h.DEFAULT_USER:
19 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_name, _query=dict(auth_token=c.rhodecode_user.feed_token))}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
20 %else:
21 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_name)}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
22 %endif
23 </li>
24 </ul>
25 </div>
26 </div>
27
28 <div id="repo-summary" class="summary">
12 <div id="repo-summary" class="summary">
29 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=True)}
13 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=True)}
30 ${components.summary_stats(gravatar_function=self.gravatar_with_user)}
31 </div><!--end repo-summary-->
14 </div><!--end repo-summary-->
32
15
33
16
34 <div class="box" >
17 <div class="box">
35 %if not c.repo_commits:
18 %if not c.repo_commits:
19 <div class="empty-repo">
36 <div class="title">
20 <div class="title">
37 <h3>${_('Quick start')}</h3>
21 <h3>${_('Quick start')}</h3>
38 </div>
22 </div>
23 <div class="clear-fix"></div>
24 </div>
39 %endif
25 %endif
40 <div class="table">
26 <div class="table">
41 <div id="shortlog_data">
27 <div id="shortlog_data">
@@ -49,7 +35,9 b''
49 <div class="box" >
35 <div class="box">
50 <div class="title" title="${h.tooltip(_('Readme file from commit %s:%s') % (c.rhodecode_db_repo.landing_rev[0], c.rhodecode_db_repo.landing_rev[1]))}">
36 <div class="title" title="${h.tooltip(_('Readme file from commit %s:%s') % (c.rhodecode_db_repo.landing_rev[0], c.rhodecode_db_repo.landing_rev[1]))}">
51 <h3 class="breadcrumbs">
37 <h3 class="breadcrumbs">
52 <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.landing_rev[1],f_path=c.readme_file)}">${c.readme_file}</a>
38 <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.landing_rev[1],f_path=c.readme_file)}">
39 ${c.readme_file}
40 </a>
53 </h3>
41 </h3>
54 </div>
42 </div>
55 <div class="readme codeblock">
43 <div class="readme codeblock">
@@ -20,8 +20,7 b''
20 </%def>
20 </%def>
21
21
22
22
23 <%def name="breadcrumbs_links()">
23 <%def name="breadcrumbs_links()"></%def>
24 </%def>
25
24
26
25
27 <%def name="main()">
26 <%def name="main()">
@@ -4,12 +4,12 b''
4 <table class="rctable repo_summary table_disp">
4 <table class="rctable repo_summary table_disp">
5 <tr>
5 <tr>
6
6
7 <th class="status" colspan="2"></th>
7 <th class="status"></th>
8 <th>${_('Commit')}</th>
8 <th>${_('Commit')}</th>
9 <th>${_('Commit message')}</th>
9 <th>${_('Commit message')}</th>
10 <th>${_('Age')}</th>
10 <th>${_('Age')}</th>
11 <th>${_('Author')}</th>
11 <th>${_('Author')}</th>
12 <th>${_('Refs')}</th>
12 <th colspan="2">${_('Refs')}</th>
13 </tr>
13 </tr>
14
14
15 ## to speed up lookups cache some functions before the loop
15 ## to speed up lookups cache some functions before the loop
@@ -37,13 +37,6 b''
37 <div class="tooltip flag_status not_reviewed" title="${_('Commit status: Not Reviewed')}"></div>
37 <div class="tooltip flag_status not_reviewed" title="${_('Commit status: Not Reviewed')}"></div>
38 %endif
38 %endif
39 </td>
39 </td>
40 <td class="td-comments">
41 %if c.comments.get(cs.raw_id,[]):
42 <a title="${_('Commit has comments')}" href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=cs.raw_id,_anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
43 <i class="icon-comment"></i> ${len(c.comments[cs.raw_id])}
44 </a>
45 %endif
46 </td>
47 <td class="td-commit">
40 <td class="td-commit">
48 <code>
41 <code>
49 <a href="${h.route_path('repo_commit', repo_name=c.repo_name, commit_id=cs.raw_id)}">${h.show_id(cs)}</a>
42 <a href="${h.route_path('repo_commit', repo_name=c.repo_name, commit_id=cs.raw_id)}">${h.show_id(cs)}</a>
@@ -83,19 +76,34 b''
83 ## branch
76 ## branch
84 %if cs.branch:
77 %if cs.branch:
85 <span class="branchtag tag" title="${h.tooltip(_('Branch %s') % cs.branch)}">
78 <span class="branchtag tag" title="${h.tooltip(_('Branch %s') % cs.branch)}">
86 <a href="${h.route_path('repo_changelog',repo_name=c.repo_name,_query=dict(branch=cs.branch))}"><i class="icon-code-fork"></i>${h.shorter(cs.branch)}</a>
79 <a href="${h.route_path('repo_commits',repo_name=c.repo_name,_query=dict(branch=cs.branch))}"><i class="icon-code-fork"></i>${h.shorter(cs.branch)}</a>
87 </span>
80 </span>
88 %endif
81 %endif
89 </div>
82 </div>
90 </td>
83 </td>
84 <td class="td-comments">
85 <% cs_comments = c.comments.get(cs.raw_id,[]) %>
86 % if cs_comments:
87 <a title="${_('Commit has comments')}" href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=cs.raw_id,_anchor='comment-%s' % cs_comments[0].comment_id)}">
88 <i class="icon-comment"></i> ${len(cs_comments)}
89 </a>
90 % else:
91 <i class="icon-comment"></i> ${len(cs_comments)}
92 % endif
93 </td>
91 </tr>
94 </tr>
92 %endfor
95 %endfor
93
96
94 </table>
97 </table>
95
98
96 <script type="text/javascript">
99 <script type="text/javascript">
97 $(document).pjax('#shortlog_data .pager_link','#shortlog_data', {timeout: 2000, scrollTo: false, push: false});
100 $(document).pjax('#shortlog_data .pager_link','#shortlog_data', {timeout: 5000, scrollTo: false, push: false});
98 $(document).on('pjax:success', function(){ timeagoActivate(); });
101 $(document).on('pjax:success', function(){ timeagoActivate(); });
102 $(document).on('pjax:timeout', function(event) {
103 // Prevent default timeout redirection behavior
104 event.preventDefault()
105 })
106
99 </script>
107 </script>
100
108
101 <div class="pagination-wh pagination-left">
109 <div class="pagination-wh pagination-left">
@@ -106,40 +114,54 b''
106 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
114 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
107 <div class="quick_start">
115 <div class="quick_start">
108 <div class="fieldset">
116 <div class="fieldset">
109 <div class="left-label">${_('Add or upload files directly via RhodeCode:')}</div>
117 <p><b>${_('Add or upload files directly via RhodeCode:')}</b></p>
110 <div class="right-content">
118 <div class="pull-left">
111 <div id="add_node_id" class="add_node">
119 <a href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=0, f_path='')}" class="btn btn-default">${_('Add New File')}</a>
112 <a href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=0, f_path='', _anchor='edit')}" class="btn btn-default">${_('Add New File')}</a>
113 </div>
120 </div>
121 <div class="pull-left">
122 <a href="${h.route_path('repo_files_upload_file',repo_name=c.repo_name,commit_id=0, f_path='')}" class="btn btn-default">${_('Upload New File')}</a>
114 </div>
123 </div>
115 %endif
124 %endif
116 </div>
125 </div>
117
126
118 %if not h.is_svn(c.rhodecode_repo):
119 <div class="fieldset">
127 <div class="fieldset">
120 <div class="left-label">${_('Push new repo:')}</div>
128 <p><b>${_('Push new repo:')}</b></p>
121 <div class="right-content">
122 <pre>
129 <pre>
123 ${c.rhodecode_repo.alias} clone ${c.clone_repo_url}
130 %if h.is_git(c.rhodecode_repo):
124 ${c.rhodecode_repo.alias} add README # add first file
131 git clone ${c.clone_repo_url}
125 ${c.rhodecode_repo.alias} commit -m "Initial" # commit with message
132 git add README # add first file
126 ${c.rhodecode_repo.alias} push ${'origin master' if h.is_git(c.rhodecode_repo) else ''} # push changes back
133 git commit -m "Initial commit" # commit with message
134 git remote add origin ${c.clone_repo_url}
135 git push -u origin master # push changes back to default master branch
136 %elif h.is_hg(c.rhodecode_repo):
137 hg clone ${c.clone_repo_url}
138 hg add README # add first file
139 hg commit -m "Initial commit" # commit with message
140 hg push ${c.clone_repo_url}
141 %elif h.is_svn(c.rhodecode_repo):
142 svn co ${c.clone_repo_url}
143 svn add README # add first file
144 svn commit -m "Initial commit"
145 svn commit # send changes back to the server
146 %endif
127 </pre>
147 </pre>
128 </div>
148 </div>
129 </div>
149
130 <div class="fieldset">
150 <div class="fieldset">
131 <div class="left-label">${_('Existing repository?')}</div>
151 <p><b>${_('Existing repository?')}</b></p>
132 <div class="right-content">
133 <pre>
152 <pre>
134 %if h.is_git(c.rhodecode_repo):
153 %if h.is_git(c.rhodecode_repo):
135 git remote add origin ${c.clone_repo_url}
154 git remote add origin ${c.clone_repo_url}
136 git push -u origin master
155 git push -u origin master
137 %else:
156 %elif h.is_hg(c.rhodecode_repo):
138 hg push ${c.clone_repo_url}
157 hg push ${c.clone_repo_url}
158 %elif h.is_svn(c.rhodecode_repo):
159 svn co ${c.clone_repo_url}
139 %endif
160 %endif
140 </pre>
161 </pre>
162
141 </div>
163 </div>
164
165
142 </div>
166 </div>
143 %endif
167 %endif
144 </div>
145 %endif
@@ -8,10 +8,7 b''
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()"></%def>
12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 <span id="obj_count">0</span> ${_('tags')}
14 </%def>
15
12
16 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
17 ${self.menu_items(active='repositories')}
14 ${self.menu_items(active='repositories')}
@@ -24,7 +21,7 b''
24 <%def name="main()">
21 <%def name="main()">
25 <div class="box">
22 <div class="box">
26 <div class="title">
23 <div class="title">
27 ${self.repo_page_title(c.rhodecode_db_repo)}
24
28 %if c.has_references:
25 %if c.has_references:
29 <ul class="links">
26 <ul class="links">
30 <li>
27 <li>
@@ -33,7 +30,8 b''
33 </ul>
30 </ul>
34 %endif
31 %endif
35 %if c.has_references:
32 %if c.has_references:
36 ${self.breadcrumbs()}
33 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
34 <span id="obj_count">0</span> ${_('tags')}
37 %endif
35 %endif
38 </div>
36 </div>
39 <table id="obj_list_table" class="display"></table>
37 <table id="obj_list_table" class="display"></table>
@@ -3,23 +3,24 b''
3 <div class="panel panel-default user-profile">
3 <div class="panel panel-default user-profile">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('User group profile')}</h3>
5 <h3 class="panel-title">${_('User group profile')}</h3>
6 %if h.HasPermissionAny('hg.admin')():
6 %if c.is_super_admin:
7 ${h.link_to(_('Edit'), h.route_path('edit_user_group', user_group_id=c.user_group.users_group_id), class_='panel-edit')}
7 ${h.link_to(_('Edit'), h.route_path('edit_user_group', user_group_id=c.user_group.users_group_id), class_='panel-edit')}
8 %endif
8 %endif
9 </div>
9 </div>
10
10
11 <div class="panel-body user-profile-content">
11 <div class="panel-body user-profile-content fields">
12
12 <div class="field">
13 <div class="fieldset">
13 <div class="label">
14 <div class="left-label">
15 ${_('Group Name')}:
14 ${_('Group Name')}:
16 </div>
15 </div>
17 <div class="right-content">
16 <div class="input">
17 <div class="text-as-placeholder">
18 ${c.user_group.users_group_name}
18 ${c.user_group.users_group_name}
19 </div>
19 </div>
20 </div>
20 </div>
21 <div class="fieldset">
21 </div>
22 <div class="left-label">
22 <div class="field">
23 <div class="label">
23 ${_('Owner')}:
24 ${_('Owner')}:
24 </div>
25 </div>
25 <div class="group_member">
26 <div class="group_member">
@@ -28,20 +29,24 b''
28
29
29 </div>
30 </div>
30 </div>
31 </div>
31 <div class="fieldset">
32 <div class="field">
32 <div class="left-label">
33 <div class="label">
33 ${_('Active')}:
34 ${_('Active')}:
34 </div>
35 </div>
35 <div class="right-content">
36 <div class="input">
37 <div class="text-as-placeholder">
36 ${c.user_group.users_group_active}
38 ${c.user_group.users_group_active}
37 </div>
39 </div>
38 </div>
40 </div>
41 </div>
39 % if not c.anonymous:
42 % if not c.anonymous:
40 <div class="fieldset">
43 <div class="field">
41 <div class="left-label">
44 <div class="label">
42 ${_('Members')}:
45 ${_('Members')}:
43 </div>
46 </div>
44 <div class="right-content">
47
48 <div class="input">
49 <div class="text-as-placeholder">
45 <table id="group_members_placeholder" class="rctable group_members">
50 <table id="group_members_placeholder" class="rctable group_members">
46 <th>${_('Username')}</th>
51 <th>${_('Username')}</th>
47 % if c.group_members:
52 % if c.group_members:
@@ -65,6 +70,7 b''
65 </table>
70 </table>
66 </div>
71 </div>
67 </div>
72 </div>
73 </div>
68 % endif
74 % endif
69 </div>
75 </div>
70 </div> No newline at end of file
76 </div>
@@ -3,55 +3,64 b''
3 <div class="panel panel-default user-profile">
3 <div class="panel panel-default user-profile">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('User Profile')}</h3>
5 <h3 class="panel-title">${_('User Profile')}</h3>
6 %if h.HasPermissionAny('hg.admin')():
6 %if c.is_super_admin:
7 ${h.link_to(_('Edit'), h.route_path('user_edit', user_id=c.user.user_id), class_='panel-edit')}
7 ${h.link_to(_('Edit'), h.route_path('user_edit', user_id=c.user.user_id), class_='panel-edit')}
8 %endif
8 %endif
9 </div>
9 </div>
10
10
11 <div class="panel-body user-profile-content">
11 <div class="panel-body user-profile-content fields">
12 <div class="fieldset">
12 <div class="field">
13 <div class="left-label">
13 <div class="label">
14 ${_('Photo')}:
14 ${_('Photo')}:
15 </div>
15 </div>
16 <div class="right-content">
16 <div class="input">
17 <div class="text-as-placeholder">
17 %if c.visual.use_gravatar:
18 %if c.visual.use_gravatar:
18 ${base.gravatar(c.user.email, 100)}
19 ${base.gravatar(c.user.email, 100)}
19 %else:
20 %else:
20 ${base.gravatar(c.user.email, 20)}
21 ${base.gravatar(c.user.email, 100)}
21 ${_('Avatars are disabled')}
22 %endif
22 %endif
23 </div>
23 </div>
24 </div>
24 </div>
25 <div class="fieldset">
25 </div>
26 <div class="left-label">
26 <div class="field">
27 <div class="label">
27 ${_('Username')}:
28 ${_('Username')}:
28 </div>
29 </div>
29 <div class="right-content">
30 <div class="input">
31 <div class="text-as-placeholder">
30 ${c.user.username}
32 ${c.user.username}
31 </div>
33 </div>
32 </div>
34 </div>
33 <div class="fieldset">
35 </div>
34 <div class="left-label">
36 <div class="field">
37 <div class="label">
35 ${_('First name')}:
38 ${_('First name')}:
36 </div>
39 </div>
37 <div class="right-content">
40 <div class="input">
41 <div class="text-as-placeholder">
38 ${c.user.first_name}
42 ${c.user.first_name}
39 </div>
43 </div>
40 </div>
44 </div>
41 <div class="fieldset">
45 </div>
42 <div class="left-label">
46 <div class="field">
47 <div class="label">
43 ${_('Last name')}:
48 ${_('Last name')}:
44 </div>
49 </div>
45 <div class="right-content">
50 <div class="input">
51 <div class="text-as-placeholder">
46 ${c.user.last_name}
52 ${c.user.last_name}
47 </div>
53 </div>
48 </div>
54 </div>
49 <div class="fieldset">
55 </div>
50 <div class="left-label">
56 <div class="field">
57 <div class="label">
51 ${_('Email')}:
58 ${_('Email')}:
52 </div>
59 </div>
53 <div class="right-content">
60 <div class="input">
54 ${c.user.email or _('Missing email, please update your user email address.')}
61 <div class="text-as-placeholder">
62 ${(c.user.email or _('Missing email, please update your user email address.'))}
63 </div>
55 </div>
64 </div>
56 </div>
65 </div>
57 </div>
66 </div>
@@ -1,1 +1,1 b''
1 {"results": [{"text": "Changesets", "children": [{"text": "r625:ead8f28a4bc2", "id": "ead8f28a4bc2f45ecfb148a6b8a89758b9654a84"}, {"text": "r535:c093f94d6d35", "id": "c093f94d6d358f13c55a687da66c30c41cca4153"}, {"text": "r534:559f640ec08b", "id": "559f640ec08b2a14c4a9ac863d8ca273545b8885"}, {"text": "r490:02a940b4ee37", "id": "02a940b4ee371ec64ef5b4c4870a5c89dc7fb98a"}, {"text": "r464:b45a4153a2d7", "id": "b45a4153a2d7adb8a78b63d35d39fac44a4320a6"}, {"text": "r460:0a54e66b9450", "id": "0a54e66b94502409074b163cd93c1233dcc0413f"}, {"text": "r457:a7bf2f6bf3d5", "id": "a7bf2f6bf3d5273da4bcd2032a891acae5a45e2b"}, {"text": "r456:7266de0154b4", "id": "7266de0154b4da7c42ba3d788876056dbf116b5a"}, {"text": "r455:666de4ee6507", "id": "666de4ee65074cd3e37ea01e75f65bd3e4c336bb"}, {"text": "r453:91acc599141c", "id": "91acc599141c87f03e0e3551dcaacf4492632e58"}, {"text": "r442:40a2d5d71b75", "id": "40a2d5d71b758e7eafc84a324ed55142cba22f42"}, {"text": "r440:d1f898326327", "id": "d1f898326327e20524fe22417c22d71064fe54a1"}, {"text": "r420:162a36830c23", "id": "162a36830c23ccf1bf1873157fd0c8d0dfc7c817"}, {"text": "r345:c994f0de03b2", "id": "c994f0de03b2a0aa848a04fc2c0d7e737dba31fc"}, {"text": "r340:5d3d4d2c262e", "id": "5d3d4d2c262e17b247d405feceeb09ff7408c940"}, {"text": "r334:4d4278a6390e", "id": "4d4278a6390e42f4fc777ecf1b9b628e77da8e22"}, {"text": "r298:00dffb625166", "id": "00dffb62516650bc5050d818eb47ea1ca207954d"}, {"text": "r297:47b6be9a812e", "id": "47b6be9a812ec3ed0384001a458a759f0f583fe2"}, {"text": "r289:1589fed841cd", "id": "1589fed841cd9ef33155f8560727809ac3ada2c8"}, {"text": "r285:afafd0ee2821", "id": "afafd0ee28218ab979678213cb96e9e4dbd7359b"}, {"text": "r284:639b115ed2b0", "id": "639b115ed2b02017824005b5ae66282c6e25eba8"}, {"text": "r283:fcf7562d7305", "id": "fcf7562d7305affc94fe20dc89a34aefd2b8aa1e"}, {"text": "r256:ec8cbdb5f364", "id": "ec8cbdb5f364fce7843cbf148c3d95d86f935339"}, {"text": "r255:0d74d2e2bdf3", "id": "0d74d2e2bdf3dcd5ee9fe4fcfe9016c5c6486f35"}, {"text": "r243:6894ad7d8223", "id": "6894ad7d8223b1e6853e9fdaa2c38d3f0cef1e38"}, {"text": "r231:31b3f4b599fa", "id": "31b3f4b599fae5f12cf438c73403679cdf923d75"}, {"text": "r220:3d2515dd21fb", "id": "3d2515dd21fb34fe6c5d0029075a863f3e92f5f6"}, {"text": "r186:f804e27aa496", "id": "f804e27aa4961f2e327f2a10ee373235df20ee21"}, {"text": "r182:7f00513785a1", "id": "7f00513785a13f273a4387ef086bb795b37f013c"}, {"text": "r181:6efcdc61028c", "id": "6efcdc61028c8edd1c787b3439fae71b77a17357"}, {"text": "r175:6c0ce52b229a", "id": "6c0ce52b229aa978889e91b38777f800e85f330b"}, {"text": "r165:09788a0b8a54", "id": "09788a0b8a5455e9678c3959214246574e546d4f"}, {"text": "r163:0164ee729def", "id": "0164ee729def0a253d6dcb594b5ee2a52fef4748"}, {"text": "r140:33fa32233551", "id": "33fa3223355104431402a888fa77a4e9956feb3e"}, {"text": "r126:fa014c12c26d", "id": "fa014c12c26d10ba682fadb78f2a11c24c8118e1"}, {"text": "r111:e686b958768e", "id": "e686b958768ee96af8029fe19c6050b1a8dd3b2b"}, {"text": "r109:ab5721ca0a08", "id": "ab5721ca0a081f26bf43d9051e615af2cc99952f"}, {"text": "r108:c877b68d18e7", "id": "c877b68d18e792a66b7f4c529ea02c8f80801542"}, {"text": "r107:4313566d2e41", "id": "4313566d2e417cb382948f8d9d7c765330356054"}, {"text": "r104:6c2303a79367", "id": "6c2303a793671e807d1cfc70134c9ca0767d98c2"}, {"text": "r102:54386793436c", "id": "54386793436c938cff89326944d4c2702340037d"}, {"text": "r101:54000345d2e7", "id": "54000345d2e78b03a99d561399e8e548de3f3203"}, {"text": "r99:1c6b3677b37e", "id": "1c6b3677b37ea064cb4b51714d8f7498f93f4b2b"}, {"text": "r93:2d03ca750a44", "id": "2d03ca750a44440fb5ea8b751176d1f36f8e8f46"}, {"text": "r92:2a08b128c206", "id": "2a08b128c206db48c2f0b8f70df060e6db0ae4f8"}, {"text": "r91:30c26513ff1e", "id": "30c26513ff1eb8e5ce0e1c6b477ee5dc50e2f34b"}, {"text": "r82:ac71e9503c2c", "id": "ac71e9503c2ca95542839af0ce7b64011b72ea7c"}, {"text": "r81:12669288fd13", "id": "12669288fd13adba2a9b7dd5b870cc23ffab92d2"}, {"text": "r76:5a0c84f3e6fe", "id": "5a0c84f3e6fe3473e4c8427199d5a6fc71a9b382"}, {"text": "r73:12f2f5e2b38e", "id": "12f2f5e2b38e6ff3fbdb5d722efed9aa72ecb0d5"}, {"text": "r61:5eab1222a7cd", "id": "5eab1222a7cd4bfcbabc218ca6d04276d4e27378"}, {"text": "r60:f50f42baeed5", "id": "f50f42baeed5af6518ef4b0cb2f1423f3851a941"}, {"text": "r59:d7e390a45f6a", "id": "d7e390a45f6aa96f04f5e7f583ad4f867431aa25"}, {"text": "r58:f15c21f97864", "id": "f15c21f97864b4f071cddfbf2750ec2e23859414"}, {"text": "r57:e906ef056cf5", "id": "e906ef056cf539a4e4e5fc8003eaf7cf14dd8ade"}, {"text": "r56:ea2b108b48aa", "id": "ea2b108b48aa8f8c9c4a941f66c1a03315ca1c3b"}, {"text": "r50:84dec09632a4", "id": "84dec09632a4458f79f50ddbbd155506c460b4f9"}, {"text": "r48:0115510b70c7", "id": "0115510b70c7229dbc5dc49036b32e7d91d23acd"}, {"text": "r46:2a13f185e452", "id": "2a13f185e4525f9d4b59882791a2d397b90d5ddc"}, {"text": "r30:3bf1c5868e57", "id": "3bf1c5868e570e39569d094f922d33ced2fa3b2b"}, {"text": "r26:b8d040125747", "id": "b8d04012574729d2c29886e53b1a43ef16dd00a1"}, {"text": "r24:6970b057cffe", "id": "6970b057cffe4aab0a792aa634c89f4bebf01441"}, {"text": "r8:dd80b0f6cf50", "id": "dd80b0f6cf5052f17cc738c2951c4f2070200d7f"}, {"text": "r7:ff7ca51e58c5", "id": "ff7ca51e58c505fec0dd2491de52c622bb7a806b"}]}, {"text": "Branches", "children": [{"text": "master", "id": "fd627b9e0dd80b47be81af07c4a98518244ed2f7"}]}, {"text": "Tags", "children": [{"text": "v0.2.2", "id": "137fea89f304a42321d40488091ee2ed419a3686"}, {"text": "v0.2.1", "id": "5051d0fa344d4408a2659d9a0348eb2d41868ecf"}, {"text": "v0.2.0", "id": "599ba911aa24d2981225f3966eb659dfae9e9f30"}, {"text": "v0.1.9", "id": "341d28f0eec5ddf0b6b77871e13c2bbd6bec685c"}, {"text": "v0.1.8", "id": "74ebce002c088b8a5ecf40073db09375515ecd68"}, {"text": "v0.1.7", "id": "4d78bf73b5c22c82b68f902f138f7881b4fffa2c"}, {"text": "v0.1.6", "id": "0205cb3f44223fb3099d12a77a69c81b798772d9"}, {"text": "v0.1.5", "id": "6c0ce52b229aa978889e91b38777f800e85f330b"}, {"text": "v0.1.4", "id": "7d735150934cd7645ac3051903add952390324a5"}, {"text": "v0.1.3", "id": "5a3a8fb005554692b16e21dee62bf02667d8dc3e"}, {"text": "v0.1.2", "id": "0ba5f8a4660034ff25c0cac2a5baabf5d2791d63"}, {"text": "v0.1.11", "id": "c60f01b77c42dce653d6b1d3b04689862c261929"}, {"text": "v0.1.10", "id": "10cddef6b794696066fb346434014f0a56810218"}, {"text": "v0.1.1", "id": "e6ea6d16e2f26250124a1f4b4fe37a912f9d86a0"}]}], "more": false}
1 {"results": [{"text": "Changesets", "children": [{"text": "r625:ead8f28a4bc2", "type": "sha", "id": "ead8f28a4bc2f45ecfb148a6b8a89758b9654a84"}, {"text": "r535:c093f94d6d35", "type": "sha", "id": "c093f94d6d358f13c55a687da66c30c41cca4153"}, {"text": "r534:559f640ec08b", "type": "sha", "id": "559f640ec08b2a14c4a9ac863d8ca273545b8885"}, {"text": "r490:02a940b4ee37", "type": "sha", "id": "02a940b4ee371ec64ef5b4c4870a5c89dc7fb98a"}, {"text": "r464:b45a4153a2d7", "type": "sha", "id": "b45a4153a2d7adb8a78b63d35d39fac44a4320a6"}, {"text": "r460:0a54e66b9450", "type": "sha", "id": "0a54e66b94502409074b163cd93c1233dcc0413f"}, {"text": "r457:a7bf2f6bf3d5", "type": "sha", "id": "a7bf2f6bf3d5273da4bcd2032a891acae5a45e2b"}, {"text": "r456:7266de0154b4", "type": "sha", "id": "7266de0154b4da7c42ba3d788876056dbf116b5a"}, {"text": "r455:666de4ee6507", "type": "sha", "id": "666de4ee65074cd3e37ea01e75f65bd3e4c336bb"}, {"text": "r453:91acc599141c", "type": "sha", "id": "91acc599141c87f03e0e3551dcaacf4492632e58"}, {"text": "r442:40a2d5d71b75", "type": "sha", "id": "40a2d5d71b758e7eafc84a324ed55142cba22f42"}, {"text": "r440:d1f898326327", "type": "sha", "id": "d1f898326327e20524fe22417c22d71064fe54a1"}, {"text": "r420:162a36830c23", "type": "sha", "id": "162a36830c23ccf1bf1873157fd0c8d0dfc7c817"}, {"text": "r345:c994f0de03b2", "type": "sha", "id": "c994f0de03b2a0aa848a04fc2c0d7e737dba31fc"}, {"text": "r340:5d3d4d2c262e", "type": "sha", "id": "5d3d4d2c262e17b247d405feceeb09ff7408c940"}, {"text": "r334:4d4278a6390e", "type": "sha", "id": "4d4278a6390e42f4fc777ecf1b9b628e77da8e22"}, {"text": "r298:00dffb625166", "type": "sha", "id": "00dffb62516650bc5050d818eb47ea1ca207954d"}, {"text": "r297:47b6be9a812e", "type": "sha", "id": "47b6be9a812ec3ed0384001a458a759f0f583fe2"}, {"text": "r289:1589fed841cd", "type": "sha", "id": "1589fed841cd9ef33155f8560727809ac3ada2c8"}, {"text": "r285:afafd0ee2821", "type": "sha", "id": "afafd0ee28218ab979678213cb96e9e4dbd7359b"}, {"text": "r284:639b115ed2b0", "type": "sha", "id": "639b115ed2b02017824005b5ae66282c6e25eba8"}, {"text": "r283:fcf7562d7305", "type": "sha", "id": "fcf7562d7305affc94fe20dc89a34aefd2b8aa1e"}, {"text": "r256:ec8cbdb5f364", "type": "sha", "id": "ec8cbdb5f364fce7843cbf148c3d95d86f935339"}, {"text": "r255:0d74d2e2bdf3", "type": "sha", "id": "0d74d2e2bdf3dcd5ee9fe4fcfe9016c5c6486f35"}, {"text": "r243:6894ad7d8223", "type": "sha", "id": "6894ad7d8223b1e6853e9fdaa2c38d3f0cef1e38"}, {"text": "r231:31b3f4b599fa", "type": "sha", "id": "31b3f4b599fae5f12cf438c73403679cdf923d75"}, {"text": "r220:3d2515dd21fb", "type": "sha", "id": "3d2515dd21fb34fe6c5d0029075a863f3e92f5f6"}, {"text": "r186:f804e27aa496", "type": "sha", "id": "f804e27aa4961f2e327f2a10ee373235df20ee21"}, {"text": "r182:7f00513785a1", "type": "sha", "id": "7f00513785a13f273a4387ef086bb795b37f013c"}, {"text": "r181:6efcdc61028c", "type": "sha", "id": "6efcdc61028c8edd1c787b3439fae71b77a17357"}, {"text": "r175:6c0ce52b229a", "type": "sha", "id": "6c0ce52b229aa978889e91b38777f800e85f330b"}, {"text": "r165:09788a0b8a54", "type": "sha", "id": "09788a0b8a5455e9678c3959214246574e546d4f"}, {"text": "r163:0164ee729def", "type": "sha", "id": "0164ee729def0a253d6dcb594b5ee2a52fef4748"}, {"text": "r140:33fa32233551", "type": "sha", "id": "33fa3223355104431402a888fa77a4e9956feb3e"}, {"text": "r126:fa014c12c26d", "type": "sha", "id": "fa014c12c26d10ba682fadb78f2a11c24c8118e1"}, {"text": "r111:e686b958768e", "type": "sha", "id": "e686b958768ee96af8029fe19c6050b1a8dd3b2b"}, {"text": "r109:ab5721ca0a08", "type": "sha", "id": "ab5721ca0a081f26bf43d9051e615af2cc99952f"}, {"text": "r108:c877b68d18e7", "type": "sha", "id": "c877b68d18e792a66b7f4c529ea02c8f80801542"}, {"text": "r107:4313566d2e41", "type": "sha", "id": "4313566d2e417cb382948f8d9d7c765330356054"}, {"text": "r104:6c2303a79367", "type": "sha", "id": "6c2303a793671e807d1cfc70134c9ca0767d98c2"}, {"text": "r102:54386793436c", "type": "sha", "id": "54386793436c938cff89326944d4c2702340037d"}, {"text": "r101:54000345d2e7", "type": "sha", "id": "54000345d2e78b03a99d561399e8e548de3f3203"}, {"text": "r99:1c6b3677b37e", "type": "sha", "id": "1c6b3677b37ea064cb4b51714d8f7498f93f4b2b"}, {"text": "r93:2d03ca750a44", "type": "sha", "id": "2d03ca750a44440fb5ea8b751176d1f36f8e8f46"}, {"text": "r92:2a08b128c206", "type": "sha", "id": "2a08b128c206db48c2f0b8f70df060e6db0ae4f8"}, {"text": "r91:30c26513ff1e", "type": "sha", "id": "30c26513ff1eb8e5ce0e1c6b477ee5dc50e2f34b"}, {"text": "r82:ac71e9503c2c", "type": "sha", "id": "ac71e9503c2ca95542839af0ce7b64011b72ea7c"}, {"text": "r81:12669288fd13", "type": "sha", "id": "12669288fd13adba2a9b7dd5b870cc23ffab92d2"}, {"text": "r76:5a0c84f3e6fe", "type": "sha", "id": "5a0c84f3e6fe3473e4c8427199d5a6fc71a9b382"}, {"text": "r73:12f2f5e2b38e", "type": "sha", "id": "12f2f5e2b38e6ff3fbdb5d722efed9aa72ecb0d5"}, {"text": "r61:5eab1222a7cd", "type": "sha", "id": "5eab1222a7cd4bfcbabc218ca6d04276d4e27378"}, {"text": "r60:f50f42baeed5", "type": "sha", "id": "f50f42baeed5af6518ef4b0cb2f1423f3851a941"}, {"text": "r59:d7e390a45f6a", "type": "sha", "id": "d7e390a45f6aa96f04f5e7f583ad4f867431aa25"}, {"text": "r58:f15c21f97864", "type": "sha", "id": "f15c21f97864b4f071cddfbf2750ec2e23859414"}, {"text": "r57:e906ef056cf5", "type": "sha", "id": "e906ef056cf539a4e4e5fc8003eaf7cf14dd8ade"}, {"text": "r56:ea2b108b48aa", "type": "sha", "id": "ea2b108b48aa8f8c9c4a941f66c1a03315ca1c3b"}, {"text": "r50:84dec09632a4", "type": "sha", "id": "84dec09632a4458f79f50ddbbd155506c460b4f9"}, {"text": "r48:0115510b70c7", "type": "sha", "id": "0115510b70c7229dbc5dc49036b32e7d91d23acd"}, {"text": "r46:2a13f185e452", "type": "sha", "id": "2a13f185e4525f9d4b59882791a2d397b90d5ddc"}, {"text": "r30:3bf1c5868e57", "type": "sha", "id": "3bf1c5868e570e39569d094f922d33ced2fa3b2b"}, {"text": "r26:b8d040125747", "type": "sha", "id": "b8d04012574729d2c29886e53b1a43ef16dd00a1"}, {"text": "r24:6970b057cffe", "type": "sha", "id": "6970b057cffe4aab0a792aa634c89f4bebf01441"}, {"text": "r8:dd80b0f6cf50", "type": "sha", "id": "dd80b0f6cf5052f17cc738c2951c4f2070200d7f"}, {"text": "r7:ff7ca51e58c5", "type": "sha", "id": "ff7ca51e58c505fec0dd2491de52c622bb7a806b"}]}, {"text": "Branches", "children": [{"text": "master", "type": "branch", "id": "fd627b9e0dd80b47be81af07c4a98518244ed2f7"}]}, {"text": "Tags", "children": [{"text": "v0.2.2", "type": "tag", "id": "137fea89f304a42321d40488091ee2ed419a3686"}, {"text": "v0.2.1", "type": "tag", "id": "5051d0fa344d4408a2659d9a0348eb2d41868ecf"}, {"text": "v0.2.0", "type": "tag", "id": "599ba911aa24d2981225f3966eb659dfae9e9f30"}, {"text": "v0.1.9", "type": "tag", "id": "341d28f0eec5ddf0b6b77871e13c2bbd6bec685c"}, {"text": "v0.1.8", "type": "tag", "id": "74ebce002c088b8a5ecf40073db09375515ecd68"}, {"text": "v0.1.7", "type": "tag", "id": "4d78bf73b5c22c82b68f902f138f7881b4fffa2c"}, {"text": "v0.1.6", "type": "tag", "id": "0205cb3f44223fb3099d12a77a69c81b798772d9"}, {"text": "v0.1.5", "type": "tag", "id": "6c0ce52b229aa978889e91b38777f800e85f330b"}, {"text": "v0.1.4", "type": "tag", "id": "7d735150934cd7645ac3051903add952390324a5"}, {"text": "v0.1.3", "type": "tag", "id": "5a3a8fb005554692b16e21dee62bf02667d8dc3e"}, {"text": "v0.1.2", "type": "tag", "id": "0ba5f8a4660034ff25c0cac2a5baabf5d2791d63"}, {"text": "v0.1.11", "type": "tag", "id": "c60f01b77c42dce653d6b1d3b04689862c261929"}, {"text": "v0.1.10", "type": "tag", "id": "10cddef6b794696066fb346434014f0a56810218"}, {"text": "v0.1.1", "type": "tag", "id": "e6ea6d16e2f26250124a1f4b4fe37a912f9d86a0"}]}], "more": false}
@@ -1,1 +1,1 b''
1 {"results": [{"text": "Changesets", "children": [{"text": "r648:dbec37a0d5ca (default)", "id": "dbec37a0d5cab8ff39af4cfc4a4cd3996e4acfc6"}, {"text": "r639:1d20ed9eda94 (default)", "id": "1d20ed9eda9482d46ff0a6af5812550218b3ff15"}, {"text": "r547:0173395e8227 (default)", "id": "0173395e822797f098799ed95c1a81b6a547a9ad"}, {"text": "r546:afbb45ade933 (default)", "id": "afbb45ade933a8182f1d8ec5d4d1bb2de2572043"}, {"text": "r502:6f093e30cac3 (default)", "id": "6f093e30cac34e6b4b11275a9f22f80c5d7ad1f7"}, {"text": "r476:c7e2212dd2ae (default)", "id": "c7e2212dd2ae975d1d06534a3d7e317165c06960"}, {"text": "r472:45477506df79 (default)", "id": "45477506df79f701bf69419aac3e1f0fed3c5bcf"}, {"text": "r469:5fc76cb25d11 (default)", "id": "5fc76cb25d11e07c60de040f78b8cd265ff10d53"}, {"text": "r468:b073433cf899 (default)", "id": "b073433cf8994969ee5cd7cce84cbe587bb880b2"}, {"text": "r467:7a74dbfcacd1 (default)", "id": "7a74dbfcacd1dbcb58bb9c860b2f29fbb22c4c96"}, {"text": "r465:71ee52cc4d62 (default)", "id": "71ee52cc4d629096bdbee036325975dac2af4501"}, {"text": "r452:a5b217d26c5f (default)", "id": "a5b217d26c5f111e72bae4de672b084ee0fbf75c"}, {"text": "r450:47aedd538bf6 (default)", "id": "47aedd538bf616eedcb0e7d630ea476df0e159c7"}, {"text": "r432:8e4915fa32d7 (default)", "id": "8e4915fa32d727dcbf09746f637a5f82e539511e"}, {"text": "r356:25213a5fbb04 (default)", "id": "25213a5fbb048dff8ba65d21e466a835536e5b70"}, {"text": "r351:23debcedddc1 (default)", "id": "23debcedddc1c23c14be33e713e7786d4a9de471"}, {"text": "r342:61e25b2a90a1 (default)", "id": "61e25b2a90a19e7fffd75dea1e4c7e20df526bbe"}, {"text": "r318:fb95b340e0d0 (webvcs)", "id": "fb95b340e0d03fa51f33c56c991c08077c99303e"}, {"text": "r303:bda35e0e564f (default)", "id": "bda35e0e564fbbc5cd26fe0a37fb647a254c99fe"}, {"text": "r302:97ff74896d7d (default)", "id": "97ff74896d7dbf3115a337a421d44b55154acc89"}, {"text": "r293:cec3473c3fdb (default)", "id": "cec3473c3fdb9599c98067182a075b49bde570f9"}, {"text": "r289:0e86c43eef86 (default)", "id": "0e86c43eef866a013a587666a877c879899599bb"}, {"text": "r288:91a27c312808 (default)", "id": "91a27c312808100cf20a602f78befbbff9d89bfd"}, {"text": "r287:400e36a1670a (default)", "id": "400e36a1670a57d11e3edcb5b07bf82c30006d0b"}, {"text": "r261:014fb17dfc95 (default)", "id": "014fb17dfc95b0995e838c565376bf9a993e230a"}, {"text": "r260:cca7aebbc4d6 (default)", "id": "cca7aebbc4d6125798446b11e69dc8847834a982"}, {"text": "r258:14cdb2957c01 (workdir)", "id": "14cdb2957c011a5feba36f50d960d9832ba0f0c1"}, {"text": "r245:34df20118ed7 (default)", "id": "34df20118ed74b5987d22a579e8a60e903da5bf8"}, {"text": "r233:0375d9042a64 (workdir)", "id": "0375d9042a64a1ac1641528f0f0668f9a339e86d"}, {"text": "r222:94aa45fc1806 (workdir)", "id": "94aa45fc1806c04d4ba640933edf682c22478453"}, {"text": "r188:7ed99bc73881 (default)", "id": "7ed99bc738818879941e3ce20243f8856a7cfc84"}, {"text": "r184:1e85975528bc (default)", "id": "1e85975528bcebe853732a9e5fb8dbf4461f6bb2"}, {"text": "r183:ed30beddde7b (default)", "id": "ed30beddde7bbddb26042625be19bcd11576c1dd"}, {"text": "r177:a6664e18181c (default)", "id": "a6664e18181c6fc81b751a8d01474e7e1a3fe7fc"}, {"text": "r167:8911406ad776 (default)", "id": "8911406ad776fdd3d0b9932a2e89677e57405a48"}, {"text": "r165:aa957ed78c35 (default)", "id": "aa957ed78c35a1541f508d2ec90e501b0a9e3167"}, {"text": "r140:48e11b73e94c (default)", "id": "48e11b73e94c0db33e736eaeea692f990cb0b5f1"}, {"text": "r126:adf3cbf48329 (default)", "id": "adf3cbf483298563b968a6c673cd5bde5f7d5eea"}, {"text": "r113:6249fd0fb2cf (git)", "id": "6249fd0fb2cfb1411e764129f598e2cf0de79a6f"}, {"text": "r109:75feb4c33e81 (default)", "id": "75feb4c33e81186c87eac740cee2447330288412"}, {"text": "r108:9a4dc232ecdc (default)", "id": "9a4dc232ecdc763ef2e98ae2238cfcbba4f6ad8d"}, {"text": "r107:595cce4efa21 (default)", "id": "595cce4efa21fda2f2e4eeb4fe5f2a6befe6fa2d"}, {"text": "r104:4a8bd421fbc2 (default)", "id": "4a8bd421fbc2dfbfb70d85a3fe064075ab2c49da"}, {"text": "r102:57be63fc8f85 (default)", "id": "57be63fc8f85e65a0106a53187f7316f8c487ffa"}, {"text": "r101:5530bd87f7e2 (git)", "id": "5530bd87f7e2e124a64d07cb2654c997682128be"}, {"text": "r99:e516008b1c93 (default)", "id": "e516008b1c93f142263dc4b7961787cbad654ce1"}, {"text": "r93:41f43fc74b8b (default)", "id": "41f43fc74b8b285984554532eb105ac3be5c434f"}, {"text": "r92:cc66b61b8455 (default)", "id": "cc66b61b8455b264a7a8a2d8ddc80fcfc58c221e"}, {"text": "r91:73ab5b616b32 (default)", "id": "73ab5b616b3271b0518682fb4988ce421de8099f"}, {"text": "r82:e0da75f308c0 (default)", "id": "e0da75f308c0f18f98e9ce6257626009fdda2b39"}, {"text": "r81:fb2e41e0f081 (default)", "id": "fb2e41e0f0810be4d7103bc2a4c7be16ee3ec611"}, {"text": "r76:602ae2f5e7ad (default)", "id": "602ae2f5e7ade70b3b66a58cdd9e3e613dc8a028"}, {"text": "r73:a066b25d5df7 (default)", "id": "a066b25d5df7016b45a41b7e2a78c33b57adc235"}, {"text": "r61:637a933c9059 (web)", "id": "637a933c905958ce5151f154147c25c1c7b68832"}, {"text": "r60:0c21004effeb (web)", "id": "0c21004effeb8ce2d2d5b4a8baf6afa8394b6fbc"}, {"text": "r59:a1f39c56d3f1 (web)", "id": "a1f39c56d3f1d52d5fb5920370a2a2716cd9a444"}, {"text": "r58:97d32df05c71 (web)", "id": "97d32df05c715a3bbf936bf3cc4e32fb77fe1a7f"}, {"text": "r57:08eaf1451771 (web)", "id": "08eaf14517718dccea4b67755a93368341aca919"}, {"text": "r56:22f71ad26526 (web)", "id": "22f71ad265265a53238359c883aa976e725aa07d"}, {"text": "r49:97501f02b7b4 (web)", "id": "97501f02b7b4330924b647755663a2d90a5e638d"}, {"text": "r47:86ede6754f2b (web)", "id": "86ede6754f2b27309452bb11f997386ae01d0e5a"}, {"text": "r45:014c40c0203c (web)", "id": "014c40c0203c423dc19ecf94644f7cac9d4cdce0"}, {"text": "r30:ee87846a61c1 (default)", "id": "ee87846a61c12153b51543bf860e1026c6d3dcba"}, {"text": "r26:9bb326a04ae5 (default)", "id": "9bb326a04ae5d98d437dece54be04f830cf1edd9"}, {"text": "r24:536c1a194283 (default)", "id": "536c1a19428381cfea92ac44985304f6a8049569"}, {"text": "r8:dc5d2c0661b6 (default)", "id": "dc5d2c0661b61928834a785d3e64a3f80d3aad9c"}, {"text": "r7:3803844fdbd3 (default)", "id": "3803844fdbd3b711175fc3da9bdacfcd6d29a6fb"}]}, {"text": "Branches", "children": [{"text": "default", "id": "2062ec7beeeaf9f44a1c25c41479565040b930b2"}, {"text": "stable", "id": "4f7e2131323e0749a740c0a56ab68ae9269c562a"}]}, {"text": "Tags", "children": [{"text": "v0.2.0", "id": "2c96c02def9a7c997f33047761a53943e6254396"}, {"text": "v0.1.9", "id": "8680b1d1cee3aa3c1ab3734b76ee164bbedbc5c9"}, {"text": "v0.1.8", "id": "ecb25ba9c96faf1e65a0bc3fd914918420a2f116"}, {"text": "v0.1.7", "id": "f67633a2894edaf28513706d558205fa93df9209"}, {"text": "v0.1.6", "id": "02b38c0eb6f982174750c0e309ff9faddc0c7e12"}, {"text": "v0.1.5", "id": "a6664e18181c6fc81b751a8d01474e7e1a3fe7fc"}, {"text": "v0.1.4", "id": "fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200"}, {"text": "v0.1.3", "id": "17544fbfcd33ffb439e2b728b5d526b1ef30bfcf"}, {"text": "v0.1.2", "id": "a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720"}, {"text": "v0.1.11", "id": "fef5bfe1dc17611d5fb59a7f6f95c55c3606f933"}, {"text": "v0.1.10", "id": "92831aebf2f8dd4879e897024b89d09af214df1c"}, {"text": "v0.1.1", "id": "eb3a60fc964309c1a318b8dfe26aa2d1586c85ae"}, {"text": "tip", "id": "2062ec7beeeaf9f44a1c25c41479565040b930b2"}]}], "more": false}
1 {"results": [{"text": "Changesets", "children": [{"text": "r648:dbec37a0d5ca (default)", "type": "sha", "id": "dbec37a0d5cab8ff39af4cfc4a4cd3996e4acfc6"}, {"text": "r639:1d20ed9eda94 (default)", "type": "sha", "id": "1d20ed9eda9482d46ff0a6af5812550218b3ff15"}, {"text": "r547:0173395e8227 (default)", "type": "sha", "id": "0173395e822797f098799ed95c1a81b6a547a9ad"}, {"text": "r546:afbb45ade933 (default)", "type": "sha", "id": "afbb45ade933a8182f1d8ec5d4d1bb2de2572043"}, {"text": "r502:6f093e30cac3 (default)", "type": "sha", "id": "6f093e30cac34e6b4b11275a9f22f80c5d7ad1f7"}, {"text": "r476:c7e2212dd2ae (default)", "type": "sha", "id": "c7e2212dd2ae975d1d06534a3d7e317165c06960"}, {"text": "r472:45477506df79 (default)", "type": "sha", "id": "45477506df79f701bf69419aac3e1f0fed3c5bcf"}, {"text": "r469:5fc76cb25d11 (default)", "type": "sha", "id": "5fc76cb25d11e07c60de040f78b8cd265ff10d53"}, {"text": "r468:b073433cf899 (default)", "type": "sha", "id": "b073433cf8994969ee5cd7cce84cbe587bb880b2"}, {"text": "r467:7a74dbfcacd1 (default)", "type": "sha", "id": "7a74dbfcacd1dbcb58bb9c860b2f29fbb22c4c96"}, {"text": "r465:71ee52cc4d62 (default)", "type": "sha", "id": "71ee52cc4d629096bdbee036325975dac2af4501"}, {"text": "r452:a5b217d26c5f (default)", "type": "sha", "id": "a5b217d26c5f111e72bae4de672b084ee0fbf75c"}, {"text": "r450:47aedd538bf6 (default)", "type": "sha", "id": "47aedd538bf616eedcb0e7d630ea476df0e159c7"}, {"text": "r432:8e4915fa32d7 (default)", "type": "sha", "id": "8e4915fa32d727dcbf09746f637a5f82e539511e"}, {"text": "r356:25213a5fbb04 (default)", "type": "sha", "id": "25213a5fbb048dff8ba65d21e466a835536e5b70"}, {"text": "r351:23debcedddc1 (default)", "type": "sha", "id": "23debcedddc1c23c14be33e713e7786d4a9de471"}, {"text": "r342:61e25b2a90a1 (default)", "type": "sha", "id": "61e25b2a90a19e7fffd75dea1e4c7e20df526bbe"}, {"text": "r318:fb95b340e0d0 (webvcs)", "type": "sha", "id": "fb95b340e0d03fa51f33c56c991c08077c99303e"}, {"text": "r303:bda35e0e564f (default)", "type": "sha", "id": "bda35e0e564fbbc5cd26fe0a37fb647a254c99fe"}, {"text": "r302:97ff74896d7d (default)", "type": "sha", "id": "97ff74896d7dbf3115a337a421d44b55154acc89"}, {"text": "r293:cec3473c3fdb (default)", "type": "sha", "id": "cec3473c3fdb9599c98067182a075b49bde570f9"}, {"text": "r289:0e86c43eef86 (default)", "type": "sha", "id": "0e86c43eef866a013a587666a877c879899599bb"}, {"text": "r288:91a27c312808 (default)", "type": "sha", "id": "91a27c312808100cf20a602f78befbbff9d89bfd"}, {"text": "r287:400e36a1670a (default)", "type": "sha", "id": "400e36a1670a57d11e3edcb5b07bf82c30006d0b"}, {"text": "r261:014fb17dfc95 (default)", "type": "sha", "id": "014fb17dfc95b0995e838c565376bf9a993e230a"}, {"text": "r260:cca7aebbc4d6 (default)", "type": "sha", "id": "cca7aebbc4d6125798446b11e69dc8847834a982"}, {"text": "r258:14cdb2957c01 (workdir)", "type": "sha", "id": "14cdb2957c011a5feba36f50d960d9832ba0f0c1"}, {"text": "r245:34df20118ed7 (default)", "type": "sha", "id": "34df20118ed74b5987d22a579e8a60e903da5bf8"}, {"text": "r233:0375d9042a64 (workdir)", "type": "sha", "id": "0375d9042a64a1ac1641528f0f0668f9a339e86d"}, {"text": "r222:94aa45fc1806 (workdir)", "type": "sha", "id": "94aa45fc1806c04d4ba640933edf682c22478453"}, {"text": "r188:7ed99bc73881 (default)", "type": "sha", "id": "7ed99bc738818879941e3ce20243f8856a7cfc84"}, {"text": "r184:1e85975528bc (default)", "type": "sha", "id": "1e85975528bcebe853732a9e5fb8dbf4461f6bb2"}, {"text": "r183:ed30beddde7b (default)", "type": "sha", "id": "ed30beddde7bbddb26042625be19bcd11576c1dd"}, {"text": "r177:a6664e18181c (default)", "type": "sha", "id": "a6664e18181c6fc81b751a8d01474e7e1a3fe7fc"}, {"text": "r167:8911406ad776 (default)", "type": "sha", "id": "8911406ad776fdd3d0b9932a2e89677e57405a48"}, {"text": "r165:aa957ed78c35 (default)", "type": "sha", "id": "aa957ed78c35a1541f508d2ec90e501b0a9e3167"}, {"text": "r140:48e11b73e94c (default)", "type": "sha", "id": "48e11b73e94c0db33e736eaeea692f990cb0b5f1"}, {"text": "r126:adf3cbf48329 (default)", "type": "sha", "id": "adf3cbf483298563b968a6c673cd5bde5f7d5eea"}, {"text": "r113:6249fd0fb2cf (git)", "type": "sha", "id": "6249fd0fb2cfb1411e764129f598e2cf0de79a6f"}, {"text": "r109:75feb4c33e81 (default)", "type": "sha", "id": "75feb4c33e81186c87eac740cee2447330288412"}, {"text": "r108:9a4dc232ecdc (default)", "type": "sha", "id": "9a4dc232ecdc763ef2e98ae2238cfcbba4f6ad8d"}, {"text": "r107:595cce4efa21 (default)", "type": "sha", "id": "595cce4efa21fda2f2e4eeb4fe5f2a6befe6fa2d"}, {"text": "r104:4a8bd421fbc2 (default)", "type": "sha", "id": "4a8bd421fbc2dfbfb70d85a3fe064075ab2c49da"}, {"text": "r102:57be63fc8f85 (default)", "type": "sha", "id": "57be63fc8f85e65a0106a53187f7316f8c487ffa"}, {"text": "r101:5530bd87f7e2 (git)", "type": "sha", "id": "5530bd87f7e2e124a64d07cb2654c997682128be"}, {"text": "r99:e516008b1c93 (default)", "type": "sha", "id": "e516008b1c93f142263dc4b7961787cbad654ce1"}, {"text": "r93:41f43fc74b8b (default)", "type": "sha", "id": "41f43fc74b8b285984554532eb105ac3be5c434f"}, {"text": "r92:cc66b61b8455 (default)", "type": "sha", "id": "cc66b61b8455b264a7a8a2d8ddc80fcfc58c221e"}, {"text": "r91:73ab5b616b32 (default)", "type": "sha", "id": "73ab5b616b3271b0518682fb4988ce421de8099f"}, {"text": "r82:e0da75f308c0 (default)", "type": "sha", "id": "e0da75f308c0f18f98e9ce6257626009fdda2b39"}, {"text": "r81:fb2e41e0f081 (default)", "type": "sha", "id": "fb2e41e0f0810be4d7103bc2a4c7be16ee3ec611"}, {"text": "r76:602ae2f5e7ad (default)", "type": "sha", "id": "602ae2f5e7ade70b3b66a58cdd9e3e613dc8a028"}, {"text": "r73:a066b25d5df7 (default)", "type": "sha", "id": "a066b25d5df7016b45a41b7e2a78c33b57adc235"}, {"text": "r61:637a933c9059 (web)", "type": "sha", "id": "637a933c905958ce5151f154147c25c1c7b68832"}, {"text": "r60:0c21004effeb (web)", "type": "sha", "id": "0c21004effeb8ce2d2d5b4a8baf6afa8394b6fbc"}, {"text": "r59:a1f39c56d3f1 (web)", "type": "sha", "id": "a1f39c56d3f1d52d5fb5920370a2a2716cd9a444"}, {"text": "r58:97d32df05c71 (web)", "type": "sha", "id": "97d32df05c715a3bbf936bf3cc4e32fb77fe1a7f"}, {"text": "r57:08eaf1451771 (web)", "type": "sha", "id": "08eaf14517718dccea4b67755a93368341aca919"}, {"text": "r56:22f71ad26526 (web)", "type": "sha", "id": "22f71ad265265a53238359c883aa976e725aa07d"}, {"text": "r49:97501f02b7b4 (web)", "type": "sha", "id": "97501f02b7b4330924b647755663a2d90a5e638d"}, {"text": "r47:86ede6754f2b (web)", "type": "sha", "id": "86ede6754f2b27309452bb11f997386ae01d0e5a"}, {"text": "r45:014c40c0203c (web)", "type": "sha", "id": "014c40c0203c423dc19ecf94644f7cac9d4cdce0"}, {"text": "r30:ee87846a61c1 (default)", "type": "sha", "id": "ee87846a61c12153b51543bf860e1026c6d3dcba"}, {"text": "r26:9bb326a04ae5 (default)", "type": "sha", "id": "9bb326a04ae5d98d437dece54be04f830cf1edd9"}, {"text": "r24:536c1a194283 (default)", "type": "sha", "id": "536c1a19428381cfea92ac44985304f6a8049569"}, {"text": "r8:dc5d2c0661b6 (default)", "type": "sha", "id": "dc5d2c0661b61928834a785d3e64a3f80d3aad9c"}, {"text": "r7:3803844fdbd3 (default)", "type": "sha", "id": "3803844fdbd3b711175fc3da9bdacfcd6d29a6fb"}]}, {"text": "Branches", "children": [{"text": "default", "type": "branch", "id": "2062ec7beeeaf9f44a1c25c41479565040b930b2"}, {"text": "stable", "type": "branch", "id": "4f7e2131323e0749a740c0a56ab68ae9269c562a"}]}, {"text": "Tags", "children": [{"text": "v0.2.0", "type": "tag", "id": "2c96c02def9a7c997f33047761a53943e6254396"}, {"text": "v0.1.9", "type": "tag", "id": "8680b1d1cee3aa3c1ab3734b76ee164bbedbc5c9"}, {"text": "v0.1.8", "type": "tag", "id": "ecb25ba9c96faf1e65a0bc3fd914918420a2f116"}, {"text": "v0.1.7", "type": "tag", "id": "f67633a2894edaf28513706d558205fa93df9209"}, {"text": "v0.1.6", "type": "tag", "id": "02b38c0eb6f982174750c0e309ff9faddc0c7e12"}, {"text": "v0.1.5", "type": "tag", "id": "a6664e18181c6fc81b751a8d01474e7e1a3fe7fc"}, {"text": "v0.1.4", "type": "tag", "id": "fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200"}, {"text": "v0.1.3", "type": "tag", "id": "17544fbfcd33ffb439e2b728b5d526b1ef30bfcf"}, {"text": "v0.1.2", "type": "tag", "id": "a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720"}, {"text": "v0.1.11", "type": "tag", "id": "fef5bfe1dc17611d5fb59a7f6f95c55c3606f933"}, {"text": "v0.1.10", "type": "tag", "id": "92831aebf2f8dd4879e897024b89d09af214df1c"}, {"text": "v0.1.1", "type": "tag", "id": "eb3a60fc964309c1a318b8dfe26aa2d1586c85ae"}, {"text": "tip", "type": "tag", "id": "2062ec7beeeaf9f44a1c25c41479565040b930b2"}]}], "more": false} No newline at end of file
@@ -1,1 +1,1 b''
1 {"more": false, "results": [{"text": "Changesets", "children": [{"text": "r15:16", "id": "16"}, {"text": "r12:13", "id": "13"}, {"text": "r7:8", "id": "8"}, {"text": "r3:4", "id": "4"}, {"text": "r2:3", "id": "3"}]}, {"text": "Branches", "children": [{"text": "branches/add-docs", "id": "branches/add-docs/example.py@26"}, {"text": "branches/argparse", "id": "branches/argparse/example.py@26"}, {"text": "trunk", "id": "trunk/example.py@26"}]}, {"text": "Tags", "children": [{"text": "tags/v0.1", "id": "tags/v0.1/example.py@26"}, {"text": "tags/v0.2", "id": "tags/v0.2/example.py@26"}, {"text": "tags/v0.3", "id": "tags/v0.3/example.py@26"}, {"text": "tags/v0.5", "id": "tags/v0.5/example.py@26"}]}]} No newline at end of file
1 {"results": [{"text": "Changesets", "children": [{"text": "r15:16", "type": "sha", "id": "16"}, {"text": "r12:13", "type": "sha", "id": "13"}, {"text": "r7:8", "type": "sha", "id": "8"}, {"text": "r3:4", "type": "sha", "id": "4"}, {"text": "r2:3", "type": "sha", "id": "3"}]}, {"text": "Branches", "children": [{"text": "branches/add-docs", "type": "branch", "id": "branches/add-docs/example.py@26"}, {"text": "branches/argparse", "type": "branch", "id": "branches/argparse/example.py@26"}, {"text": "trunk", "type": "branch", "id": "trunk/example.py@26"}]}, {"text": "Tags", "children": [{"text": "tags/v0.1", "type": "tag", "id": "tags/v0.1/example.py@26"}, {"text": "tags/v0.2", "type": "tag", "id": "tags/v0.2/example.py@26"}, {"text": "tags/v0.3", "type": "tag", "id": "tags/v0.3/example.py@26"}, {"text": "tags/v0.5", "type": "tag", "id": "tags/v0.5/example.py@26"}]}], "more": false} No newline at end of file
@@ -1,1 +1,1 b''
1 {"results": [{"text": "Changesets", "children": [{"text": "r382:383", "id": "383"}, {"text": "r323:324", "id": "324"}, {"text": "r322:323", "id": "323"}, {"text": "r299:300", "id": "300"}, {"text": "r277:278", "id": "278"}, {"text": "r273:274", "id": "274"}, {"text": "r270:271", "id": "271"}, {"text": "r269:270", "id": "270"}, {"text": "r263:264", "id": "264"}, {"text": "r261:262", "id": "262"}, {"text": "r251:252", "id": "252"}, {"text": "r208:209", "id": "209"}, {"text": "r202:203", "id": "203"}, {"text": "r173:174", "id": "174"}, {"text": "r172:173", "id": "173"}, {"text": "r171:172", "id": "172"}, {"text": "r145:146", "id": "146"}, {"text": "r144:145", "id": "145"}, {"text": "r140:141", "id": "141"}, {"text": "r134:135", "id": "135"}, {"text": "r107:108", "id": "108"}, {"text": "r106:107", "id": "107"}, {"text": "r100:101", "id": "101"}, {"text": "r94:95", "id": "95"}, {"text": "r85:86", "id": "86"}, {"text": "r73:74", "id": "74"}, {"text": "r72:73", "id": "73"}, {"text": "r71:72", "id": "72"}, {"text": "r69:70", "id": "70"}, {"text": "r67:68", "id": "68"}, {"text": "r63:64", "id": "64"}, {"text": "r62:63", "id": "63"}, {"text": "r61:62", "id": "62"}, {"text": "r50:51", "id": "51"}, {"text": "r49:50", "id": "50"}, {"text": "r48:49", "id": "49"}, {"text": "r47:48", "id": "48"}, {"text": "r46:47", "id": "47"}, {"text": "r45:46", "id": "46"}, {"text": "r41:42", "id": "42"}, {"text": "r39:40", "id": "40"}, {"text": "r37:38", "id": "38"}, {"text": "r25:26", "id": "26"}, {"text": "r23:24", "id": "24"}, {"text": "r8:9", "id": "9"}, {"text": "r7:8", "id": "8"}]}, {"text": "Branches", "children": []}, {"text": "Tags", "children": []}], "more": false} No newline at end of file
1 {"results": [{"text": "Changesets", "children": [{"text": "r382:383", "type": "sha", "id": "383"}, {"text": "r323:324", "type": "sha", "id": "324"}, {"text": "r322:323", "type": "sha", "id": "323"}, {"text": "r299:300", "type": "sha", "id": "300"}, {"text": "r277:278", "type": "sha", "id": "278"}, {"text": "r273:274", "type": "sha", "id": "274"}, {"text": "r270:271", "type": "sha", "id": "271"}, {"text": "r269:270", "type": "sha", "id": "270"}, {"text": "r263:264", "type": "sha", "id": "264"}, {"text": "r261:262", "type": "sha", "id": "262"}, {"text": "r251:252", "type": "sha", "id": "252"}, {"text": "r208:209", "type": "sha", "id": "209"}, {"text": "r202:203", "type": "sha", "id": "203"}, {"text": "r173:174", "type": "sha", "id": "174"}, {"text": "r172:173", "type": "sha", "id": "173"}, {"text": "r171:172", "type": "sha", "id": "172"}, {"text": "r145:146", "type": "sha", "id": "146"}, {"text": "r144:145", "type": "sha", "id": "145"}, {"text": "r140:141", "type": "sha", "id": "141"}, {"text": "r134:135", "type": "sha", "id": "135"}, {"text": "r107:108", "type": "sha", "id": "108"}, {"text": "r106:107", "type": "sha", "id": "107"}, {"text": "r100:101", "type": "sha", "id": "101"}, {"text": "r94:95", "type": "sha", "id": "95"}, {"text": "r85:86", "type": "sha", "id": "86"}, {"text": "r73:74", "type": "sha", "id": "74"}, {"text": "r72:73", "type": "sha", "id": "73"}, {"text": "r71:72", "type": "sha", "id": "72"}, {"text": "r69:70", "type": "sha", "id": "70"}, {"text": "r67:68", "type": "sha", "id": "68"}, {"text": "r63:64", "type": "sha", "id": "64"}, {"text": "r62:63", "type": "sha", "id": "63"}, {"text": "r61:62", "type": "sha", "id": "62"}, {"text": "r50:51", "type": "sha", "id": "51"}, {"text": "r49:50", "type": "sha", "id": "50"}, {"text": "r48:49", "type": "sha", "id": "49"}, {"text": "r47:48", "type": "sha", "id": "48"}, {"text": "r46:47", "type": "sha", "id": "47"}, {"text": "r45:46", "type": "sha", "id": "46"}, {"text": "r41:42", "type": "sha", "id": "42"}, {"text": "r39:40", "type": "sha", "id": "40"}, {"text": "r37:38", "type": "sha", "id": "38"}, {"text": "r25:26", "type": "sha", "id": "26"}, {"text": "r23:24", "type": "sha", "id": "24"}, {"text": "r8:9", "type": "sha", "id": "9"}, {"text": "r7:8", "type": "sha", "id": "8"}]}, {"text": "Branches", "children": []}, {"text": "Tags", "children": []}], "more": false} No newline at end of file
@@ -30,10 +30,13 b' def route_path(name, params=None, **kwar'
30
30
31 base_url = {
31 base_url = {
32 'home': '/',
32 'home': '/',
33 'admin_home': ADMIN_PREFIX,
33 'repos':
34 'repos':
34 ADMIN_PREFIX + '/repos',
35 ADMIN_PREFIX + '/repos',
35 'repo_groups':
36 'repo_groups':
36 ADMIN_PREFIX + '/repo_groups',
37 ADMIN_PREFIX + '/repo_groups',
38 'repo_groups_data':
39 ADMIN_PREFIX + '/repo_groups_data',
37 'user_groups':
40 'user_groups':
38 ADMIN_PREFIX + '/user_groups',
41 ADMIN_PREFIX + '/user_groups',
39 'user_groups_data':
42 'user_groups_data':
@@ -50,32 +53,27 b' fixture = Fixture()'
50
53
51 class TestAdminDelegatedUser(TestController):
54 class TestAdminDelegatedUser(TestController):
52
55
53 def test_regular_user_cannot_see_admin_interfaces(
56 def test_regular_user_cannot_see_admin_interfaces(self, user_util, xhr_header):
54 self, user_util, xhr_header):
55 user = user_util.create_user(password='qweqwe')
57 user = user_util.create_user(password='qweqwe')
58 user_util.inherit_default_user_permissions(user.username, False)
59
56 self.log_user(user.username, 'qweqwe')
60 self.log_user(user.username, 'qweqwe')
57
61
58 # check if in home view, such user doesn't see the "admin" menus
62 # user doesn't have any access to resources so main admin page should 404
59 response = self.app.get(route_path('home'))
63 self.app.get(route_path('admin_home'), status=404)
60
61 assert_response = response.assert_response()
62
63 assert_response.no_element_exists('li.local-admin-repos')
64 assert_response.no_element_exists('li.local-admin-repo-groups')
65 assert_response.no_element_exists('li.local-admin-user-groups')
66
64
67 response = self.app.get(route_path('repos'), status=200)
65 response = self.app.get(route_path('repos'), status=200)
68 response.mustcontain('data: []')
66 response.mustcontain('data: []')
69
67
70 response = self.app.get(route_path('repo_groups'), status=200)
68 response = self.app.get(route_path('repo_groups_data'),
71 response.mustcontain('data: []')
69 status=200, extra_environ=xhr_header)
70 assert response.json['data'] == []
72
71
73 response = self.app.get(route_path('user_groups_data'),
72 response = self.app.get(route_path('user_groups_data'),
74 status=200, extra_environ=xhr_header)
73 status=200, extra_environ=xhr_header)
75 assert response.json['data'] == []
74 assert response.json['data'] == []
76
75
77 def test_regular_user_can_see_admin_interfaces_if_owner(
76 def test_regular_user_can_see_admin_interfaces_if_owner(self, user_util, xhr_header):
78 self, user_util, xhr_header):
79 user = user_util.create_user(password='qweqwe')
77 user = user_util.create_user(password='qweqwe')
80 username = user.username
78 username = user.username
81
79
@@ -89,20 +87,21 b' class TestAdminDelegatedUser(TestControl'
89 user_group_name = user_group.users_group_name
87 user_group_name = user_group.users_group_name
90
88
91 self.log_user(username, 'qweqwe')
89 self.log_user(username, 'qweqwe')
92 # check if in home view, such user doesn't see the "admin" menus
90
93 response = self.app.get(route_path('home'))
91 response = self.app.get(route_path('admin_home'))
94
92
95 assert_response = response.assert_response()
93 assert_response = response.assert_response()
96
94
97 assert_response.one_element_exists('li.local-admin-repos')
95 assert_response.element_contains('td.delegated-admin-repos', '1')
98 assert_response.one_element_exists('li.local-admin-repo-groups')
96 assert_response.element_contains('td.delegated-admin-repo-groups', '1')
99 assert_response.one_element_exists('li.local-admin-user-groups')
97 assert_response.element_contains('td.delegated-admin-user-groups', '1')
100
98
101 # admin interfaces have visible elements
99 # admin interfaces have visible elements
102 response = self.app.get(route_path('repos'), status=200)
100 response = self.app.get(route_path('repos'), status=200)
103 response.mustcontain('"name_raw": "{}"'.format(repo_name))
101 response.mustcontain('"name_raw": "{}"'.format(repo_name))
104
102
105 response = self.app.get(route_path('repo_groups'), status=200)
103 response = self.app.get(route_path('repo_groups_data'),
104 extra_environ=xhr_header, status=200)
106 response.mustcontain('"name_raw": "{}"'.format(repo_group_name))
105 response.mustcontain('"name_raw": "{}"'.format(repo_group_name))
107
106
108 response = self.app.get(route_path('user_groups_data'),
107 response = self.app.get(route_path('user_groups_data'),
@@ -132,19 +131,20 b' class TestAdminDelegatedUser(TestControl'
132
131
133 self.log_user(username, 'qweqwe')
132 self.log_user(username, 'qweqwe')
134 # check if in home view, such user doesn't see the "admin" menus
133 # check if in home view, such user doesn't see the "admin" menus
135 response = self.app.get(route_path('home'))
134 response = self.app.get(route_path('admin_home'))
136
135
137 assert_response = response.assert_response()
136 assert_response = response.assert_response()
138
137
139 assert_response.one_element_exists('li.local-admin-repos')
138 assert_response.element_contains('td.delegated-admin-repos', '1')
140 assert_response.one_element_exists('li.local-admin-repo-groups')
139 assert_response.element_contains('td.delegated-admin-repo-groups', '1')
141 assert_response.one_element_exists('li.local-admin-user-groups')
140 assert_response.element_contains('td.delegated-admin-user-groups', '1')
142
141
143 # admin interfaces have visible elements
142 # admin interfaces have visible elements
144 response = self.app.get(route_path('repos'), status=200)
143 response = self.app.get(route_path('repos'), status=200)
145 response.mustcontain('"name_raw": "{}"'.format(repo_name))
144 response.mustcontain('"name_raw": "{}"'.format(repo_name))
146
145
147 response = self.app.get(route_path('repo_groups'), status=200)
146 response = self.app.get(route_path('repo_groups_data'),
147 extra_environ=xhr_header, status=200)
148 response.mustcontain('"name_raw": "{}"'.format(repo_group_name))
148 response.mustcontain('"name_raw": "{}"'.format(repo_group_name))
149
149
150 response = self.app.get(route_path('user_groups_data'),
150 response = self.app.get(route_path('user_groups_data'),
@@ -121,7 +121,8 b' def test_get_config(user_util, baseapp, '
121 expected_config.update({
121 expected_config.update({
122 'git_update_server_info': False,
122 'git_update_server_info': False,
123 'git_lfs_enabled': False,
123 'git_lfs_enabled': False,
124 'git_lfs_store_path': git_config['git_lfs_store_path']
124 'git_lfs_store_path': git_config['git_lfs_store_path'],
125 'git_lfs_http_scheme': 'http'
125 })
126 })
126
127
127 assert git_config == expected_config
128 assert git_config == expected_config
@@ -69,7 +69,7 b' class StubVCSController(simplevcs.Simple'
69 return self.stub_response_body
69 return self.stub_response_body
70 return fake_app
70 return fake_app
71
71
72 def _create_config(self, extras, repo_name):
72 def _create_config(self, extras, repo_name, scheme='http'):
73 return None
73 return None
74
74
75
75
@@ -22,6 +22,7 b' import pytest'
22
22
23 from rhodecode.lib.encrypt import (
23 from rhodecode.lib.encrypt import (
24 AESCipher, SignatureVerificationError, InvalidDecryptedValue)
24 AESCipher, SignatureVerificationError, InvalidDecryptedValue)
25 from rhodecode.lib.encrypt2 import (Encryptor, InvalidToken)
25
26
26
27
27 class TestEncryptModule(object):
28 class TestEncryptModule(object):
@@ -74,3 +75,59 b' class TestEncryptModule(object):'
74 assert isinstance(AESCipher(
75 assert isinstance(AESCipher(
75 'differentsecret', hmac=True, strict_verification=False
76 'differentsecret', hmac=True, strict_verification=False
76 ).decrypt(enc), InvalidDecryptedValue)
77 ).decrypt(enc), InvalidDecryptedValue)
78
79
80 class TestEncryptModule2(object):
81
82 @pytest.mark.parametrize(
83 "key, text",
84 [
85 ('a', 'short'),
86 ('a'*64, 'too long(trimmed to 32)'),
87 ('a'*32, 'just enough'),
88 ('ąćęćę', 'non asci'),
89 ('$asa$asa', 'special $ used'),
90 ]
91 )
92 def test_encryption(self, key, text):
93 enc = Encryptor(key).encrypt(text)
94 assert Encryptor(key).decrypt(enc) == text
95
96 def test_encryption_with_bad_key(self):
97 key = 'secretstring'
98 text = 'ihatemysql'
99 enc = Encryptor(key).encrypt(text)
100
101 assert Encryptor('differentsecret').decrypt(enc) == ''
102
103 def test_encryption_with_bad_key_raises(self):
104 key = 'secretstring'
105 text = 'ihatemysql'
106 enc = Encryptor(key).encrypt(text)
107
108 with pytest.raises(InvalidToken) as e:
109 Encryptor('differentsecret').decrypt(enc, safe=False)
110
111 assert 'InvalidToken' in str(e)
112
113 def test_encryption_with_bad_format_data(self):
114 key = 'secret'
115 text = 'ihatemysql'
116 enc = Encryptor(key).encrypt(text)
117 enc = '$xyz' + enc[3:]
118
119 with pytest.raises(ValueError) as e:
120 Encryptor(key).decrypt(enc, safe=False)
121
122 assert 'Encrypted Data has invalid format' in str(e)
123
124 def test_encryption_with_bad_data(self):
125 key = 'secret'
126 text = 'ihatemysql'
127 enc = Encryptor(key).encrypt(text)
128 enc = enc[:-5]
129
130 with pytest.raises(InvalidToken) as e:
131 Encryptor(key).decrypt(enc, safe=False)
132
133 assert 'InvalidToken' in str(e)
@@ -40,27 +40,52 b' def test_urlify_text(url, expected_url):'
40
40
41
41
42 @pytest.mark.parametrize('repo_name, commit_id, path, expected_result', [
42 @pytest.mark.parametrize('repo_name, commit_id, path, expected_result', [
43 # Simple case 1
44 ('repo', 'commit', 'a/b',
45 '<a href="/repo/files/commit/"><i class="icon-home"></i></a>'
46 ' / '
47 '<a href="/repo/files/commit/a">a</a>'
48 ' / '
49 'b'),
50
51 # Simple case
43 ('rX<X', 'cX<X', 'pX<X/aX<X/bX<X',
52 ('rX<X', 'cX<X', 'pX<X/aX<X/bX<X',
44 '<a class="pjax-link" href="/rX%3CX/files/cX%3CX/">rX&lt;X</a>/'
53 '<a href="/rX%3CX/files/cX%3CX/"><i class="icon-home"></i></a>'
45 '<a class="pjax-link" href="/rX%3CX/files/cX%3CX/pX%3CX">pX&lt;X</a>/'
54 ' / '
46 '<a class="pjax-link" href="/rX%3CX/files/cX%3CX/pX%3CX/aX%3CX">aX&lt;X'
55 '<a href="/rX%3CX/files/cX%3CX/pX%3CX">pX&lt;X</a>'
47 '</a>/bX&lt;X'),
56 ' / '
57 '<a href="/rX%3CX/files/cX%3CX/pX%3CX/aX%3CX">aX&lt;X</a>'
58 ' / '
59 'bX&lt;X'),
60
48 # Path with only one segment
61 # Path with only one segment
49 ('rX<X', 'cX<X', 'pX<X',
62 ('rX<X', 'cX<X', 'pX<X',
50 '<a class="pjax-link" href="/rX%3CX/files/cX%3CX/">rX&lt;X</a>/pX&lt;X'),
63 '<a href="/rX%3CX/files/cX%3CX/"><i class="icon-home"></i></a>'
64 ' / '
65 'pX&lt;X'),
66
51 # Empty path
67 # Empty path
52 ('rX<X', 'cX<X', '', 'rX&lt;X'),
68 ('rX<X', 'cX<X', '',
69 '<i class="icon-home"></i>'),
70
71 # simple quote
53 ('rX"X', 'cX"X', 'pX"X/aX"X/bX"X',
72 ('rX"X', 'cX"X', 'pX"X/aX"X/bX"X',
54 '<a class="pjax-link" href="/rX%22X/files/cX%22X/">rX&#34;X</a>/'
73 '<a href="/rX%22X/files/cX%22X/"><i class="icon-home"></i></a>'
55 '<a class="pjax-link" href="/rX%22X/files/cX%22X/pX%22X">pX&#34;X</a>/'
74 ' / '
56 '<a class="pjax-link" href="/rX%22X/files/cX%22X/pX%22X/aX%22X">aX&#34;X'
75 '<a href="/rX%22X/files/cX%22X/pX%22X">pX&#34;X</a>'
57 '</a>/bX&#34;X'),
76 ' / '
58 ], ids=['simple', 'one_segment', 'empty_path', 'simple_quote'])
77 '<a href="/rX%22X/files/cX%22X/pX%22X/aX%22X">aX&#34;X</a>'
78 ' / '
79 'bX&#34;X'),
80
81 ], ids=['simple1', 'simple2', 'one_segment', 'empty_path', 'simple_quote'])
59 def test_files_breadcrumbs_xss(
82 def test_files_breadcrumbs_xss(
60 repo_name, commit_id, path, app, expected_result):
83 repo_name, commit_id, path, app, expected_result):
61 result = helpers.files_breadcrumbs(repo_name, commit_id, path)
84 result = helpers.files_breadcrumbs(repo_name, commit_id, path)
62 # Expect it to encode all path fragments properly. This is important
85 # Expect it to encode all path fragments properly. This is important
63 # because it returns an instance of `literal`.
86 # because it returns an instance of `literal`.
87 if path != '':
88 expected_result = expected_result + helpers.files_icon.format(helpers.escape(path))
64 assert result == expected_result
89 assert result == expected_result
65
90
66
91
@@ -501,8 +501,8 b' class TestCreateOrUpdateUi(object):'
501
501
502 def test_update(self, repo_stub, settings_util):
502 def test_update(self, repo_stub, settings_util):
503 model = VcsSettingsModel(repo=repo_stub.repo_name)
503 model = VcsSettingsModel(repo=repo_stub.repo_name)
504
504 # care about only 3 first settings
505 largefiles, phases, evolve = model.HG_SETTINGS
505 largefiles, phases, evolve = model.HG_SETTINGS[:3]
506
506
507 section = 'test-section'
507 section = 'test-section'
508 key = 'test-key'
508 key = 'test-key'
@@ -531,10 +531,11 b' class TestCreateOrUpdateRepoHgSettings(o'
531 with mock.patch.object(model, '_create_or_update_ui') as create_mock:
531 with mock.patch.object(model, '_create_or_update_ui') as create_mock:
532 model.create_or_update_repo_hg_settings(self.FORM_DATA)
532 model.create_or_update_repo_hg_settings(self.FORM_DATA)
533 expected_calls = [
533 expected_calls = [
534 mock.call(model.repo_settings, 'extensions', 'largefiles',
534 mock.call(model.repo_settings, 'extensions', 'largefiles', active=False, value=''),
535 active=False, value=''),
535 mock.call(model.repo_settings, 'extensions', 'evolve', active=False, value=''),
536 mock.call(model.repo_settings, 'extensions', 'evolve',
536 mock.call(model.repo_settings, 'experimental', 'evolution', active=False, value=''),
537 active=False, value=''),
537 mock.call(model.repo_settings, 'experimental', 'evolution.exchange', active=False, value='no'),
538 mock.call(model.repo_settings, 'extensions', 'topic', active=False, value=''),
538 mock.call(model.repo_settings, 'phases', 'publish', value='False'),
539 mock.call(model.repo_settings, 'phases', 'publish', value='False'),
539 ]
540 ]
540 assert expected_calls == create_mock.call_args_list
541 assert expected_calls == create_mock.call_args_list
@@ -589,17 +590,16 b' class TestCreateOrUpdateGlobalHgSettings'
589 with mock.patch.object(model, '_create_or_update_ui') as create_mock:
590 with mock.patch.object(model, '_create_or_update_ui') as create_mock:
590 model.create_or_update_global_hg_settings(self.FORM_DATA)
591 model.create_or_update_global_hg_settings(self.FORM_DATA)
591 expected_calls = [
592 expected_calls = [
592 mock.call(model.global_settings, 'extensions', 'largefiles',
593 mock.call(model.global_settings, 'extensions', 'largefiles', active=False, value=''),
593 active=False, value=''),
594 mock.call(model.global_settings, 'largefiles', 'usercache', value='/example/largefiles-store'),
594 mock.call(model.global_settings, 'largefiles', 'usercache',
595 mock.call(model.global_settings, 'phases', 'publish', value='False'),
595 value='/example/largefiles-store'),
596 mock.call(model.global_settings, 'extensions', 'hgsubversion', active=False),
596 mock.call(model.global_settings, 'phases', 'publish',
597 mock.call(model.global_settings, 'extensions', 'evolve', active=False, value=''),
597 value='False'),
598 mock.call(model.global_settings, 'experimental', 'evolution', active=False, value=''),
598 mock.call(model.global_settings, 'extensions', 'hgsubversion',
599 mock.call(model.global_settings, 'experimental', 'evolution.exchange', active=False, value='no'),
599 active=False),
600 mock.call(model.global_settings, 'extensions', 'topic', active=False, value=''),
600 mock.call(model.global_settings, 'extensions', 'evolve',
601 active=False, value='')
602 ]
601 ]
602
603 assert expected_calls == create_mock.call_args_list
603 assert expected_calls == create_mock.call_args_list
604
604
605 @pytest.mark.parametrize('field_to_remove', FORM_DATA.keys())
605 @pytest.mark.parametrize('field_to_remove', FORM_DATA.keys())
@@ -625,10 +625,8 b' class TestCreateOrUpdateGlobalGitSetting'
625 with mock.patch.object(model, '_create_or_update_ui') as create_mock:
625 with mock.patch.object(model, '_create_or_update_ui') as create_mock:
626 model.create_or_update_global_git_settings(self.FORM_DATA)
626 model.create_or_update_global_git_settings(self.FORM_DATA)
627 expected_calls = [
627 expected_calls = [
628 mock.call(model.global_settings, 'vcs_git_lfs', 'enabled',
628 mock.call(model.global_settings, 'vcs_git_lfs', 'enabled', active=False, value=False),
629 active=False, value=False),
629 mock.call(model.global_settings, 'vcs_git_lfs', 'store_location', value='/example/lfs-store'),
630 mock.call(model.global_settings, 'vcs_git_lfs', 'store_location',
631 value='/example/lfs-store'),
632 ]
630 ]
633 assert expected_calls == create_mock.call_args_list
631 assert expected_calls == create_mock.call_args_list
634
632
@@ -512,7 +512,7 b' def test_outdated_comments('
512 (MergeFailureReason.HG_SOURCE_HAS_MORE_BRANCHES,
512 (MergeFailureReason.HG_SOURCE_HAS_MORE_BRANCHES,
513 'This pull request cannot be merged because the source contains more branches than the target.'),
513 'This pull request cannot be merged because the source contains more branches than the target.'),
514 (MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS,
514 (MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS,
515 'This pull request cannot be merged because the target has multiple heads: `a,b,c`.'),
515 'This pull request cannot be merged because the target `ref_name` has multiple heads: `a,b,c`.'),
516 (MergeFailureReason.TARGET_IS_LOCKED,
516 (MergeFailureReason.TARGET_IS_LOCKED,
517 'This pull request cannot be merged because the target repository is locked by user:123.'),
517 'This pull request cannot be merged because the target repository is locked by user:123.'),
518 (MergeFailureReason.MISSING_TARGET_REF,
518 (MergeFailureReason.MISSING_TARGET_REF,
@@ -129,20 +129,19 b' def test_strip_with_single_heads(backend'
129 assert commit_ids['b'] not in rest_commit_ids
129 assert commit_ids['b'] not in rest_commit_ids
130
130
131
131
132 def test_get_nodes_returns_unicode_flat(backend_random):
132 def test_get_nodes_returns_unicode_flat(backend):
133 repo = backend_random.repo
133 repo = backend.repo
134 directories, files = scm.ScmModel().get_nodes(
134 commit_id = repo.get_commit(commit_idx=0).raw_id
135 repo.repo_name, repo.get_commit(commit_idx=0).raw_id,
135 directories, files = scm.ScmModel().get_nodes(repo.repo_name, commit_id, flat=True)
136 flat=True)
137 assert_contains_only_unicode(directories)
136 assert_contains_only_unicode(directories)
138 assert_contains_only_unicode(files)
137 assert_contains_only_unicode(files)
139
138
140
139
141 def test_get_nodes_returns_unicode_non_flat(backend_random):
140 def test_get_nodes_returns_unicode_non_flat(backend):
142 repo = backend_random.repo
141 repo = backend.repo
143 directories, files = scm.ScmModel().get_nodes(
142 commit_id = repo.get_commit(commit_idx=0).raw_id
144 repo.repo_name, repo.get_commit(commit_idx=0).raw_id,
143
145 flat=False)
144 directories, files = scm.ScmModel().get_nodes(repo.repo_name, commit_id, flat=False)
146 # johbo: Checking only the names for now, since that is the critical
145 # johbo: Checking only the names for now, since that is the critical
147 # part.
146 # part.
148 assert_contains_only_unicode([d['name'] for d in directories])
147 assert_contains_only_unicode([d['name'] for d in directories])
@@ -631,7 +631,9 b' class Backend(object):'
631 commits = commits or [
631 commits = commits or [
632 {'message': 'Commit %s of %s' % (x, self.repo_name)}
632 {'message': 'Commit %s of %s' % (x, self.repo_name)}
633 for x in range(number_of_commits)]
633 for x in range(number_of_commits)]
634 self._add_commits_to_repo(repo.scm_instance(), commits)
634 vcs_repo = repo.scm_instance()
635 vcs_repo.count()
636 self._add_commits_to_repo(vcs_repo, commits)
635 if heads:
637 if heads:
636 self.pull_heads(repo, heads)
638 self.pull_heads(repo, heads)
637
639
@@ -1224,7 +1226,7 b' class UserUtility(object):'
1224 return user_group
1226 return user_group
1225
1227
1226 def grant_user_permission(self, user_name, permission_name):
1228 def grant_user_permission(self, user_name, permission_name):
1227 self._inherit_default_user_permissions(user_name, False)
1229 self.inherit_default_user_permissions(user_name, False)
1228 self.user_permissions.append((user_name, permission_name))
1230 self.user_permissions.append((user_name, permission_name))
1229
1231
1230 def grant_user_permission_to_repo_group(
1232 def grant_user_permission_to_repo_group(
@@ -1276,10 +1278,10 b' class UserUtility(object):'
1276 return permission
1278 return permission
1277
1279
1278 def revoke_user_permission(self, user_name, permission_name):
1280 def revoke_user_permission(self, user_name, permission_name):
1279 self._inherit_default_user_permissions(user_name, True)
1281 self.inherit_default_user_permissions(user_name, True)
1280 UserModel().revoke_perm(user_name, permission_name)
1282 UserModel().revoke_perm(user_name, permission_name)
1281
1283
1282 def _inherit_default_user_permissions(self, user_name, value):
1284 def inherit_default_user_permissions(self, user_name, value):
1283 user = UserModel().get_by_username(user_name)
1285 user = UserModel().get_by_username(user_name)
1284 user.inherit_default_permissions = value
1286 user.inherit_default_permissions = value
1285 Session().add(user)
1287 Session().add(user)
@@ -1884,3 +1886,17 b' def repo_groups(request):'
1884 fixture.destroy_repo_group(parent_group)
1886 fixture.destroy_repo_group(parent_group)
1885
1887
1886 return zombie_group, parent_group, child_group
1888 return zombie_group, parent_group, child_group
1889
1890
1891 @pytest.fixture(scope="session")
1892 def tmp_path_factory(request):
1893 """Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session.
1894 """
1895
1896 class TempPathFactory:
1897
1898 def mktemp(self, basename):
1899 import tempfile
1900 return tempfile.mktemp(basename)
1901
1902 return TempPathFactory()
@@ -48,9 +48,9 b' log = logging.getLogger(__name__)'
48
48
49
49
50 class CustomTestResponse(TestResponse):
50 class CustomTestResponse(TestResponse):
51
51 def _save_output(self, out):
52 def _save_output(self, out):
52 f = tempfile.NamedTemporaryFile(
53 f = tempfile.NamedTemporaryFile(delete=False, prefix='rc-test-', suffix='.html')
53 delete=False, prefix='rc-test-', suffix='.html')
54 f.write(out)
54 f.write(out)
55 return f.name
55 return f.name
56
56
@@ -63,6 +63,7 b' class CustomTestResponse(TestResponse):'
63
63
64 assert string in res
64 assert string in res
65 """
65 """
66 print_body = kw.pop('print_body', False)
66 if 'no' in kw:
67 if 'no' in kw:
67 no = kw['no']
68 no = kw['no']
68 del kw['no']
69 del kw['no']
@@ -79,18 +80,20 b' class CustomTestResponse(TestResponse):'
79 for s in strings:
80 for s in strings:
80 if not s in self:
81 if not s in self:
81 print_stderr("Actual response (no %r):" % s)
82 print_stderr("Actual response (no %r):" % s)
83 print_stderr("body output saved as `%s`" % f)
84 if print_body:
82 print_stderr(str(self))
85 print_stderr(str(self))
83 raise IndexError(
86 raise IndexError(
84 "Body does not contain string %r, output saved as %s" % (
87 "Body does not contain string %r, body output saved as %s" % (s, f))
85 s, f))
86
88
87 for no_s in no:
89 for no_s in no:
88 if no_s in self:
90 if no_s in self:
89 print_stderr("Actual response (has %r)" % no_s)
91 print_stderr("Actual response (has %r)" % no_s)
92 print_stderr("body output saved as `%s`" % f)
93 if print_body:
90 print_stderr(str(self))
94 print_stderr(str(self))
91 raise IndexError(
95 raise IndexError(
92 "Body contains bad string %r, output saved as %s" % (
96 "Body contains bad string %r, body output saved as %s" % (no_s, f))
93 no_s, f))
94
97
95 def assert_response(self):
98 def assert_response(self):
96 return AssertResponse(self)
99 return AssertResponse(self)
@@ -99,8 +102,7 b' class CustomTestResponse(TestResponse):'
99 """
102 """
100 This returns the session from a response object.
103 This returns the session from a response object.
101 """
104 """
102
105 from rhodecode.lib.rc_beaker import session_factory_from_settings
103 from pyramid_beaker import session_factory_from_settings
104 session = session_factory_from_settings(self.test_app._pyramid_settings)
106 session = session_factory_from_settings(self.test_app._pyramid_settings)
105 return session(self.request)
107 return session(self.request)
106
108
@@ -390,6 +392,7 b' def is_url_reachable(url):'
390 try:
392 try:
391 urllib2.urlopen(url)
393 urllib2.urlopen(url)
392 except urllib2.URLError:
394 except urllib2.URLError:
395 log.exception('URL Reach error')
393 return False
396 return False
394 return True
397 return True
395
398
@@ -148,7 +148,6 b' def _add_commits_to_repo(repo, commits):'
148 author=unicode(commit['author']),
148 author=unicode(commit['author']),
149 date=commit['date'],
149 date=commit['date'],
150 branch=commit.get('branch'))
150 branch=commit.get('branch'))
151
152 return tip
151 return tip
153
152
154
153
@@ -97,7 +97,7 b' class TestArchives(BackendTestMixin):'
97 metafile = out.read('.archival.txt')
97 metafile = out.read('.archival.txt')
98
98
99 raw_id = self.tip.raw_id
99 raw_id = self.tip.raw_id
100 assert 'rev:%s' % raw_id in metafile
100 assert 'commit_id:%s' % raw_id in metafile
101
101
102 for x in range(5):
102 for x in range(5):
103 node_path = '%d/file_%d.txt' % (x, x)
103 node_path = '%d/file_%d.txt' % (x, x)
@@ -35,7 +35,7 b' from rhodecode.tests import get_new_dir'
35 from rhodecode.tests.vcs.conftest import BackendTestMixin
35 from rhodecode.tests.vcs.conftest import BackendTestMixin
36
36
37
37
38 class TestBaseChangeset:
38 class TestBaseChangeset(object):
39
39
40 def test_is_deprecated(self):
40 def test_is_deprecated(self):
41 from rhodecode.lib.vcs.backends.base import BaseChangeset
41 from rhodecode.lib.vcs.backends.base import BaseChangeset
@@ -159,8 +159,7 b' class TestCommitsInNonEmptyRepo(BackendT'
159 parents=[initial],
159 parents=[initial],
160 branch=DEFAULT_BRANCH,)
160 branch=DEFAULT_BRANCH,)
161
161
162 default_branch_commits = self.repo.get_commits(
162 default_branch_commits = self.repo.get_commits(branch_name=DEFAULT_BRANCH)
163 branch_name=DEFAULT_BRANCH)
164 assert docs_branch_commit1 not in list(default_branch_commits)
163 assert docs_branch_commit1 not in list(default_branch_commits)
165 assert docs_branch_commit2 not in list(default_branch_commits)
164 assert docs_branch_commit2 not in list(default_branch_commits)
166
165
@@ -177,6 +176,10 b' class TestCommitsInNonEmptyRepo(BackendT'
177 commit_indexes = [c.idx for c in commits]
176 commit_indexes = [c.idx for c in commits]
178 assert commit_indexes == [1, 2, 3, 7, 12, 15]
177 assert commit_indexes == [1, 2, 3, 7, 12, 15]
179
178
179 def test_get_commit_by_index(self):
180 for idx in [1, 2, 3, 4]:
181 assert idx == self.repo.get_commit(commit_idx=idx).idx
182
180 def test_get_commit_by_branch(self):
183 def test_get_commit_by_branch(self):
181 for branch, commit_id in self.repo.branches.iteritems():
184 for branch, commit_id in self.repo.branches.iteritems():
182 assert commit_id == self.repo.get_commit(branch).raw_id
185 assert commit_id == self.repo.get_commit(branch).raw_id
@@ -41,60 +41,41 b' from rhodecode.tests.vcs.conftest import'
41 pytestmark = pytest.mark.backends("git")
41 pytestmark = pytest.mark.backends("git")
42
42
43
43
44 def repo_path_generator():
44 class TestGitRepository(object):
45 """
46 Return a different path to be used for cloning repos.
47 """
48 i = 0
49 while True:
50 i += 1
51 yield '%s-%d' % (TEST_GIT_REPO_CLONE, i)
52
53
54 REPO_PATH_GENERATOR = repo_path_generator()
55
56
57 class TestGitRepository:
58
59 # pylint: disable=protected-access
60
61 def __check_for_existing_repo(self):
62 if os.path.exists(TEST_GIT_REPO_CLONE):
63 self.fail('Cannot test git clone repo as location %s already '
64 'exists. You should manually remove it first.'
65 % TEST_GIT_REPO_CLONE)
66
45
67 @pytest.fixture(autouse=True)
46 @pytest.fixture(autouse=True)
68 def prepare(self, request, baseapp):
47 def prepare(self, request, baseapp):
69 self.repo = GitRepository(TEST_GIT_REPO, bare=True)
48 self.repo = GitRepository(TEST_GIT_REPO, bare=True)
70
49
71 def get_clone_repo(self):
50 def get_clone_repo(self, tmp_path_factory):
72 """
51 """
73 Return a non bare clone of the base repo.
52 Return a non bare clone of the base repo.
74 """
53 """
75 clone_path = next(REPO_PATH_GENERATOR)
54 clone_path = tmp_path_factory.mktemp('clone-url')
76 repo_clone = GitRepository(
55 repo_clone = GitRepository(
77 clone_path, create=True, src_url=self.repo.path, bare=False)
56 clone_path, create=True, src_url=self.repo.path, bare=False)
78
57
79 return repo_clone
58 return repo_clone
80
59
81 def get_empty_repo(self, bare=False):
60 def get_empty_repo(self, tmp_path_factory, bare=False):
82 """
61 """
83 Return a non bare empty repo.
62 Return a non bare empty repo.
84 """
63 """
85 return GitRepository(next(REPO_PATH_GENERATOR), create=True, bare=bare)
64 clone_path = tmp_path_factory.mktemp('empty-repo')
65 return GitRepository(clone_path, create=True, bare=bare)
86
66
87 def test_wrong_repo_path(self):
67 def test_wrong_repo_path(self):
88 wrong_repo_path = '/tmp/errorrepo_git'
68 wrong_repo_path = '/tmp/errorrepo_git'
89 with pytest.raises(RepositoryError):
69 with pytest.raises(RepositoryError):
90 GitRepository(wrong_repo_path)
70 GitRepository(wrong_repo_path)
91
71
92 def test_repo_clone(self):
72 def test_repo_clone(self, tmp_path_factory):
93 self.__check_for_existing_repo()
94 repo = GitRepository(TEST_GIT_REPO)
73 repo = GitRepository(TEST_GIT_REPO)
74 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE
95 repo_clone = GitRepository(
75 repo_clone = GitRepository(
96 TEST_GIT_REPO_CLONE,
76 clone_path,
97 src_url=TEST_GIT_REPO, create=True, do_workspace_checkout=True)
77 src_url=TEST_GIT_REPO, create=True, do_workspace_checkout=True)
78
98 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
79 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
99 # Checking hashes of commits should be enough
80 # Checking hashes of commits should be enough
100 for commit in repo.get_commits():
81 for commit in repo.get_commits():
@@ -106,9 +87,10 b' class TestGitRepository:'
106 GitRepository(
87 GitRepository(
107 TEST_GIT_REPO_CLONE + '_wo_create', src_url=TEST_GIT_REPO)
88 TEST_GIT_REPO_CLONE + '_wo_create', src_url=TEST_GIT_REPO)
108
89
109 def test_repo_clone_with_update(self):
90 def test_repo_clone_with_update(self, tmp_path_factory):
110 repo = GitRepository(TEST_GIT_REPO)
91 repo = GitRepository(TEST_GIT_REPO)
111 clone_path = TEST_GIT_REPO_CLONE + '_with_update'
92 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE + '_update'
93
112 repo_clone = GitRepository(
94 repo_clone = GitRepository(
113 clone_path,
95 clone_path,
114 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=True)
96 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=True)
@@ -118,9 +100,9 b' class TestGitRepository:'
118 fpath = os.path.join(clone_path, 'MANIFEST.in')
100 fpath = os.path.join(clone_path, 'MANIFEST.in')
119 assert os.path.isfile(fpath)
101 assert os.path.isfile(fpath)
120
102
121 def test_repo_clone_without_update(self):
103 def test_repo_clone_without_update(self, tmp_path_factory):
122 repo = GitRepository(TEST_GIT_REPO)
104 repo = GitRepository(TEST_GIT_REPO)
123 clone_path = TEST_GIT_REPO_CLONE + '_without_update'
105 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE + '_without_update'
124 repo_clone = GitRepository(
106 repo_clone = GitRepository(
125 clone_path,
107 clone_path,
126 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=False)
108 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=False)
@@ -131,9 +113,9 b' class TestGitRepository:'
131 assert not repo_clone.bare
113 assert not repo_clone.bare
132 assert not os.path.isfile(fpath)
114 assert not os.path.isfile(fpath)
133
115
134 def test_repo_clone_into_bare_repo(self):
116 def test_repo_clone_into_bare_repo(self, tmp_path_factory):
135 repo = GitRepository(TEST_GIT_REPO)
117 repo = GitRepository(TEST_GIT_REPO)
136 clone_path = TEST_GIT_REPO_CLONE + '_bare.git'
118 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE + '_bare.git'
137 repo_clone = GitRepository(
119 repo_clone = GitRepository(
138 clone_path, create=True, src_url=repo.path, bare=True)
120 clone_path, create=True, src_url=repo.path, bare=True)
139 assert repo_clone.bare
121 assert repo_clone.bare
@@ -275,8 +257,8 b' TODO: To be written...'
275 def test_head(self):
257 def test_head(self):
276 assert self.repo.head == self.repo.get_commit().raw_id
258 assert self.repo.head == self.repo.get_commit().raw_id
277
259
278 def test_checkout_with_create(self):
260 def test_checkout_with_create(self, tmp_path_factory):
279 repo_clone = self.get_clone_repo()
261 repo_clone = self.get_clone_repo(tmp_path_factory)
280
262
281 new_branch = 'new_branch'
263 new_branch = 'new_branch'
282 assert repo_clone._current_branch() == 'master'
264 assert repo_clone._current_branch() == 'master'
@@ -288,22 +270,22 b' TODO: To be written...'
288 assert set(repo_clone.branches) == {'master', new_branch}
270 assert set(repo_clone.branches) == {'master', new_branch}
289 assert repo_clone._current_branch() == new_branch
271 assert repo_clone._current_branch() == new_branch
290
272
291 def test_checkout(self):
273 def test_checkout(self, tmp_path_factory):
292 repo_clone = self.get_clone_repo()
274 repo_clone = self.get_clone_repo(tmp_path_factory)
293
275
294 repo_clone._checkout('new_branch', create=True)
276 repo_clone._checkout('new_branch', create=True)
295 repo_clone._checkout('master')
277 repo_clone._checkout('master')
296
278
297 assert repo_clone._current_branch() == 'master'
279 assert repo_clone._current_branch() == 'master'
298
280
299 def test_checkout_same_branch(self):
281 def test_checkout_same_branch(self, tmp_path_factory):
300 repo_clone = self.get_clone_repo()
282 repo_clone = self.get_clone_repo(tmp_path_factory)
301
283
302 repo_clone._checkout('master')
284 repo_clone._checkout('master')
303 assert repo_clone._current_branch() == 'master'
285 assert repo_clone._current_branch() == 'master'
304
286
305 def test_checkout_branch_already_exists(self):
287 def test_checkout_branch_already_exists(self, tmp_path_factory):
306 repo_clone = self.get_clone_repo()
288 repo_clone = self.get_clone_repo(tmp_path_factory)
307
289
308 with pytest.raises(RepositoryError):
290 with pytest.raises(RepositoryError):
309 repo_clone._checkout('master', create=True)
291 repo_clone._checkout('master', create=True)
@@ -316,32 +298,32 b' TODO: To be written...'
316 with pytest.raises(RepositoryError):
298 with pytest.raises(RepositoryError):
317 self.repo._current_branch()
299 self.repo._current_branch()
318
300
319 def test_current_branch_empty_repo(self):
301 def test_current_branch_empty_repo(self, tmp_path_factory):
320 repo = self.get_empty_repo()
302 repo = self.get_empty_repo(tmp_path_factory)
321 assert repo._current_branch() is None
303 assert repo._current_branch() is None
322
304
323 def test_local_clone(self):
305 def test_local_clone(self, tmp_path_factory):
324 clone_path = next(REPO_PATH_GENERATOR)
306 clone_path = tmp_path_factory.mktemp('test-local-clone')
325 self.repo._local_clone(clone_path, 'master')
307 self.repo._local_clone(clone_path, 'master')
326 repo_clone = GitRepository(clone_path)
308 repo_clone = GitRepository(clone_path)
327
309
328 assert self.repo.commit_ids == repo_clone.commit_ids
310 assert self.repo.commit_ids == repo_clone.commit_ids
329
311
330 def test_local_clone_with_specific_branch(self):
312 def test_local_clone_with_specific_branch(self, tmp_path_factory):
331 source_repo = self.get_clone_repo()
313 source_repo = self.get_clone_repo(tmp_path_factory)
332
314
333 # Create a new branch in source repo
315 # Create a new branch in source repo
334 new_branch_commit = source_repo.commit_ids[-3]
316 new_branch_commit = source_repo.commit_ids[-3]
335 source_repo._checkout(new_branch_commit)
317 source_repo._checkout(new_branch_commit)
336 source_repo._checkout('new_branch', create=True)
318 source_repo._checkout('new_branch', create=True)
337
319
338 clone_path = next(REPO_PATH_GENERATOR)
320 clone_path = tmp_path_factory.mktemp('git-clone-path-1')
339 source_repo._local_clone(clone_path, 'new_branch')
321 source_repo._local_clone(clone_path, 'new_branch')
340 repo_clone = GitRepository(clone_path)
322 repo_clone = GitRepository(clone_path)
341
323
342 assert source_repo.commit_ids[:-3 + 1] == repo_clone.commit_ids
324 assert source_repo.commit_ids[:-3 + 1] == repo_clone.commit_ids
343
325
344 clone_path = next(REPO_PATH_GENERATOR)
326 clone_path = tmp_path_factory.mktemp('git-clone-path-2')
345 source_repo._local_clone(clone_path, 'master')
327 source_repo._local_clone(clone_path, 'master')
346 repo_clone = GitRepository(clone_path)
328 repo_clone = GitRepository(clone_path)
347
329
@@ -351,9 +333,9 b' TODO: To be written...'
351 with pytest.raises(RepositoryError):
333 with pytest.raises(RepositoryError):
352 self.repo._local_clone(self.repo.path, 'master')
334 self.repo._local_clone(self.repo.path, 'master')
353
335
354 def test_local_fetch(self):
336 def test_local_fetch(self, tmp_path_factory):
355 target_repo = self.get_empty_repo()
337 target_repo = self.get_empty_repo(tmp_path_factory)
356 source_repo = self.get_clone_repo()
338 source_repo = self.get_clone_repo(tmp_path_factory)
357
339
358 # Create a new branch in source repo
340 # Create a new branch in source repo
359 master_commit = source_repo.commit_ids[-1]
341 master_commit = source_repo.commit_ids[-1]
@@ -367,8 +349,8 b' TODO: To be written...'
367 target_repo._local_fetch(source_repo.path, 'master')
349 target_repo._local_fetch(source_repo.path, 'master')
368 assert target_repo._last_fetch_heads() == [master_commit]
350 assert target_repo._last_fetch_heads() == [master_commit]
369
351
370 def test_local_fetch_from_bare_repo(self):
352 def test_local_fetch_from_bare_repo(self, tmp_path_factory):
371 target_repo = self.get_empty_repo()
353 target_repo = self.get_empty_repo(tmp_path_factory)
372 target_repo._local_fetch(self.repo.path, 'master')
354 target_repo._local_fetch(self.repo.path, 'master')
373
355
374 master_commit = self.repo.commit_ids[-1]
356 master_commit = self.repo.commit_ids[-1]
@@ -378,15 +360,15 b' TODO: To be written...'
378 with pytest.raises(ValueError):
360 with pytest.raises(ValueError):
379 self.repo._local_fetch(self.repo.path, 'master')
361 self.repo._local_fetch(self.repo.path, 'master')
380
362
381 def test_local_fetch_branch_does_not_exist(self):
363 def test_local_fetch_branch_does_not_exist(self, tmp_path_factory):
382 target_repo = self.get_empty_repo()
364 target_repo = self.get_empty_repo(tmp_path_factory)
383
365
384 with pytest.raises(RepositoryError):
366 with pytest.raises(RepositoryError):
385 target_repo._local_fetch(self.repo.path, 'new_branch')
367 target_repo._local_fetch(self.repo.path, 'new_branch')
386
368
387 def test_local_pull(self):
369 def test_local_pull(self, tmp_path_factory):
388 target_repo = self.get_empty_repo()
370 target_repo = self.get_empty_repo(tmp_path_factory)
389 source_repo = self.get_clone_repo()
371 source_repo = self.get_clone_repo(tmp_path_factory)
390
372
391 # Create a new branch in source repo
373 # Create a new branch in source repo
392 master_commit = source_repo.commit_ids[-1]
374 master_commit = source_repo.commit_ids[-1]
@@ -406,9 +388,9 b' TODO: To be written...'
406 with pytest.raises(RepositoryError):
388 with pytest.raises(RepositoryError):
407 self.repo._local_pull(self.repo.path, 'master')
389 self.repo._local_pull(self.repo.path, 'master')
408
390
409 def test_local_merge(self):
391 def test_local_merge(self, tmp_path_factory):
410 target_repo = self.get_empty_repo()
392 target_repo = self.get_empty_repo(tmp_path_factory)
411 source_repo = self.get_clone_repo()
393 source_repo = self.get_clone_repo(tmp_path_factory)
412
394
413 # Create a new branch in source repo
395 # Create a new branch in source repo
414 master_commit = source_repo.commit_ids[-1]
396 master_commit = source_repo.commit_ids[-1]
@@ -449,8 +431,8 b' TODO: To be written...'
449 assert not os.path.exists(
431 assert not os.path.exists(
450 os.path.join(target_repo.path, '.git', 'MERGE_HEAD'))
432 os.path.join(target_repo.path, '.git', 'MERGE_HEAD'))
451
433
452 def test_local_merge_into_empty_repo(self):
434 def test_local_merge_into_empty_repo(self, tmp_path_factory):
453 target_repo = self.get_empty_repo()
435 target_repo = self.get_empty_repo(tmp_path_factory)
454
436
455 # This is required as one cannot do a -ff-only merge in an empty repo.
437 # This is required as one cannot do a -ff-only merge in an empty repo.
456 target_repo._local_fetch(self.repo.path, 'master')
438 target_repo._local_fetch(self.repo.path, 'master')
@@ -464,8 +446,8 b' TODO: To be written...'
464 self.repo._local_merge(
446 self.repo._local_merge(
465 'merge_message', 'user name', 'user@name.com', None)
447 'merge_message', 'user name', 'user@name.com', None)
466
448
467 def test_local_push_non_bare(self):
449 def test_local_push_non_bare(self, tmp_path_factory):
468 target_repo = self.get_empty_repo()
450 target_repo = self.get_empty_repo(tmp_path_factory)
469
451
470 pushed_branch = 'pushed_branch'
452 pushed_branch = 'pushed_branch'
471 self.repo._local_push('master', target_repo.path, pushed_branch)
453 self.repo._local_push('master', target_repo.path, pushed_branch)
@@ -479,8 +461,8 b' TODO: To be written...'
479 assert (target_repo.branches[pushed_branch] ==
461 assert (target_repo.branches[pushed_branch] ==
480 self.repo.branches['master'])
462 self.repo.branches['master'])
481
463
482 def test_local_push_bare(self):
464 def test_local_push_bare(self, tmp_path_factory):
483 target_repo = self.get_empty_repo(bare=True)
465 target_repo = self.get_empty_repo(tmp_path_factory, bare=True)
484
466
485 pushed_branch = 'pushed_branch'
467 pushed_branch = 'pushed_branch'
486 self.repo._local_push('master', target_repo.path, pushed_branch)
468 self.repo._local_push('master', target_repo.path, pushed_branch)
@@ -494,8 +476,8 b' TODO: To be written...'
494 assert (target_repo.branches[pushed_branch] ==
476 assert (target_repo.branches[pushed_branch] ==
495 self.repo.branches['master'])
477 self.repo.branches['master'])
496
478
497 def test_local_push_non_bare_target_branch_is_checked_out(self):
479 def test_local_push_non_bare_target_branch_is_checked_out(self, tmp_path_factory):
498 target_repo = self.get_clone_repo()
480 target_repo = self.get_clone_repo(tmp_path_factory)
499
481
500 pushed_branch = 'pushed_branch'
482 pushed_branch = 'pushed_branch'
501 # Create a new branch in source repo
483 # Create a new branch in source repo
@@ -515,8 +497,8 b' TODO: To be written...'
515 with pytest.raises(RepositoryError):
497 with pytest.raises(RepositoryError):
516 self.repo._local_push('master', target_repo.path, 'master')
498 self.repo._local_push('master', target_repo.path, 'master')
517
499
518 def test_hooks_can_be_enabled_via_env_variable_for_local_push(self):
500 def test_hooks_can_be_enabled_via_env_variable_for_local_push(self, tmp_path_factory):
519 target_repo = self.get_empty_repo(bare=True)
501 target_repo = self.get_empty_repo(tmp_path_factory, bare=True)
520
502
521 with mock.patch.object(self.repo, 'run_git_command') as run_mock:
503 with mock.patch.object(self.repo, 'run_git_command') as run_mock:
522 self.repo._local_push(
504 self.repo._local_push(
@@ -540,8 +522,8 b' TODO: To be written...'
540 f.write('\n'.join(script_lines))
522 f.write('\n'.join(script_lines))
541 os.chmod(hook_path, 0o755)
523 os.chmod(hook_path, 0o755)
542
524
543 def test_local_push_does_not_execute_hook(self):
525 def test_local_push_does_not_execute_hook(self, tmp_path_factory):
544 target_repo = self.get_empty_repo()
526 target_repo = self.get_empty_repo(tmp_path_factory)
545
527
546 pushed_branch = 'pushed_branch'
528 pushed_branch = 'pushed_branch'
547 self._add_failing_hook(target_repo.path, 'pre-receive')
529 self._add_failing_hook(target_repo.path, 'pre-receive')
@@ -556,8 +538,8 b' TODO: To be written...'
556 assert (target_repo.branches[pushed_branch] ==
538 assert (target_repo.branches[pushed_branch] ==
557 self.repo.branches['master'])
539 self.repo.branches['master'])
558
540
559 def test_local_push_executes_hook(self):
541 def test_local_push_executes_hook(self, tmp_path_factory):
560 target_repo = self.get_empty_repo(bare=True)
542 target_repo = self.get_empty_repo(tmp_path_factory, bare=True)
561 self._add_failing_hook(target_repo.path, 'pre-receive', bare=True)
543 self._add_failing_hook(target_repo.path, 'pre-receive', bare=True)
562 with pytest.raises(RepositoryError):
544 with pytest.raises(RepositoryError):
563 self.repo._local_push(
545 self.repo._local_push(
@@ -1087,27 +1069,32 b' class TestGitSpecificWithRepo(BackendTes'
1087 'base')
1069 'base')
1088
1070
1089 def test_get_diff_runs_git_command_with_hashes(self):
1071 def test_get_diff_runs_git_command_with_hashes(self):
1072 comm1 = self.repo[0]
1073 comm2 = self.repo[1]
1090 self.repo.run_git_command = mock.Mock(return_value=['', ''])
1074 self.repo.run_git_command = mock.Mock(return_value=['', ''])
1091 self.repo.get_diff(self.repo[0], self.repo[1])
1075 self.repo.get_diff(comm1, comm2)
1076
1092 self.repo.run_git_command.assert_called_once_with(
1077 self.repo.run_git_command.assert_called_once_with(
1093 ['diff', '-U3', '--full-index', '--binary', '-p', '-M',
1078 ['diff', '-U3', '--full-index', '--binary', '-p', '-M',
1094 '--abbrev=40', self.repo._get_commit_id(0),
1079 '--abbrev=40', comm1.raw_id, comm2.raw_id])
1095 self.repo._get_commit_id(1)])
1096
1080
1097 def test_get_diff_runs_git_command_with_str_hashes(self):
1081 def test_get_diff_runs_git_command_with_str_hashes(self):
1082 comm2 = self.repo[1]
1098 self.repo.run_git_command = mock.Mock(return_value=['', ''])
1083 self.repo.run_git_command = mock.Mock(return_value=['', ''])
1099 self.repo.get_diff(self.repo.EMPTY_COMMIT, self.repo[1])
1084 self.repo.get_diff(self.repo.EMPTY_COMMIT, comm2)
1100 self.repo.run_git_command.assert_called_once_with(
1085 self.repo.run_git_command.assert_called_once_with(
1101 ['show', '-U3', '--full-index', '--binary', '-p', '-M',
1086 ['show', '-U3', '--full-index', '--binary', '-p', '-M',
1102 '--abbrev=40', self.repo._get_commit_id(1)])
1087 '--abbrev=40', comm2.raw_id])
1103
1088
1104 def test_get_diff_runs_git_command_with_path_if_its_given(self):
1089 def test_get_diff_runs_git_command_with_path_if_its_given(self):
1090 comm1 = self.repo[0]
1091 comm2 = self.repo[1]
1105 self.repo.run_git_command = mock.Mock(return_value=['', ''])
1092 self.repo.run_git_command = mock.Mock(return_value=['', ''])
1106 self.repo.get_diff(self.repo[0], self.repo[1], 'foo')
1093 self.repo.get_diff(comm1, comm2, 'foo')
1107 self.repo.run_git_command.assert_called_once_with(
1094 self.repo.run_git_command.assert_called_once_with(
1108 ['diff', '-U3', '--full-index', '--binary', '-p', '-M',
1095 ['diff', '-U3', '--full-index', '--binary', '-p', '-M',
1109 '--abbrev=40', self.repo._get_commit_id(0),
1096 '--abbrev=40', self.repo._lookup_commit(0),
1110 self.repo._get_commit_id(1), '--', 'foo'])
1097 comm2.raw_id, '--', 'foo'])
1111
1098
1112
1099
1113 @pytest.mark.usefixtures("vcs_repository_support")
1100 @pytest.mark.usefixtures("vcs_repository_support")
@@ -70,10 +70,13 b' class TestMercurialRemoteRepoInvalidatio'
70 tags[name] = raw_id
70 tags[name] = raw_id
71
71
72 repo = backend_hg.repo.scm_instance()
72 repo = backend_hg.repo.scm_instance()
73
73 with patch.object(repo, '_remote') as remote:
74 with patch.object(repo, '_remote') as remote:
75 repo.tags = tags
74 remote.lookup.return_value = ('commit-id', 'commit-idx')
76 remote.lookup.return_value = ('commit-id', 'commit-idx')
75 remote.tags.return_value = tags
77 remote.tags.return_value = tags
76 remote._get_tags.return_value = tags
78 remote._get_tags.return_value = tags
79 remote.is_empty.return_value = False
77 remote.tag.side_effect = add_tag
80 remote.tag.side_effect = add_tag
78
81
79 # Invoke method.
82 # Invoke method.
@@ -79,9 +79,17 b' class TestInMemoryCommit(BackendTestMixi'
79 self.commit()
79 self.commit()
80 self.assert_succesful_commit(nodes)
80 self.assert_succesful_commit(nodes)
81
81
82 @pytest.mark.skip_backends(
82 @pytest.mark.backends("hg")
83 'svn', reason="Svn does not support commits on branches.")
83 def test_add_on_branch_hg(self, nodes):
84 def test_add_on_branch(self, nodes):
84 for node in nodes:
85 self.imc.add(node)
86 self.commit(branch=u'stable')
87 self.assert_succesful_commit(nodes)
88
89 @pytest.mark.backends("git")
90 def test_add_on_branch_git(self, nodes):
91 self.repo._checkout('stable', create=True)
92
85 for node in nodes:
93 for node in nodes:
86 self.imc.add(node)
94 self.imc.add(node)
87 self.commit(branch=u'stable')
95 self.commit(branch=u'stable')
@@ -54,6 +54,20 b' class TestVCSOperations(object):'
54 'hg clone', clone_url, tmpdir.strpath)
54 'hg clone', clone_url, tmpdir.strpath)
55 _check_proper_clone(stdout, stderr, 'hg')
55 _check_proper_clone(stdout, stderr, 'hg')
56
56
57 def test_clone_hg_repo_by_admin_pull_protocol(self, rc_web_server, tmpdir):
58 clone_url = rc_web_server.repo_clone_url(HG_REPO)
59 stdout, stderr = Command('/tmp').execute(
60 'hg clone --pull', clone_url, tmpdir.strpath)
61 _check_proper_clone(stdout, stderr, 'hg')
62
63 def test_clone_hg_repo_by_admin_pull_stream_protocol(self, rc_web_server, tmpdir):
64 clone_url = rc_web_server.repo_clone_url(HG_REPO)
65 stdout, stderr = Command('/tmp').execute(
66 'hg clone --pull --stream', clone_url, tmpdir.strpath)
67 assert 'files to transfer,' in stdout
68 assert 'transferred 1.' in stdout
69 assert '114 files updated,' in stdout
70
57 def test_clone_git_repo_by_admin(self, rc_web_server, tmpdir):
71 def test_clone_git_repo_by_admin(self, rc_web_server, tmpdir):
58 clone_url = rc_web_server.repo_clone_url(GIT_REPO)
72 clone_url = rc_web_server.repo_clone_url(GIT_REPO)
59 cmd = Command('/tmp')
73 cmd = Command('/tmp')
@@ -46,6 +46,7 b' class TestVCSOperationsSpecial(object):'
46 cmd.execute('git clone', clone_url)
46 cmd.execute('git clone', clone_url)
47
47
48 repo = GitRepository(os.path.join(tmpdir.strpath, empty_repo.repo_name))
48 repo = GitRepository(os.path.join(tmpdir.strpath, empty_repo.repo_name))
49 repo._checkout('test', create=True)
49 repo.in_memory_commit.add(FileNode('file', content=''))
50 repo.in_memory_commit.add(FileNode('file', content=''))
50 repo.in_memory_commit.commit(
51 repo.in_memory_commit.commit(
51 message='Commit on branch test',
52 message='Commit on branch test',
@@ -92,6 +92,7 b' def junk_form_data_detector(request):'
92
92
93 def sanity_check_factory(handler, registry):
93 def sanity_check_factory(handler, registry):
94 def sanity_check(request):
94 def sanity_check(request):
95 log.debug('Checking current URL sanity for bad data')
95 try:
96 try:
96 junk_encoding_detector(request)
97 junk_encoding_detector(request)
97 bad_url_data_detector(request)
98 bad_url_data_detector(request)
@@ -113,5 +114,5 b' def includeme(config):'
113 'pyramid.events.NewRequest')
114 'pyramid.events.NewRequest')
114 config.add_subscriber('rhodecode.subscribers.add_request_user_context',
115 config.add_subscriber('rhodecode.subscribers.add_request_user_context',
115 'pyramid.events.ContextFound')
116 'pyramid.events.ContextFound')
117 config.add_tween('rhodecode.tweens.vcs_detection_tween_factory')
116 config.add_tween('rhodecode.tweens.sanity_check_factory')
118 config.add_tween('rhodecode.tweens.sanity_check_factory')
117 config.add_tween('rhodecode.tweens.vcs_detection_tween_factory')
@@ -1,26 +0,0 b''
1 .. _permissions-info-add-group-ref:
2
3 Repository Administration
4 =========================
5
6 Repository permissions in |RCE| can be managed in a number of different ways.
7 This overview should give you an insight into how you could adopt particular
8 settings for your needs:
9
10 * Global |repo| permissions: This allows you to set the default permissions
11 for each new |repo| created within |RCE|, see :ref:`repo-default-ref`. All
12 |repos| created will inherit these permissions unless explicitly configured.
13 * Individual |repo| permissions: To set individual |repo| permissions,
14 see :ref:`set-repo-perms`.
15 * Repository Group permissions: This allows you to define the permissions for
16 a group, and all |repos| created within that group will inherit the same
17 permissions.
18
19 .. toctree::
20
21 repo-perm-steps
22 repo-extra-fields
23 repo-hooks
24 repo-issue-tracker
25 repo-vcs
26
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
@@ -1,12 +0,0 b''
1 <%namespace name="base" file="/base/base.mako"/>
2
3 <div class="summary-detail-header">
4 <h4 class="item">
5 ${_('Commit Author')}
6 </h4>
7 </div>
8 <div class="sidebar-right-content">
9 ${base.gravatar_with_user(c.commit.author)}
10 <div class="user-inline-data">- ${h.age_component(c.commit.date)}</div>
11 </div>
12
General Comments 0
You need to be logged in to leave comments. Login now