##// END OF EJS Templates
merged new-ui into default
marcink -
r3779:c69b10da merge default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -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,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,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,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,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, (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
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -29,7 +29,7 b' 1. Go to :menuselection:`Admin --> Repos'
29 29 beside the |repo| to which you wish to add extra fields.
30 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 34 The most important is the `New field key` variable which under the value will
35 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
1 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
1 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
@@ -16,19 +16,17 b' The following are the most common system'
16 16
17 17 .. toctree::
18 18
19 config-files-overview
20 vcs-server
21 svn-http
22 svn-path-permissions
23 gunicorn-ssl-support
24 apache-config
25 nginx-config
26 backup-restore
27 tuning-rhodecode
28 indexing
29 reset-information
30 enable-debug
31 admin-tricks
32 cleanup-cmds
33 restore-deleted-repositories
34
19 system_admin/config-files-overview
20 system_admin/vcs-server
21 system_admin/svn-http
22 system_admin/svn-path-permissions
23 system_admin/gunicorn-ssl-support
24 system_admin/apache-config
25 system_admin/nginx-config
26 system_admin/backup-restore
27 system_admin/tuning-rhodecode
28 system_admin/indexing
29 system_admin/reset-information
30 system_admin/enable-debug
31 system_admin/admin-tricks
32 system_admin/cleanup-cmds
@@ -57,7 +57,7 b' 2. To add a message that will be display'
57 57 3. Select :guilabel:`Save`, and you will see the message once your page
58 58 refreshes.
59 59
60 .. image:: ../images/server-wide-announcement.png
60 .. image:: ../../images/server-wide-announcement.png
61 61 :alt: Server Wide Announcement
62 62
63 63 .. _md-rst:
@@ -207,7 +207,7 b' 2. Restart the |RCE| instance and check '
207 207 Instance "enterprise-2" successfully stopped.
208 208 Instance "enterprise-2" successfully started.
209 209
210 .. image:: ../images/language.png
210 .. image:: ../../images/language.png
211 211
212 212 .. _set-repo-pub:
213 213
@@ -8,7 +8,7 b' the information in the following section'
8 8
9 9 .. toctree::
10 10
11 apache-conf-example
12 apache-diffie-hellman
13 apache-subdirectory
14 apache-wsgi-coding
11 apache/apache-conf-example
12 apache/apache-diffie-hellman
13 apache/apache-subdirectory
14 apache/apache-wsgi-coding
1 NO CONTENT: file renamed from docs/admin/apache-conf-example.rst to docs/admin/system_admin/apache/apache-conf-example.rst
1 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
1 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
1 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
1 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
1 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 9 .. toctree::
10 10
11 nginx-config-example
12 nginx-diffie-hellman
13 nginx-proxy-conf
14 nginx-url-prefix
11 nginx/nginx-config-example
12 nginx/nginx-diffie-hellman
13 nginx/nginx-proxy-conf
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
1 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
1 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
1 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
@@ -8,14 +8,14 b' may find some of the following methods u'
8 8
9 9 .. toctree::
10 10
11 tuning-gunicorn
12 tuning-vcs-memory-cache
13 tuning-user-sessions-performance
14 tuning-increase-db-performance
15 tuning-scale-horizontally-cluster
16 tuning-mount-cache-memory
17 tuning-change-encoding
18 tuning-change-large-file-dir
19 tuning-change-lfs-dir
20 tuning-hg-auth-loop
11 tuning/tuning-gunicorn
12 tuning/tuning-vcs-memory-cache
13 tuning/tuning-user-sessions-performance
14 tuning/tuning-increase-db-performance
15 tuning/tuning-scale-horizontally-cluster
16 tuning/tuning-mount-cache-memory
17 tuning/tuning-change-encoding
18 tuning/tuning-change-large-file-dir
19 tuning/tuning-change-lfs-dir
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
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
1 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 42 ## restarted, could prevent memory leaks
43 43 max_requests = 1000
44 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 46 ## gets killed and restarted. Set to 6hrs
47 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
1 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
1 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
1 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
@@ -204,6 +204,7 b' are not required in args.'
204 204 methods/pull-request-methods
205 205 methods/repo-methods
206 206 methods/repo-group-methods
207 methods/search-methods
207 208 methods/server-methods
208 209 methods/user-methods
209 210 methods/user-group-methods
@@ -462,6 +462,7 b' get_repo_file'
462 462 :param cache: Use internal caches for fetching files. If disabled fetching
463 463 files is slower but more memory efficient
464 464 :type cache: Optional(bool)
465
465 466 Example output:
466 467
467 468 .. code-block:: bash
@@ -499,53 +500,51 b' get_repo_nodes'
499 500 .. py:function:: get_repo_nodes(apiuser, repoid, revision, root_path, ret_type=<Optional:'all'>, details=<Optional:'basic'>, max_file_bytes=<Optional:None>)
500 501
501 502 Returns a list of nodes and children in a flat list for a given
502 path at given revision.
503 path at given revision.
503 504
504 It's possible to specify ret_type to show only `files` or `dirs`.
505 It's possible to specify ret_type to show only `files` or `dirs`.
505 506
506 This command can only be run using an |authtoken| with admin rights,
507 or users with at least read rights to |repos|.
507 This command can only be run using an |authtoken| with admin rights,
508 or users with at least read rights to |repos|.
508 509
509 :param apiuser: This is filled automatically from the |authtoken|.
510 :type apiuser: AuthUser
511 :param repoid: The repository name or repository ID.
512 :type repoid: str or int
513 :param revision: The revision for which listing should be done.
514 :type revision: str
515 :param root_path: The path from which to start displaying.
516 :type root_path: str
517 :param ret_type: Set the return type. Valid options are
518 ``all`` (default), ``files`` and ``dirs``.
519 :type ret_type: Optional(str)
520 :param details: Returns extended information about nodes, such as
521 md5, binary, and or content.
522 The valid options are ``basic`` and ``full``.
523 :type details: Optional(str)
524 :param max_file_bytes: Only return file content under this file size bytes
525 :type details: Optional(int)
526
527 Example output:
510 :param apiuser: This is filled automatically from the |authtoken|.
511 :type apiuser: AuthUser
512 :param repoid: The repository name or repository ID.
513 :type repoid: str or int
514 :param revision: The revision for which listing should be done.
515 :type revision: str
516 :param root_path: The path from which to start displaying.
517 :type root_path: str
518 :param ret_type: Set the return type. Valid options are
519 ``all`` (default), ``files`` and ``dirs``.
520 :type ret_type: Optional(str)
521 :param details: Returns extended information about nodes, such as
522 md5, binary, and or content.
523 The valid options are ``basic`` and ``full``.
524 :type details: Optional(str)
525 :param max_file_bytes: Only return file content under this file size bytes
526 :type details: Optional(int)
528 527
529 .. code-block:: bash
528 Example output:
529
530 .. code-block:: bash
530 531
531 id : <id_given_in_input>
532 result: [
533 {
534 "binary": false,
535 "content": "File line
536 Line2
537 ",
538 "extension": "md",
539 "lines": 2,
540 "md5": "059fa5d29b19c0657e384749480f6422",
541 "mimetype": "text/x-minidsrc",
542 "name": "file.md",
543 "size": 580,
544 "type": "file"
545 },
546 ...
547 ]
548 error: null
532 id : <id_given_in_input>
533 result: [
534 {
535 "binary": false,
536 "content": "File line",
537 "extension": "md",
538 "lines": 2,
539 "md5": "059fa5d29b19c0657e384749480f6422",
540 "mimetype": "text/x-minidsrc",
541 "name": "file.md",
542 "size": 580,
543 "type": "file"
544 },
545 ...
546 ]
547 error: null
549 548
550 549
551 550 get_repo_refs
@@ -46,7 +46,7 b' and commit files and |repos| while manag'
46 46 nix/default-env
47 47 admin/system-admin
48 48 admin/user-admin
49 admin/setting-repo-perms
49 admin/repo-admin
50 50 admin/security-tips
51 51 auth/auth
52 52 issue-trackers/issue-trackers
@@ -35,6 +35,7 b''
35 35 "<%= dirs.js.node_modules %>/moment/min/moment.min.js",
36 36 "<%= dirs.js.node_modules %>/clipboard/dist/clipboard.min.js",
37 37 "<%= dirs.js.node_modules %>/favico.js/favico-0.3.10.min.js",
38 "<%= dirs.js.node_modules %>/dropzone/dist/dropzone.js",
38 39 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/sticky-sidebar.min.js",
39 40 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/jquery.sticky-sidebar.min.js",
40 41 "<%= dirs.js.node_modules %>/waypoints/lib/noframework.waypoints.min.js",
@@ -13,6 +13,7 b''
13 13 "clipboard": "^2.0.1",
14 14 "exports-loader": "^0.6.4",
15 15 "favico.js": "^0.3.10",
16 "dropzone": "^5.5.0",
16 17 "grunt": "^0.4.5",
17 18 "grunt-cli": "^1.3.1",
18 19 "grunt-contrib-concat": "^0.5.1",
This diff has been collapsed as it changes many lines, (617 lines changed) Show them Hide them
@@ -211,13 +211,13 b' let'
211 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 215 name = "_at_polymer_slash_polymer";
216 216 packageName = "@polymer/polymer";
217 version = "3.1.0";
218 src = fetchurl {
219 url = "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.1.0.tgz";
220 sha512 = "hwN8IMERsFATz/9dSMxYHL+84J9uBkPuuarxJWlTsppZ4CAYTZKnepBfNrKoyNsafBmA3yXBiiKPPf+fJtza7A==";
217 version = "3.2.0";
218 src = fetchurl {
219 url = "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.2.0.tgz";
220 sha512 = "L6uV1oM6T6xbwbVx6t3biG5T2VSSB03LxnIrUd9M2pr6RkHVPFHJ37pC5MUwBAEhkGFJif7eks7fdMMSGZTeEQ==";
221 221 };
222 222 };
223 223 "@types/clone-0.1.30" = {
@@ -229,13 +229,13 b' let'
229 229 sha1 = "e7365648c1b42136a59c7d5040637b3b5c83b614";
230 230 };
231 231 };
232 "@types/node-6.14.3" = {
232 "@types/node-6.14.6" = {
233 233 name = "_at_types_slash_node";
234 234 packageName = "@types/node";
235 version = "6.14.3";
236 src = fetchurl {
237 url = "https://registry.npmjs.org/@types/node/-/node-6.14.3.tgz";
238 sha512 = "V2VrQBCKo4U0rni6tW4AASRDqIO5ZTLDN/Xzrm4mNBr9SGQYZ+7zZJn+hMs89Q8ZCIHzp4aWQPyCpK+rux1YGA==";
235 version = "6.14.6";
236 src = fetchurl {
237 url = "https://registry.npmjs.org/@types/node/-/node-6.14.6.tgz";
238 sha512 = "rFs9zCFtSHuseiNXxYxFlun8ibu+jtZPgRM+2ILCmeLiGeGLiIGxuOzD+cNyHegI1GD+da3R/cIbs9+xCLp13w==";
239 239 };
240 240 };
241 241 "@types/parse5-2.2.34" = {
@@ -409,22 +409,22 b' let'
409 409 sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA==";
410 410 };
411 411 };
412 "@webcomponents/shadycss-1.9.0" = {
412 "@webcomponents/shadycss-1.9.1" = {
413 413 name = "_at_webcomponents_slash_shadycss";
414 414 packageName = "@webcomponents/shadycss";
415 version = "1.9.0";
416 src = fetchurl {
417 url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.9.0.tgz";
418 sha512 = "g8Xa+6RSEME4g/wLJW4YII0eq15rvXp76RxPAuv7hx+Bdoi7GzZJ/EoZOUfyIbqAsQbII1TcWD4/+Xhs5NcM1w==";
419 };
420 };
421 "@webcomponents/webcomponentsjs-2.2.7" = {
415 version = "1.9.1";
416 src = fetchurl {
417 url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.9.1.tgz";
418 sha512 = "IaZOnWOKXHghqk/WfPNDRIgDBi3RsVPY2IFAw6tYiL9UBGvQRy5R6uC+Fk7qTZsReTJ0xh5MTT8yAcb3MUR4mQ==";
419 };
420 };
421 "@webcomponents/webcomponentsjs-2.2.10" = {
422 422 name = "_at_webcomponents_slash_webcomponentsjs";
423 423 packageName = "@webcomponents/webcomponentsjs";
424 version = "2.2.7";
425 src = fetchurl {
426 url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.7.tgz";
427 sha512 = "kPPjzV+5kpoWpTniyvBSPcXS33f3j/C6HvNOJ3YecF3pvz3XwVeU4ammbxtVy/osF3z7hr1DYNptIf4oPEvXZA==";
424 version = "2.2.10";
425 src = fetchurl {
426 url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.10.tgz";
427 sha512 = "5dzhUhP+h0qMiK0IWb7VNb0OGBoXO3AuI6Qi8t9PoKT50s5L1jv0xnwnLq+cFgPuTB8FLTNP8xIDmyoOsKBy9Q==";
428 428 };
429 429 };
430 430 "@xtuc/ieee754-1.2.0" = {
@@ -499,13 +499,13 b' let'
499 499 sha1 = "82ffb02b29e662ae53bdc20af15947706739c536";
500 500 };
501 501 };
502 "ajv-6.9.2" = {
502 "ajv-6.10.0" = {
503 503 name = "ajv";
504 504 packageName = "ajv";
505 version = "6.9.2";
506 src = fetchurl {
507 url = "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz";
508 sha512 = "4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==";
505 version = "6.10.0";
506 src = fetchurl {
507 url = "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz";
508 sha512 = "nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==";
509 509 };
510 510 };
511 511 "ajv-keywords-3.4.0" = {
@@ -743,13 +743,13 b' let'
743 743 sha512 = "p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==";
744 744 };
745 745 };
746 "assert-1.4.1" = {
746 "assert-1.5.0" = {
747 747 name = "assert";
748 748 packageName = "assert";
749 version = "1.4.1";
750 src = fetchurl {
751 url = "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz";
752 sha1 = "99912d591836b5a6f5b345c0f07eefc08fc65d91";
749 version = "1.5.0";
750 src = fetchurl {
751 url = "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz";
752 sha512 = "EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==";
753 753 };
754 754 };
755 755 "assert-plus-0.2.0" = {
@@ -815,13 +815,13 b' let'
815 815 sha512 = "H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==";
816 816 };
817 817 };
818 "async-each-1.0.1" = {
818 "async-each-1.0.3" = {
819 819 name = "async-each";
820 820 packageName = "async-each";
821 version = "1.0.1";
822 src = fetchurl {
823 url = "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz";
824 sha1 = "19d386a1d9edc6e7c1c85d388aedbcc56d33602d";
821 version = "1.0.3";
822 src = fetchurl {
823 url = "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz";
824 sha512 = "z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==";
825 825 };
826 826 };
827 827 "asynckit-0.4.0" = {
@@ -1436,22 +1436,22 b' let'
1436 1436 sha512 = "vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==";
1437 1437 };
1438 1438 };
1439 "binary-extensions-1.13.0" = {
1439 "binary-extensions-1.13.1" = {
1440 1440 name = "binary-extensions";
1441 1441 packageName = "binary-extensions";
1442 version = "1.13.0";
1443 src = fetchurl {
1444 url = "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz";
1445 sha512 = "EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==";
1446 };
1447 };
1448 "bluebird-3.5.3" = {
1442 version = "1.13.1";
1443 src = fetchurl {
1444 url = "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz";
1445 sha512 = "Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==";
1446 };
1447 };
1448 "bluebird-3.5.4" = {
1449 1449 name = "bluebird";
1450 1450 packageName = "bluebird";
1451 version = "3.5.3";
1452 src = fetchurl {
1453 url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz";
1454 sha512 = "/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==";
1451 version = "3.5.4";
1452 src = fetchurl {
1453 url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz";
1454 sha512 = "FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==";
1455 1455 };
1456 1456 };
1457 1457 "bn.js-4.11.8" = {
@@ -1652,13 +1652,13 b' let'
1652 1652 sha1 = "9bb5304d2e0b56698b2c758b08a3eaa9daa58a39";
1653 1653 };
1654 1654 };
1655 "camelcase-5.0.0" = {
1655 "camelcase-5.3.1" = {
1656 1656 name = "camelcase";
1657 1657 packageName = "camelcase";
1658 version = "5.0.0";
1659 src = fetchurl {
1660 url = "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz";
1661 sha512 = "faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==";
1658 version = "5.3.1";
1659 src = fetchurl {
1660 url = "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz";
1661 sha512 = "L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==";
1662 1662 };
1663 1663 };
1664 1664 "caniuse-api-1.6.1" = {
@@ -1670,22 +1670,22 b' let'
1670 1670 sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c";
1671 1671 };
1672 1672 };
1673 "caniuse-db-1.0.30000939" = {
1673 "caniuse-db-1.0.30000967" = {
1674 1674 name = "caniuse-db";
1675 1675 packageName = "caniuse-db";
1676 version = "1.0.30000939";
1677 src = fetchurl {
1678 url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000939.tgz";
1679 sha512 = "nB5tLf3hOs+biXl1lhKjHRgNC0J1I7H52h/t1FP7qxARKKwpB0z+P/JewJLYAlxCBP/q7rxJzQzHHrQMl0viKg==";
1680 };
1681 };
1682 "caniuse-lite-1.0.30000939" = {
1676 version = "1.0.30000967";
1677 src = fetchurl {
1678 url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000967.tgz";
1679 sha512 = "70gk6cLSD5rItxnZ7WUxyCpM9LAjEb1tVzlENQfXQXZS/IiGnfAC6u32G5cZFlDBKjNPBIta/QSx5CZLZepxRA==";
1680 };
1681 };
1682 "caniuse-lite-1.0.30000967" = {
1683 1683 name = "caniuse-lite";
1684 1684 packageName = "caniuse-lite";
1685 version = "1.0.30000939";
1686 src = fetchurl {
1687 url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000939.tgz";
1688 sha512 = "oXB23ImDJOgQpGjRv1tCtzAvJr4/OvrHi5SO2vUgB0g0xpdZZoA/BxfImiWfdwoYdUTtQrPsXsvYU/dmCSM8gg==";
1685 version = "1.0.30000967";
1686 src = fetchurl {
1687 url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000967.tgz";
1688 sha512 = "rUBIbap+VJfxTzrM4akJ00lkvVb5/n5v3EGXfWzSH5zT8aJmGzjA8HWhJ4U6kCpzxozUSnB+yvAYDRPY6mRpgQ==";
1689 1689 };
1690 1690 };
1691 1691 "caseless-0.12.0" = {
@@ -1733,13 +1733,13 b' let'
1733 1733 sha512 = "Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==";
1734 1734 };
1735 1735 };
1736 "chokidar-2.1.2" = {
1736 "chokidar-2.1.5" = {
1737 1737 name = "chokidar";
1738 1738 packageName = "chokidar";
1739 version = "2.1.2";
1740 src = fetchurl {
1741 url = "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz";
1742 sha512 = "IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==";
1739 version = "2.1.5";
1740 src = fetchurl {
1741 url = "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz";
1742 sha512 = "i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==";
1743 1743 };
1744 1744 };
1745 1745 "chownr-1.1.1" = {
@@ -1967,13 +1967,13 b' let'
1967 1967 sha512 = "mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==";
1968 1968 };
1969 1969 };
1970 "combined-stream-1.0.7" = {
1970 "combined-stream-1.0.8" = {
1971 1971 name = "combined-stream";
1972 1972 packageName = "combined-stream";
1973 version = "1.0.7";
1974 src = fetchurl {
1975 url = "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz";
1976 sha512 = "brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==";
1973 version = "1.0.8";
1974 src = fetchurl {
1975 url = "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz";
1976 sha512 = "FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==";
1977 1977 };
1978 1978 };
1979 1979 "commander-2.14.1" = {
@@ -1994,6 +1994,15 b' let'
1994 1994 sha512 = "wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==";
1995 1995 };
1996 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 };
1997 2006 "commondir-1.0.1" = {
1998 2007 name = "commondir";
1999 2008 packageName = "commondir";
@@ -2003,13 +2012,13 b' let'
2003 2012 sha1 = "ddd800da0c66127393cca5950ea968a3aaf1253b";
2004 2013 };
2005 2014 };
2006 "component-emitter-1.2.1" = {
2015 "component-emitter-1.3.0" = {
2007 2016 name = "component-emitter";
2008 2017 packageName = "component-emitter";
2009 version = "1.2.1";
2010 src = fetchurl {
2011 url = "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz";
2012 sha1 = "137918d6d78283f7df7a6b7c5a63e140e69425e6";
2018 version = "1.3.0";
2019 src = fetchurl {
2020 url = "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz";
2021 sha512 = "Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==";
2013 2022 };
2014 2023 };
2015 2024 "concat-map-0.0.1" = {
@@ -2480,6 +2489,15 b' let'
2480 2489 sha1 = "dcd8488a26f563d61079e48c9f7b7e32373682cf";
2481 2490 };
2482 2491 };
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 };
2483 2501 "duplexify-3.7.1" = {
2484 2502 name = "duplexify";
2485 2503 packageName = "duplexify";
@@ -2498,13 +2516,13 b' let'
2498 2516 sha1 = "3a83a904e54353287874c564b7549386849a98c9";
2499 2517 };
2500 2518 };
2501 "electron-to-chromium-1.3.113" = {
2519 "electron-to-chromium-1.3.133" = {
2502 2520 name = "electron-to-chromium";
2503 2521 packageName = "electron-to-chromium";
2504 version = "1.3.113";
2505 src = fetchurl {
2506 url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz";
2507 sha512 = "De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==";
2522 version = "1.3.133";
2523 src = fetchurl {
2524 url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.133.tgz";
2525 sha512 = "lyoC8aoqbbDqsprb6aPdt9n3DpOZZzdz/T4IZKsR0/dkZIxnJVUjjcpOSwA66jPRIOyDAamCTAUqweU05kKNSg==";
2508 2526 };
2509 2527 };
2510 2528 "elliptic-6.4.1" = {
@@ -2615,13 +2633,13 b' let'
2615 2633 sha1 = "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4";
2616 2634 };
2617 2635 };
2618 "eslint-scope-4.0.0" = {
2636 "eslint-scope-4.0.3" = {
2619 2637 name = "eslint-scope";
2620 2638 packageName = "eslint-scope";
2621 version = "4.0.0";
2622 src = fetchurl {
2623 url = "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz";
2624 sha512 = "1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==";
2639 version = "4.0.3";
2640 src = fetchurl {
2641 url = "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz";
2642 sha512 = "p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==";
2625 2643 };
2626 2644 };
2627 2645 "espree-3.5.4" = {
@@ -2912,13 +2930,13 b' let'
2912 2930 sha1 = "9326b1488c22d1a6088650a86901b2d9a90a2cbc";
2913 2931 };
2914 2932 };
2915 "fined-1.1.1" = {
2933 "fined-1.2.0" = {
2916 2934 name = "fined";
2917 2935 packageName = "fined";
2918 version = "1.1.1";
2919 src = fetchurl {
2920 url = "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz";
2921 sha512 = "jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==";
2936 version = "1.2.0";
2937 src = fetchurl {
2938 url = "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz";
2939 sha512 = "ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==";
2922 2940 };
2923 2941 };
2924 2942 "flagged-respawn-1.0.1" = {
@@ -3020,13 +3038,13 b' let'
3020 3038 sha1 = "1504ad2523158caa40db4a2787cb01411994ea4f";
3021 3039 };
3022 3040 };
3023 "fsevents-1.2.7" = {
3041 "fsevents-1.2.9" = {
3024 3042 name = "fsevents";
3025 3043 packageName = "fsevents";
3026 version = "1.2.7";
3027 src = fetchurl {
3028 url = "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz";
3029 sha512 = "Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==";
3044 version = "1.2.9";
3045 src = fetchurl {
3046 url = "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz";
3047 sha512 = "oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==";
3030 3048 };
3031 3049 };
3032 3050 "function-bind-1.1.1" = {
@@ -3110,13 +3128,13 b' let'
3110 3128 sha1 = "4a973f635b9190f715d10987d5c00fd2815ebe3d";
3111 3129 };
3112 3130 };
3113 "glob-7.1.3" = {
3131 "glob-7.1.4" = {
3114 3132 name = "glob";
3115 3133 packageName = "glob";
3116 version = "7.1.3";
3117 src = fetchurl {
3118 url = "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz";
3119 sha512 = "vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==";
3134 version = "7.1.4";
3135 src = fetchurl {
3136 url = "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz";
3137 sha512 = "hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==";
3120 3138 };
3121 3139 };
3122 3140 "glob-parent-3.1.0" = {
@@ -3605,13 +3623,13 b' let'
3605 3623 sha1 = "83f0a0ec378bf3246178b6c2ad9136f135b1c962";
3606 3624 };
3607 3625 };
3608 "ieee754-1.1.12" = {
3626 "ieee754-1.1.13" = {
3609 3627 name = "ieee754";
3610 3628 packageName = "ieee754";
3611 version = "1.1.12";
3612 src = fetchurl {
3613 url = "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz";
3614 sha512 = "GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==";
3629 version = "1.1.13";
3630 src = fetchurl {
3631 url = "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz";
3632 sha512 = "4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==";
3615 3633 };
3616 3634 };
3617 3635 "iferr-0.1.5" = {
@@ -3929,13 +3947,13 b' let'
3929 3947 sha1 = "7ba5ae24217804ac70707b96922567486cc3e84a";
3930 3948 };
3931 3949 };
3932 "is-glob-4.0.0" = {
3950 "is-glob-4.0.1" = {
3933 3951 name = "is-glob";
3934 3952 packageName = "is-glob";
3935 version = "4.0.0";
3936 src = fetchurl {
3937 url = "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz";
3938 sha1 = "9521c76845cc2610a85203ddf080a958c2ffabc0";
3953 version = "4.0.1";
3954 src = fetchurl {
3955 url = "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz";
3956 sha512 = "5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==";
3939 3957 };
3940 3958 };
3941 3959 "is-number-3.0.0" = {
@@ -4163,13 +4181,13 b' let'
4163 4181 sha1 = "46c3fec8c1892b12b0833db9bc7622176dbab34b";
4164 4182 };
4165 4183 };
4166 "jshint-2.10.1" = {
4184 "jshint-2.10.2" = {
4167 4185 name = "jshint";
4168 4186 packageName = "jshint";
4169 version = "2.10.1";
4170 src = fetchurl {
4171 url = "https://registry.npmjs.org/jshint/-/jshint-2.10.1.tgz";
4172 sha512 = "9GpPfKeffYBl7oBDX2lHPG16j0AM7D2bn3aLy9DaWTr6CWa0i/7UGhX8WLZ7V14QQnnr4hXbjauTLYg06F+HYw==";
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==";
4173 4191 };
4174 4192 };
4175 4193 "jshint-2.9.7" = {
@@ -4568,13 +4586,13 b' let'
4568 4586 sha512 = "xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==";
4569 4587 };
4570 4588 };
4571 "mem-4.1.0" = {
4589 "mem-4.3.0" = {
4572 4590 name = "mem";
4573 4591 packageName = "mem";
4574 version = "4.1.0";
4575 src = fetchurl {
4576 url = "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz";
4577 sha512 = "I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==";
4592 version = "4.3.0";
4593 src = fetchurl {
4594 url = "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz";
4595 sha512 = "qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==";
4578 4596 };
4579 4597 };
4580 4598 "memory-fs-0.4.1" = {
@@ -4613,31 +4631,31 b' let'
4613 4631 sha512 = "x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==";
4614 4632 };
4615 4633 };
4616 "mime-db-1.38.0" = {
4634 "mime-db-1.40.0" = {
4617 4635 name = "mime-db";
4618 4636 packageName = "mime-db";
4619 version = "1.38.0";
4620 src = fetchurl {
4621 url = "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz";
4622 sha512 = "bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==";
4623 };
4624 };
4625 "mime-types-2.1.22" = {
4637 version = "1.40.0";
4638 src = fetchurl {
4639 url = "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz";
4640 sha512 = "jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==";
4641 };
4642 };
4643 "mime-types-2.1.24" = {
4626 4644 name = "mime-types";
4627 4645 packageName = "mime-types";
4628 version = "2.1.22";
4629 src = fetchurl {
4630 url = "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz";
4631 sha512 = "aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==";
4632 };
4633 };
4634 "mimic-fn-1.2.0" = {
4646 version = "2.1.24";
4647 src = fetchurl {
4648 url = "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz";
4649 sha512 = "WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==";
4650 };
4651 };
4652 "mimic-fn-2.1.0" = {
4635 4653 name = "mimic-fn";
4636 4654 packageName = "mimic-fn";
4637 version = "1.2.0";
4638 src = fetchurl {
4639 url = "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz";
4640 sha512 = "jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==";
4655 version = "2.1.0";
4656 src = fetchurl {
4657 url = "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz";
4658 sha512 = "OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==";
4641 4659 };
4642 4660 };
4643 4661 "minimalistic-assert-1.0.1" = {
@@ -4739,13 +4757,13 b' let'
4739 4757 sha512 = "bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==";
4740 4758 };
4741 4759 };
4742 "mousetrap-1.6.2" = {
4760 "mousetrap-1.6.3" = {
4743 4761 name = "mousetrap";
4744 4762 packageName = "mousetrap";
4745 version = "1.6.2";
4746 src = fetchurl {
4747 url = "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.2.tgz";
4748 sha512 = "jDjhi7wlHwdO6q6DS7YRmSHcuI+RVxadBkLt3KHrhd3C2b+w5pKefg3oj5beTcHZyVFA9Aksf+yEE1y5jxUjVA==";
4763 version = "1.6.3";
4764 src = fetchurl {
4765 url = "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.3.tgz";
4766 sha512 = "bd+nzwhhs9ifsUrC2tWaSgm24/oo2c83zaRyZQF06hYA6sANfsXHtnZ19AbbbDXCDzeH5nZBSQ4NvCjgD62tJA==";
4749 4767 };
4750 4768 };
4751 4769 "move-concurrently-1.0.1" = {
@@ -4766,13 +4784,13 b' let'
4766 4784 sha1 = "5608aeadfc00be6c2901df5f9861788de0d597c8";
4767 4785 };
4768 4786 };
4769 "nan-2.12.1" = {
4787 "nan-2.13.2" = {
4770 4788 name = "nan";
4771 4789 packageName = "nan";
4772 version = "2.12.1";
4773 src = fetchurl {
4774 url = "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz";
4775 sha512 = "JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==";
4790 version = "2.13.2";
4791 src = fetchurl {
4792 url = "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz";
4793 sha512 = "TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==";
4776 4794 };
4777 4795 };
4778 4796 "nanomatch-1.2.13" = {
@@ -4784,13 +4802,13 b' let'
4784 4802 sha512 = "fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==";
4785 4803 };
4786 4804 };
4787 "neo-async-2.6.0" = {
4805 "neo-async-2.6.1" = {
4788 4806 name = "neo-async";
4789 4807 packageName = "neo-async";
4790 version = "2.6.0";
4791 src = fetchurl {
4792 url = "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz";
4793 sha512 = "MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==";
4808 version = "2.6.1";
4809 src = fetchurl {
4810 url = "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz";
4811 sha512 = "iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==";
4794 4812 };
4795 4813 };
4796 4814 "nice-try-1.0.5" = {
@@ -4955,13 +4973,13 b' let'
4955 4973 sha1 = "7e7d858b781bd7c991a41ba975ed3812754e998c";
4956 4974 };
4957 4975 };
4958 "object-keys-1.1.0" = {
4976 "object-keys-1.1.1" = {
4959 4977 name = "object-keys";
4960 4978 packageName = "object-keys";
4961 version = "1.1.0";
4962 src = fetchurl {
4963 url = "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz";
4964 sha512 = "6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==";
4979 version = "1.1.1";
4980 src = fetchurl {
4981 url = "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz";
4982 sha512 = "NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==";
4965 4983 };
4966 4984 };
4967 4985 "object-visit-1.0.1" = {
@@ -5081,13 +5099,13 b' let'
5081 5099 sha1 = "3fbcfb15b899a44123b34b6dcc18b724336a2cae";
5082 5100 };
5083 5101 };
5084 "p-is-promise-2.0.0" = {
5102 "p-is-promise-2.1.0" = {
5085 5103 name = "p-is-promise";
5086 5104 packageName = "p-is-promise";
5087 version = "2.0.0";
5088 src = fetchurl {
5089 url = "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz";
5090 sha512 = "pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==";
5105 version = "2.1.0";
5106 src = fetchurl {
5107 url = "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz";
5108 sha512 = "Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==";
5091 5109 };
5092 5110 };
5093 5111 "p-limit-1.3.0" = {
@@ -5099,13 +5117,13 b' let'
5099 5117 sha512 = "vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==";
5100 5118 };
5101 5119 };
5102 "p-limit-2.1.0" = {
5120 "p-limit-2.2.0" = {
5103 5121 name = "p-limit";
5104 5122 packageName = "p-limit";
5105 version = "2.1.0";
5106 src = fetchurl {
5107 url = "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz";
5108 sha512 = "NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==";
5123 version = "2.2.0";
5124 src = fetchurl {
5125 url = "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz";
5126 sha512 = "pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==";
5109 5127 };
5110 5128 };
5111 5129 "p-locate-2.0.0" = {
@@ -5135,22 +5153,22 b' let'
5135 5153 sha1 = "cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3";
5136 5154 };
5137 5155 };
5138 "p-try-2.0.0" = {
5156 "p-try-2.2.0" = {
5139 5157 name = "p-try";
5140 5158 packageName = "p-try";
5141 version = "2.0.0";
5142 src = fetchurl {
5143 url = "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz";
5144 sha512 = "hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==";
5145 };
5146 };
5147 "pako-1.0.8" = {
5159 version = "2.2.0";
5160 src = fetchurl {
5161 url = "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz";
5162 sha512 = "R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==";
5163 };
5164 };
5165 "pako-1.0.10" = {
5148 5166 name = "pako";
5149 5167 packageName = "pako";
5150 version = "1.0.8";
5151 src = fetchurl {
5152 url = "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz";
5153 sha512 = "6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==";
5168 version = "1.0.10";
5169 src = fetchurl {
5170 url = "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz";
5171 sha512 = "0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==";
5154 5172 };
5155 5173 };
5156 5174 "parallel-transform-1.1.0" = {
@@ -6134,13 +6152,13 b' let'
6134 6152 sha1 = "97f717b69d48784f5f526a6c5aa8ffdda055a4d1";
6135 6153 };
6136 6154 };
6137 "resolve-1.10.0" = {
6155 "resolve-1.10.1" = {
6138 6156 name = "resolve";
6139 6157 packageName = "resolve";
6140 version = "1.10.0";
6141 src = fetchurl {
6142 url = "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz";
6143 sha512 = "3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==";
6158 version = "1.10.1";
6159 src = fetchurl {
6160 url = "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz";
6161 sha512 = "KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==";
6144 6162 };
6145 6163 };
6146 6164 "resolve-cwd-2.0.0" = {
@@ -6287,22 +6305,22 b' let'
6287 6305 sha1 = "0e7350acdec80b1108528786ec1d4418d11b396d";
6288 6306 };
6289 6307 };
6290 "semver-5.6.0" = {
6308 "semver-5.7.0" = {
6291 6309 name = "semver";
6292 6310 packageName = "semver";
6293 version = "5.6.0";
6294 src = fetchurl {
6295 url = "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz";
6296 sha512 = "RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==";
6297 };
6298 };
6299 "serialize-javascript-1.6.1" = {
6311 version = "5.7.0";
6312 src = fetchurl {
6313 url = "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz";
6314 sha512 = "Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==";
6315 };
6316 };
6317 "serialize-javascript-1.7.0" = {
6300 6318 name = "serialize-javascript";
6301 6319 packageName = "serialize-javascript";
6302 version = "1.6.1";
6303 src = fetchurl {
6304 url = "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz";
6305 sha512 = "A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==";
6320 version = "1.7.0";
6321 src = fetchurl {
6322 url = "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz";
6323 sha512 = "ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==";
6306 6324 };
6307 6325 };
6308 6326 "set-blocking-2.0.0" = {
@@ -6791,13 +6809,13 b' let'
6791 6809 sha512 = "2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==";
6792 6810 };
6793 6811 };
6794 "tapable-1.1.1" = {
6812 "tapable-1.1.3" = {
6795 6813 name = "tapable";
6796 6814 packageName = "tapable";
6797 version = "1.1.1";
6798 src = fetchurl {
6799 url = "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz";
6800 sha512 = "9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==";
6815 version = "1.1.3";
6816 src = fetchurl {
6817 url = "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz";
6818 sha512 = "4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==";
6801 6819 };
6802 6820 };
6803 6821 "through-2.3.8" = {
@@ -6989,13 +7007,13 b' let'
6989 7007 sha1 = "29c5733148057bb4e1f75df35b7a9cb72e6a59dd";
6990 7008 };
6991 7009 };
6992 "uglify-js-3.4.9" = {
7010 "uglify-js-3.4.10" = {
6993 7011 name = "uglify-js";
6994 7012 packageName = "uglify-js";
6995 version = "3.4.9";
6996 src = fetchurl {
6997 url = "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz";
6998 sha512 = "8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==";
7013 version = "3.4.10";
7014 src = fetchurl {
7015 url = "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz";
7016 sha512 = "Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==";
6999 7017 };
7000 7018 };
7001 7019 "uglify-to-browserify-1.0.2" = {
@@ -7115,13 +7133,13 b' let'
7115 7133 sha1 = "8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559";
7116 7134 };
7117 7135 };
7118 "upath-1.1.0" = {
7136 "upath-1.1.2" = {
7119 7137 name = "upath";
7120 7138 packageName = "upath";
7121 version = "1.1.0";
7122 src = fetchurl {
7123 url = "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz";
7124 sha512 = "bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==";
7139 version = "1.1.2";
7140 src = fetchurl {
7141 url = "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz";
7142 sha512 = "kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==";
7125 7143 };
7126 7144 };
7127 7145 "upper-case-1.1.3" = {
@@ -7223,31 +7241,31 b' let'
7223 7241 sha512 = "yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==";
7224 7242 };
7225 7243 };
7226 "v8-compile-cache-2.0.2" = {
7244 "v8-compile-cache-2.0.3" = {
7227 7245 name = "v8-compile-cache";
7228 7246 packageName = "v8-compile-cache";
7229 version = "2.0.2";
7230 src = fetchurl {
7231 url = "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz";
7232 sha512 = "1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==";
7233 };
7234 };
7235 "v8flags-3.1.2" = {
7247 version = "2.0.3";
7248 src = fetchurl {
7249 url = "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz";
7250 sha512 = "CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==";
7251 };
7252 };
7253 "v8flags-3.1.3" = {
7236 7254 name = "v8flags";
7237 7255 packageName = "v8flags";
7238 version = "3.1.2";
7239 src = fetchurl {
7240 url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz";
7241 sha512 = "MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==";
7242 };
7243 };
7244 "vendors-1.0.2" = {
7256 version = "3.1.3";
7257 src = fetchurl {
7258 url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz";
7259 sha512 = "amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==";
7260 };
7261 };
7262 "vendors-1.0.3" = {
7245 7263 name = "vendors";
7246 7264 packageName = "vendors";
7247 version = "1.0.2";
7248 src = fetchurl {
7249 url = "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz";
7250 sha512 = "w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==";
7265 version = "1.0.3";
7266 src = fetchurl {
7267 url = "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz";
7268 sha512 = "fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==";
7251 7269 };
7252 7270 };
7253 7271 "verror-1.10.0" = {
@@ -7385,13 +7403,13 b' let'
7385 7403 sha1 = "b79669bb42ecb409f83d583cad52ca17eaa1643f";
7386 7404 };
7387 7405 };
7388 "worker-farm-1.6.0" = {
7406 "worker-farm-1.7.0" = {
7389 7407 name = "worker-farm";
7390 7408 packageName = "worker-farm";
7391 version = "1.6.0";
7392 src = fetchurl {
7393 url = "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz";
7394 sha512 = "6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==";
7409 version = "1.7.0";
7410 src = fetchurl {
7411 url = "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz";
7412 sha512 = "rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==";
7395 7413 };
7396 7414 };
7397 7415 "wrap-ansi-2.1.0" = {
@@ -7496,9 +7514,9 b' let'
7496 7514 sources."@polymer/paper-toast-3.0.1"
7497 7515 sources."@polymer/paper-toggle-button-3.0.1"
7498 7516 sources."@polymer/paper-tooltip-3.0.1"
7499 sources."@polymer/polymer-3.1.0"
7517 sources."@polymer/polymer-3.2.0"
7500 7518 sources."@types/clone-0.1.30"
7501 sources."@types/node-6.14.3"
7519 sources."@types/node-6.14.6"
7502 7520 sources."@types/parse5-2.2.34"
7503 7521 sources."@webassemblyjs/ast-1.7.10"
7504 7522 sources."@webassemblyjs/floating-point-hex-parser-1.7.10"
@@ -7518,8 +7536,8 b' let'
7518 7536 sources."@webassemblyjs/wasm-parser-1.7.10"
7519 7537 sources."@webassemblyjs/wast-parser-1.7.10"
7520 7538 sources."@webassemblyjs/wast-printer-1.7.10"
7521 sources."@webcomponents/shadycss-1.9.0"
7522 sources."@webcomponents/webcomponentsjs-2.2.7"
7539 sources."@webcomponents/shadycss-1.9.1"
7540 sources."@webcomponents/webcomponentsjs-2.2.10"
7523 7541 sources."@xtuc/ieee754-1.2.0"
7524 7542 sources."@xtuc/long-4.2.1"
7525 7543 sources."abbrev-1.1.1"
@@ -7564,7 +7582,7 b' let'
7564 7582 sources."asap-2.0.6"
7565 7583 sources."asn1-0.2.4"
7566 7584 sources."asn1.js-4.10.1"
7567 (sources."assert-1.4.1" // {
7585 (sources."assert-1.5.0" // {
7568 7586 dependencies = [
7569 7587 sources."inherits-2.0.1"
7570 7588 sources."util-0.10.3"
@@ -7574,7 +7592,7 b' let'
7574 7592 sources."assign-symbols-1.0.0"
7575 7593 sources."ast-types-0.9.6"
7576 7594 sources."async-0.1.22"
7577 sources."async-each-1.0.1"
7595 sources."async-each-1.0.3"
7578 7596 sources."asynckit-0.4.0"
7579 7597 sources."atob-2.1.2"
7580 7598 (sources."autoprefixer-6.7.7" // {
@@ -7696,8 +7714,8 b' let'
7696 7714 sources."base64-js-1.3.0"
7697 7715 sources."bcrypt-pbkdf-1.0.2"
7698 7716 sources."big.js-5.2.2"
7699 sources."binary-extensions-1.13.0"
7700 sources."bluebird-3.5.3"
7717 sources."binary-extensions-1.13.1"
7718 sources."bluebird-3.5.4"
7701 7719 sources."bn.js-4.11.8"
7702 7720 sources."boolbase-1.0.0"
7703 7721 sources."boom-2.10.1"
@@ -7721,7 +7739,7 b' let'
7721 7739 sources."builtin-status-codes-3.0.0"
7722 7740 (sources."cacache-10.0.4" // {
7723 7741 dependencies = [
7724 sources."glob-7.1.3"
7742 sources."glob-7.1.4"
7725 7743 sources."graceful-fs-4.1.15"
7726 7744 sources."lru-cache-4.1.5"
7727 7745 sources."minimatch-3.0.4"
@@ -7730,20 +7748,20 b' let'
7730 7748 })
7731 7749 sources."cache-base-1.0.1"
7732 7750 sources."camel-case-3.0.0"
7733 sources."camelcase-5.0.0"
7751 sources."camelcase-5.3.1"
7734 7752 (sources."caniuse-api-1.6.1" // {
7735 7753 dependencies = [
7736 7754 sources."browserslist-1.7.7"
7737 7755 ];
7738 7756 })
7739 sources."caniuse-db-1.0.30000939"
7740 sources."caniuse-lite-1.0.30000939"
7757 sources."caniuse-db-1.0.30000967"
7758 sources."caniuse-lite-1.0.30000967"
7741 7759 sources."caseless-0.12.0"
7742 7760 sources."center-align-0.1.3"
7743 7761 sources."chalk-0.5.1"
7744 (sources."chokidar-2.1.2" // {
7745 dependencies = [
7746 sources."is-glob-4.0.0"
7762 (sources."chokidar-2.1.5" // {
7763 dependencies = [
7764 sources."is-glob-4.0.1"
7747 7765 ];
7748 7766 })
7749 7767 sources."chownr-1.1.1"
@@ -7783,7 +7801,7 b' let'
7783 7801 })
7784 7802 (sources."cli-1.0.1" // {
7785 7803 dependencies = [
7786 sources."glob-7.1.3"
7804 sources."glob-7.1.4"
7787 7805 sources."minimatch-3.0.4"
7788 7806 ];
7789 7807 })
@@ -7806,10 +7824,10 b' let'
7806 7824 sources."color-string-0.3.0"
7807 7825 sources."colormin-1.1.2"
7808 7826 sources."colors-0.6.2"
7809 sources."combined-stream-1.0.7"
7827 sources."combined-stream-1.0.8"
7810 7828 sources."commander-2.14.1"
7811 7829 sources."commondir-1.0.1"
7812 sources."component-emitter-1.2.1"
7830 sources."component-emitter-1.3.0"
7813 7831 sources."concat-map-0.0.1"
7814 7832 (sources."concat-stream-1.6.2" // {
7815 7833 dependencies = [
@@ -7822,7 +7840,7 b' let'
7822 7840 sources."convert-source-map-1.6.0"
7823 7841 (sources."copy-concurrently-1.0.5" // {
7824 7842 dependencies = [
7825 sources."glob-7.1.3"
7843 sources."glob-7.1.4"
7826 7844 sources."minimatch-3.0.4"
7827 7845 sources."rimraf-2.6.3"
7828 7846 ];
@@ -7830,7 +7848,7 b' let'
7830 7848 sources."copy-descriptor-0.1.1"
7831 7849 (sources."copy-webpack-plugin-4.6.0" // {
7832 7850 dependencies = [
7833 sources."is-glob-4.0.0"
7851 sources."is-glob-4.0.1"
7834 7852 sources."minimatch-3.0.4"
7835 7853 ];
7836 7854 })
@@ -7896,6 +7914,7 b' let'
7896 7914 sources."domelementtype-1.3.1"
7897 7915 sources."domhandler-2.3.0"
7898 7916 sources."domutils-1.5.1"
7917 sources."dropzone-5.5.1"
7899 7918 (sources."duplexify-3.7.1" // {
7900 7919 dependencies = [
7901 7920 sources."readable-stream-2.3.6"
@@ -7903,7 +7922,7 b' let'
7903 7922 ];
7904 7923 })
7905 7924 sources."ecc-jsbn-0.1.2"
7906 sources."electron-to-chromium-1.3.113"
7925 sources."electron-to-chromium-1.3.133"
7907 7926 sources."elliptic-6.4.1"
7908 7927 sources."emojis-list-2.1.0"
7909 7928 sources."end-of-stream-1.4.1"
@@ -7918,7 +7937,7 b' let'
7918 7937 sources."es-to-primitive-1.2.0"
7919 7938 sources."es6-templates-0.2.3"
7920 7939 sources."escape-string-regexp-1.0.5"
7921 sources."eslint-scope-4.0.0"
7940 sources."eslint-scope-4.0.3"
7922 7941 sources."espree-3.5.4"
7923 7942 sources."esprima-1.0.4"
7924 7943 sources."esrecurse-4.2.1"
@@ -7982,7 +8001,7 b' let'
7982 8001 sources."minimatch-0.3.0"
7983 8002 ];
7984 8003 })
7985 sources."fined-1.1.1"
8004 sources."fined-1.2.0"
7986 8005 sources."flagged-respawn-1.0.1"
7987 8006 sources."flatten-1.0.2"
7988 8007 (sources."flush-write-stream-1.1.1" // {
@@ -8008,7 +8027,7 b' let'
8008 8027 ];
8009 8028 })
8010 8029 sources."fs.realpath-1.0.0"
8011 sources."fsevents-1.2.7"
8030 sources."fsevents-1.2.9"
8012 8031 sources."function-bind-1.1.1"
8013 8032 sources."gaze-0.5.2"
8014 8033 sources."get-caller-file-1.0.3"
@@ -8040,7 +8059,7 b' let'
8040 8059 sources."globals-9.18.0"
8041 8060 (sources."globby-7.1.1" // {
8042 8061 dependencies = [
8043 sources."glob-7.1.3"
8062 sources."glob-7.1.4"
8044 8063 sources."minimatch-3.0.4"
8045 8064 ];
8046 8065 })
@@ -8166,7 +8185,7 b' let'
8166 8185 sources."supports-color-5.5.0"
8167 8186 ];
8168 8187 })
8169 sources."ieee754-1.1.12"
8188 sources."ieee754-1.1.13"
8170 8189 sources."iferr-0.1.5"
8171 8190 sources."ignore-3.3.10"
8172 8191 sources."image-size-0.5.5"
@@ -8174,9 +8193,9 b' let'
8174 8193 dependencies = [
8175 8194 sources."find-up-3.0.0"
8176 8195 sources."locate-path-3.0.0"
8177 sources."p-limit-2.1.0"
8196 sources."p-limit-2.2.0"
8178 8197 sources."p-locate-3.0.0"
8179 sources."p-try-2.0.0"
8198 sources."p-try-2.2.0"
8180 8199 sources."pkg-dir-3.0.0"
8181 8200 ];
8182 8201 })
@@ -8229,7 +8248,7 b' let'
8229 8248 sources."js-yaml-2.0.5"
8230 8249 sources."jsbn-0.1.1"
8231 8250 sources."jsesc-1.3.0"
8232 (sources."jshint-2.10.1" // {
8251 (sources."jshint-2.10.2" // {
8233 8252 dependencies = [
8234 8253 sources."lodash-4.17.11"
8235 8254 sources."minimatch-3.0.4"
@@ -8280,7 +8299,7 b' let'
8280 8299 sources."mark.js-8.11.1"
8281 8300 sources."math-expression-evaluator-1.2.17"
8282 8301 sources."md5.js-1.3.5"
8283 sources."mem-4.1.0"
8302 sources."mem-4.3.0"
8284 8303 (sources."memory-fs-0.4.1" // {
8285 8304 dependencies = [
8286 8305 sources."readable-stream-2.3.6"
@@ -8290,9 +8309,9 b' let'
8290 8309 sources."micromatch-3.1.10"
8291 8310 sources."miller-rabin-4.0.1"
8292 8311 sources."mime-1.6.0"
8293 sources."mime-db-1.38.0"
8294 sources."mime-types-2.1.22"
8295 sources."mimic-fn-1.2.0"
8312 sources."mime-db-1.40.0"
8313 sources."mime-types-2.1.24"
8314 sources."mimic-fn-2.1.0"
8296 8315 sources."minimalistic-assert-1.0.1"
8297 8316 sources."minimalistic-crypto-utils-1.0.1"
8298 8317 sources."minimatch-0.2.14"
@@ -8309,18 +8328,18 b' let'
8309 8328 ];
8310 8329 })
8311 8330 sources."moment-2.24.0"
8312 sources."mousetrap-1.6.2"
8331 sources."mousetrap-1.6.3"
8313 8332 (sources."move-concurrently-1.0.1" // {
8314 8333 dependencies = [
8315 sources."glob-7.1.3"
8334 sources."glob-7.1.4"
8316 8335 sources."minimatch-3.0.4"
8317 8336 sources."rimraf-2.6.3"
8318 8337 ];
8319 8338 })
8320 8339 sources."ms-2.0.0"
8321 sources."nan-2.12.1"
8340 sources."nan-2.13.2"
8322 8341 sources."nanomatch-1.2.13"
8323 sources."neo-async-2.6.0"
8342 sources."neo-async-2.6.1"
8324 8343 sources."nice-try-1.0.5"
8325 8344 sources."no-case-2.3.2"
8326 8345 (sources."node-libs-browser-2.2.0" // {
@@ -8361,7 +8380,7 b' let'
8361 8380 sources."kind-of-3.2.2"
8362 8381 ];
8363 8382 })
8364 sources."object-keys-1.1.0"
8383 sources."object-keys-1.1.1"
8365 8384 sources."object-visit-1.0.1"
8366 8385 sources."object.defaults-1.1.0"
8367 8386 sources."object.getownpropertydescriptors-2.0.3"
@@ -8375,11 +8394,11 b' let'
8375 8394 sources."osenv-0.1.5"
8376 8395 sources."p-defer-1.0.0"
8377 8396 sources."p-finally-1.0.0"
8378 sources."p-is-promise-2.0.0"
8397 sources."p-is-promise-2.1.0"
8379 8398 sources."p-limit-1.3.0"
8380 8399 sources."p-locate-2.0.0"
8381 8400 sources."p-try-1.0.0"
8382 sources."pako-1.0.8"
8401 sources."pako-1.0.10"
8383 8402 (sources."parallel-transform-1.1.0" // {
8384 8403 dependencies = [
8385 8404 sources."readable-stream-2.3.6"
@@ -8582,7 +8601,7 b' let'
8582 8601 sources."request-2.81.0"
8583 8602 sources."require-directory-2.1.1"
8584 8603 sources."require-main-filename-1.0.1"
8585 sources."resolve-1.10.0"
8604 sources."resolve-1.10.1"
8586 8605 sources."resolve-cwd-2.0.0"
8587 8606 sources."resolve-dir-1.0.1"
8588 8607 sources."resolve-from-3.0.0"
@@ -8598,12 +8617,12 b' let'
8598 8617 sources."sax-1.2.4"
8599 8618 (sources."schema-utils-0.4.7" // {
8600 8619 dependencies = [
8601 sources."ajv-6.9.2"
8620 sources."ajv-6.10.0"
8602 8621 ];
8603 8622 })
8604 8623 sources."select-1.1.2"
8605 sources."semver-5.6.0"
8606 sources."serialize-javascript-1.6.1"
8624 sources."semver-5.7.0"
8625 sources."serialize-javascript-1.7.0"
8607 8626 sources."set-blocking-2.0.0"
8608 8627 (sources."set-value-2.0.0" // {
8609 8628 dependencies = [
@@ -8716,7 +8735,7 b' let'
8716 8735 sources."js-yaml-3.7.0"
8717 8736 ];
8718 8737 })
8719 sources."tapable-1.1.1"
8738 sources."tapable-1.1.3"
8720 8739 sources."through-2.3.8"
8721 8740 (sources."through2-2.0.5" // {
8722 8741 dependencies = [
@@ -8765,9 +8784,9 b' let'
8765 8784 sources."source-map-0.6.1"
8766 8785 ];
8767 8786 })
8768 (sources."uglify-js-3.4.9" // {
8769 dependencies = [
8770 sources."commander-2.17.1"
8787 (sources."uglify-js-3.4.10" // {
8788 dependencies = [
8789 sources."commander-2.19.0"
8771 8790 sources."source-map-0.6.1"
8772 8791 ];
8773 8792 })
@@ -8800,7 +8819,7 b' let'
8800 8819 sources."has-values-0.1.4"
8801 8820 ];
8802 8821 })
8803 sources."upath-1.1.0"
8822 sources."upath-1.1.2"
8804 8823 sources."upper-case-1.1.3"
8805 8824 (sources."uri-js-4.2.2" // {
8806 8825 dependencies = [
@@ -8819,9 +8838,9 b' let'
8819 8838 sources."util.promisify-1.0.0"
8820 8839 sources."utila-0.4.0"
8821 8840 sources."uuid-3.3.2"
8822 sources."v8-compile-cache-2.0.2"
8823 sources."v8flags-3.1.2"
8824 sources."vendors-1.0.2"
8841 sources."v8-compile-cache-2.0.3"
8842 sources."v8flags-3.1.3"
8843 sources."vendors-1.0.3"
8825 8844 (sources."verror-1.10.0" // {
8826 8845 dependencies = [
8827 8846 sources."assert-plus-1.0.0"
@@ -8836,7 +8855,7 b' let'
8836 8855 sources."waypoints-4.0.1"
8837 8856 (sources."webpack-4.23.1" // {
8838 8857 dependencies = [
8839 sources."ajv-6.9.2"
8858 sources."ajv-6.10.0"
8840 8859 ];
8841 8860 })
8842 8861 (sources."webpack-cli-3.1.2" // {
@@ -8876,7 +8895,7 b' let'
8876 8895 sources."which-module-2.0.0"
8877 8896 sources."window-size-0.1.0"
8878 8897 sources."wordwrap-0.0.2"
8879 sources."worker-farm-1.6.0"
8898 sources."worker-farm-1.7.0"
8880 8899 (sources."wrap-ansi-2.1.0" // {
8881 8900 dependencies = [
8882 8901 sources."ansi-regex-2.1.1"
@@ -8892,9 +8911,9 b' let'
8892 8911 dependencies = [
8893 8912 sources."find-up-3.0.0"
8894 8913 sources."locate-path-3.0.0"
8895 sources."p-limit-2.1.0"
8914 sources."p-limit-2.2.0"
8896 8915 sources."p-locate-3.0.0"
8897 sources."p-try-2.0.0"
8916 sources."p-try-2.2.0"
8898 8917 ];
8899 8918 })
8900 8919 sources."yargs-parser-11.1.1"
@@ -88,8 +88,8 b' self: super: {'
88 88 name = "authomatic-0.1.0.post1";
89 89 doCheck = false;
90 90 src = fetchurl {
91 url = "https://code.rhodecode.com/upstream/authomatic/archive/90a9ce60cc405ae8a2bf5c3713acd5d78579a04e.tar.gz?md5=3c68720a1322b25254009518d1ff6801";
92 sha256 = "1cgk0a86sbsjbri06gf5z5l4npwkjdxw6fdnwl4vvfmxs2sx9yxw";
91 url = "https://code.rhodecode.com/upstream/authomatic/artifacts/download/0-4fe9c041-a567-4f84-be4c-7efa2a606d3c.tar.gz?md5=f6bdc3c769688212db68233e8d2b0383";
92 sha256 = "0pc716mva0ym6xd8jwzjbjp8dqxy9069wwwv2aqwb8lyhl4757ab";
93 93 };
94 94 meta = {
95 95 license = [ pkgs.lib.licenses.mit ];
@@ -277,8 +277,8 b' self: super: {'
277 277 self."six"
278 278 ];
279 279 src = fetchurl {
280 url = "https://code.rhodecode.com/upstream/configobj/archive/a11ff0a0bd4fbda9e3a91267e720f88329efb4a6.tar.gz?md5=9916c524ea11a6c418217af6b28d4b3c";
281 sha256 = "1hhcxirwvg58grlfr177b3awhbq8hlx1l3lh69ifl1ki7lfd1s1x";
280 url = "https://code.rhodecode.com/upstream/configobj/artifacts/download/0-012de99a-b1e1-4f64-a5c0-07a98a41b324.tar.gz?md5=6a513f51fe04b2c18cf84c1395a7c626";
281 sha256 = "0kqfrdfr14mw8yd8qwq14dv2xghpkjmd3yjsy8dfcbvpcc17xnxp";
282 282 };
283 283 meta = {
284 284 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -442,11 +442,11 b' self: super: {'
442 442 };
443 443 };
444 444 "ecdsa" = super.buildPythonPackage {
445 name = "ecdsa-0.13";
445 name = "ecdsa-0.13.2";
446 446 doCheck = false;
447 447 src = fetchurl {
448 url = "https://files.pythonhosted.org/packages/f9/e5/99ebb176e47f150ac115ffeda5fedb6a3dbb3c00c74a59fd84ddf12f5857/ecdsa-0.13.tar.gz";
449 sha256 = "1yj31j0asmrx4an9xvsaj2icdmzy6pw0glfpqrrkrphwdpi1xkv4";
448 url = "https://files.pythonhosted.org/packages/51/76/139bf6e9b7b6684d5891212cdbd9e0739f2bfc03f380a1a6ffa700f392ac/ecdsa-0.13.2.tar.gz";
449 sha256 = "116qaq7bh4lcynzi613960jhsnn19v0kmsqwahiwjfj14gx4y0sw";
450 450 };
451 451 meta = {
452 452 license = [ pkgs.lib.licenses.mit ];
@@ -534,8 +534,8 b' self: super: {'
534 534 self."configparser"
535 535 ];
536 536 src = fetchurl {
537 url = "https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313";
538 sha256 = "0bihrdp8ahsys437kxdhk52gz6kib8rxjv71i93wkw7594fcaxll";
537 url = "https://code.rhodecode.com/upstream/entrypoints/artifacts/download/0-8e9ee9e4-c4db-409c-b07e-81568fd1832d.tar.gz?md5=3a027b8ff1d257b91fe257de6c43357d";
538 sha256 = "0qih72n2myclanplqipqxpgpj9d2yhff1pz5d02zq1cfqyd173w5";
539 539 };
540 540 meta = {
541 541 license = [ pkgs.lib.licenses.mit ];
@@ -845,14 +845,14 b' self: super: {'
845 845 };
846 846 };
847 847 "jupyter-core" = super.buildPythonPackage {
848 name = "jupyter-core-4.4.0";
848 name = "jupyter-core-4.5.0";
849 849 doCheck = false;
850 850 propagatedBuildInputs = [
851 851 self."traitlets"
852 852 ];
853 853 src = fetchurl {
854 url = "https://files.pythonhosted.org/packages/b6/2d/2804f4de3a95583f65e5dcb4d7c8c7183124882323758996e867f47e72af/jupyter_core-4.4.0.tar.gz";
855 sha256 = "1dy083rarba8prn9f9srxq3c7n7vyql02ycrqq306c40lr57aw5s";
854 url = "https://files.pythonhosted.org/packages/4a/de/ff4ca734656d17ebe0450807b59d728f45277e2e7f4b82bc9aae6cb82961/jupyter_core-4.5.0.tar.gz";
855 sha256 = "1xr4pbghwk5hayn5wwnhb7z95380r45p79gf5if5pi1akwg7qvic";
856 856 };
857 857 meta = {
858 858 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -1092,15 +1092,15 b' self: super: {'
1092 1092 };
1093 1093 };
1094 1094 "pathlib2" = super.buildPythonPackage {
1095 name = "pathlib2-2.3.3";
1095 name = "pathlib2-2.3.4";
1096 1096 doCheck = false;
1097 1097 propagatedBuildInputs = [
1098 1098 self."six"
1099 1099 self."scandir"
1100 1100 ];
1101 1101 src = fetchurl {
1102 url = "https://files.pythonhosted.org/packages/bf/d7/a2568f4596b75d2c6e2b4094a7e64f620decc7887f69a1f2811931ea15b9/pathlib2-2.3.3.tar.gz";
1103 sha256 = "0hpp92vqqgcd8h92msm9slv161b1q160igjwnkf2ag6cx0c96695";
1102 url = "https://files.pythonhosted.org/packages/b5/f4/9c7cc726ece2498b6c8b62d3262aa43f59039b953fe23c9964ac5e18d40b/pathlib2-2.3.4.tar.gz";
1103 sha256 = "1y0f9rkm1924zrc5dn4bwxlhgdkbml82lkcc28l5rgmr7d918q24";
1104 1104 };
1105 1105 meta = {
1106 1106 license = [ pkgs.lib.licenses.mit ];
@@ -1212,11 +1212,11 b' self: super: {'
1212 1212 };
1213 1213 };
1214 1214 "psycopg2" = super.buildPythonPackage {
1215 name = "psycopg2-2.8.2";
1215 name = "psycopg2-2.8.3";
1216 1216 doCheck = false;
1217 1217 src = fetchurl {
1218 url = "https://files.pythonhosted.org/packages/23/7e/93c325482c328619870b6cd09370f6dbe1148283daca65115cd63642e60f/psycopg2-2.8.2.tar.gz";
1219 sha256 = "122mn2z3r0zgs8jyq682jjjr6vq5690qmxqf22gj6g41dwdz5b2w";
1218 url = "https://files.pythonhosted.org/packages/5c/1c/6997288da181277a0c29bc39a5f9143ff20b8c99f2a7d059cfb55163e165/psycopg2-2.8.3.tar.gz";
1219 sha256 = "0ms4kx0p5n281l89awccix4d05ybmdngnjjpi9jbzd0rhf1nwyl9";
1220 1220 };
1221 1221 meta = {
1222 1222 license = [ pkgs.lib.licenses.zpl21 { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "LGPL with exceptions or ZPL"; } ];
@@ -1329,11 +1329,11 b' self: super: {'
1329 1329 };
1330 1330 };
1331 1331 "pygments" = super.buildPythonPackage {
1332 name = "pygments-2.3.1";
1332 name = "pygments-2.4.2";
1333 1333 doCheck = false;
1334 1334 src = fetchurl {
1335 url = "https://files.pythonhosted.org/packages/64/69/413708eaf3a64a6abb8972644e0f20891a55e621c6759e2c3f3891e05d63/Pygments-2.3.1.tar.gz";
1336 sha256 = "0ji87g09jph8jqcvclgb02qvxasdnr9pzvk90rl66d90yqcxmyjz";
1335 url = "https://files.pythonhosted.org/packages/7e/ae/26808275fc76bf2832deb10d3a3ed3107bc4de01b85dcccbe525f2cd6d1e/Pygments-2.4.2.tar.gz";
1336 sha256 = "15v2sqm5g12bqa0c7wikfh9ck2nl97ayizy1hpqhmws5gqalq748";
1337 1337 };
1338 1338 meta = {
1339 1339 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -1395,21 +1395,6 b' self: super: {'
1395 1395 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1396 1396 };
1397 1397 };
1398 "pyramid-beaker" = super.buildPythonPackage {
1399 name = "pyramid-beaker-0.8";
1400 doCheck = false;
1401 propagatedBuildInputs = [
1402 self."pyramid"
1403 self."beaker"
1404 ];
1405 src = fetchurl {
1406 url = "https://files.pythonhosted.org/packages/d9/6e/b85426e00fd3d57f4545f74e1c3828552d8700f13ededeef9233f7bca8be/pyramid_beaker-0.8.tar.gz";
1407 sha256 = "0hflx3qkcdml1mwpq53sz46s7jickpfn0zy0ns2c7j445j66bp3p";
1408 };
1409 meta = {
1410 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1411 };
1412 };
1413 1398 "pyramid-debugtoolbar" = super.buildPythonPackage {
1414 1399 name = "pyramid-debugtoolbar-4.5";
1415 1400 doCheck = false;
@@ -1783,6 +1768,7 b' self: super: {'
1783 1768 self."msgpack-python"
1784 1769 self."pyotp"
1785 1770 self."packaging"
1771 self."pathlib2"
1786 1772 self."paste"
1787 1773 self."pastedeploy"
1788 1774 self."pastescript"
@@ -1793,7 +1779,6 b' self: super: {'
1793 1779 self."pycrypto"
1794 1780 self."pygments"
1795 1781 self."pyparsing"
1796 self."pyramid-beaker"
1797 1782 self."pyramid-debugtoolbar"
1798 1783 self."pyramid-mako"
1799 1784 self."pyramid"
@@ -1886,8 +1871,8 b' self: super: {'
1886 1871 self."elasticsearch1-dsl"
1887 1872 ];
1888 1873 src = fetchurl {
1889 url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v1.2.1.tar.gz?md5=25bc2f7de1da318e547236d3fb463d28";
1890 sha256 = "1k8l3s4mvshza1zay6dfxprq54fyb5dc85dqdva9wa3f466y0adk";
1874 url = "https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-10ac93f4-bb7d-4b97-baea-68110743dd5a.tar.gz?md5=962dc77c06aceee62282b98d33149661";
1875 sha256 = "1vfhgf46inbx7jvlfx4fdzh3vz7lh37r291gzb5hx447pfm3qllg";
1891 1876 };
1892 1877 meta = {
1893 1878 license = [ { fullName = "Apache 2.0 and Proprietary"; } ];
@@ -2001,25 +1986,25 b' self: super: {'
2001 1986 };
2002 1987 };
2003 1988 "subprocess32" = super.buildPythonPackage {
2004 name = "subprocess32-3.5.3";
1989 name = "subprocess32-3.5.4";
2005 1990 doCheck = false;
2006 1991 src = fetchurl {
2007 url = "https://files.pythonhosted.org/packages/be/2b/beeba583e9877e64db10b52a96915afc0feabf7144dcbf2a0d0ea68bf73d/subprocess32-3.5.3.tar.gz";
2008 sha256 = "1hr5fan8i719hmlmz73hf8rhq74014w07d8ryg7krvvf6692kj3b";
1992 url = "https://files.pythonhosted.org/packages/32/c8/564be4d12629b912ea431f1a50eb8b3b9d00f1a0b1ceff17f266be190007/subprocess32-3.5.4.tar.gz";
1993 sha256 = "17f7mvwx2271s1wrl0qac3wjqqnrqag866zs3qc8v5wp0k43fagb";
2009 1994 };
2010 1995 meta = {
2011 1996 license = [ pkgs.lib.licenses.psfl ];
2012 1997 };
2013 1998 };
2014 1999 "supervisor" = super.buildPythonPackage {
2015 name = "supervisor-4.0.2";
2000 name = "supervisor-4.0.3";
2016 2001 doCheck = false;
2017 2002 propagatedBuildInputs = [
2018 2003 self."meld3"
2019 2004 ];
2020 2005 src = fetchurl {
2021 url = "https://files.pythonhosted.org/packages/cb/02/95953c98a770803e42009f18c2eb361bc035ab6fb3cbb442ffcc94387eac/supervisor-4.0.2.tar.gz";
2022 sha256 = "0xg5c41wd51wnf2ihc47gwkwjf29zq2q44lcwx8di2gvliyla12n";
2006 url = "https://files.pythonhosted.org/packages/97/48/f38bf70bd9282d1a18d591616557cc1a77a1c627d57dff66ead65c891dc8/supervisor-4.0.3.tar.gz";
2007 sha256 = "17hla7mx6w5m5jzkkjxgqa8wpswqmfhbhf49f692hw78fg0ans7p";
2023 2008 };
2024 2009 meta = {
2025 2010 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
@@ -2159,11 +2144,11 b' self: super: {'
2159 2144 };
2160 2145 };
2161 2146 "waitress" = super.buildPythonPackage {
2162 name = "waitress-1.1.0";
2147 name = "waitress-1.3.0";
2163 2148 doCheck = false;
2164 2149 src = fetchurl {
2165 url = "https://files.pythonhosted.org/packages/3c/68/1c10dd5c556872ceebe88483b0436140048d39de83a84a06a8baa8136f4f/waitress-1.1.0.tar.gz";
2166 sha256 = "1a85gyji0kajc3p0s1pwwfm06w4wfxjkvvl4rnrz3h164kbd6g6k";
2150 url = "https://files.pythonhosted.org/packages/43/50/9890471320d5ad22761ae46661cf745f487b1c8c4ec49352b99e1078b970/waitress-1.3.0.tar.gz";
2151 sha256 = "09j5dzbbcxib7vdskhx39s1qsydlr4n2p2png71d7mjnr9pnwajf";
2167 2152 };
2168 2153 meta = {
2169 2154 license = [ pkgs.lib.licenses.zpl21 ];
@@ -2,7 +2,7 b''
2 2
3 3 amqp==2.3.1
4 4 # not released authomatic that has updated some oauth providers
5 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
6 6
7 7 babel==1.3
8 8 beaker==1.9.1
@@ -12,7 +12,7 b' channelstream==0.5.2'
12 12 click==7.0
13 13 colander==1.7.0
14 14 # our custom configobj
15 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
16 16 cssselect==1.0.3
17 17 cryptography==2.6.1
18 18 decorator==4.1.2
@@ -34,6 +34,7 b' markupsafe==1.1.0'
34 34 msgpack-python==0.5.6
35 35 pyotp==2.2.7
36 36 packaging==15.2
37 pathlib2==2.3.4
37 38 paste==3.0.8
38 39 pastedeploy==2.0.1
39 40 pastescript==3.1.0
@@ -42,9 +43,8 b' psutil==5.5.1'
42 43 py-bcrypt==0.4
43 44 pycurl==7.43.0.2
44 45 pycrypto==2.6.1
45 pygments==2.3.1
46 pygments==2.4.2
46 47 pyparsing==2.3.0
47 pyramid-beaker==0.8
48 48 pyramid-debugtoolbar==4.5.0
49 49 pyramid-mako==1.0.2
50 50 pyramid==1.10.4
@@ -66,8 +66,8 b' simplejson==3.16.0'
66 66 six==1.11.0
67 67 sqlalchemy==1.1.18
68 68 sshpubkeys==3.1.0
69 subprocess32==3.5.3
70 supervisor==4.0.2
69 subprocess32==3.5.4
70 supervisor==4.0.3
71 71 translationstring==1.3
72 72 urllib3==1.24.1
73 73 urlobject==2.4.3
@@ -87,11 +87,11 b' zope.interface==4.6.0'
87 87 mysql-python==1.2.5
88 88 pymysql==0.8.1
89 89 pysqlite==2.8.3
90 psycopg2==2.8.2
90 psycopg2==2.8.3
91 91
92 92 # IPYTHON RENDERING
93 93 # entrypoints backport, pypi version doesn't support egg installs
94 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
95 95 nbconvert==5.3.1
96 96 nbformat==4.4.0
97 97 jupyter_client==5.0.0
@@ -105,14 +105,14 b' bumpversion==0.5.3'
105 105 gevent==1.4.0
106 106 greenlet==0.4.15
107 107 gunicorn==19.9.0
108 waitress==1.1.0
108 waitress==1.3.0
109 109
110 110 ## debug
111 111 ipdb==0.12.0
112 112 ipython==5.1.0
113 113
114 114 ## rhodecode-tools, special case
115 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
116 116
117 117 ## appenlight
118 118 appenlight-client==0.6.26
@@ -5,15 +5,15 b' attrs==18.2.0'
5 5 billiard==3.5.0.3
6 6 chameleon==2.24
7 7 cffi==1.12.2
8 ecdsa==0.13
8 ecdsa==0.13.2
9 9 hupper==1.6.1
10 10 gnureadline==6.3.8
11 11 jinja2==2.9.6
12 12 jsonschema==2.6.0
13 pathlib2==2.3.3
14 13 pyramid-jinja2==2.7
14 pluggy==0.11.0
15 15 setproctitle==1.1.10
16 16 scandir==1.10.0
17 17 tempita==0.5.2
18 18 vine==1.3.0
19 configparser==3.7.4 No newline at end of file
19 configparser==3.7.4
@@ -45,7 +45,7 b' PYRAMID_SETTINGS = {}'
45 45 EXTENSIONS = {}
46 46
47 47 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
48 __dbversion__ = 97 # defines current db version for migrations
48 __dbversion__ = 98 # defines current db version for migrations
49 49 __platform__ = platform.system()
50 50 __license__ = 'AGPLv3, and Commercial License'
51 51 __author__ = 'RhodeCode GmbH'
@@ -37,11 +37,11 b' class TestCommentCommit(object):'
37 37 assert_error(id_, expected, given=response.body)
38 38
39 39 @pytest.mark.parametrize("commit_id, expected_err", [
40 ('abcabca', {'hg': 'Commit {commit} does not exist for {repo}',
41 'git': '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}`',
42 42 'svn': 'Commit id {commit} not understood.'}),
43 ('idontexist', {'hg': 'Commit {commit} does not exist for {repo}',
44 'git': '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}`',
45 45 'svn': 'Commit id {commit} not understood.'}),
46 46 ])
47 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 54 expected_err = expected_err[backend.alias]
55 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 57 assert_error(id_, expected_err, given=response.body)
58 58
59 59 @pytest.mark.parametrize("status_change, message, commit_id", [
@@ -44,6 +44,7 b' class TestGetRepo(object):'
44 44 self, apikey_attr, expect_secrets, cache_param, backend,
45 45 user_util):
46 46 repo = backend.create_repo()
47 repo_id = repo.repo_id
47 48 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
48 49 group = user_util.create_user_group(members=[usr])
49 50 user_util.grant_user_group_permission_to_repo(
@@ -64,6 +65,8 b' class TestGetRepo(object):'
64 65 permissions = expected_permissions(repo)
65 66
66 67 followers = []
68
69 repo = RepoModel().get(repo_id)
67 70 for user in repo.followers:
68 71 followers.append(user.user.get_api_data(
69 72 include_secrets=expect_secrets))
@@ -84,6 +87,7 b' class TestGetRepo(object):'
84 87 # TODO: Depending on which tests are running before this one, we
85 88 # start with a different number of permissions in the database.
86 89 repo = RepoModel().get_by_repo_name(backend.repo_name)
90 repo_id = repo.repo_id
87 91 permission_count = len(repo.repo_to_perm)
88 92
89 93 RepoModel().grant_user_permission(repo=backend.repo_name,
@@ -102,6 +106,8 b' class TestGetRepo(object):'
102 106 permissions = expected_permissions(repo)
103 107
104 108 followers = []
109
110 repo = RepoModel().get(repo_id)
105 111 for user in repo.followers:
106 112 followers.append(user.user.get_api_data())
107 113
@@ -444,7 +444,7 b' def get_repo_nodes(request, apiuser, rep'
444 444 result: [
445 445 {
446 446 "binary": false,
447 "content": "File line\nLine2\n",
447 "content": "File line",
448 448 "extension": "md",
449 449 "lines": 2,
450 450 "md5": "059fa5d29b19c0657e384749480f6422",
@@ -529,6 +529,7 b' def get_repo_file(request, apiuser, repo'
529 529 :param cache: Use internal caches for fetching files. If disabled fetching
530 530 files is slower but more memory efficient
531 531 :type cache: Optional(bool)
532
532 533 Example output:
533 534
534 535 .. code-block:: bash
@@ -168,6 +168,28 b' class BaseAppView(object):'
168 168 from rhodecode.lib.base import attach_context_attributes
169 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 193 return c
172 194
173 195 def _get_template_context(self, tmpl_args, **kwargs):
@@ -215,12 +237,17 b' class RepoAppView(BaseAppView):'
215 237 c.rhodecode_db_repo = self.db_repo
216 238 c.repo_name = self.db_repo_name
217 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 242 self.path_filter = PathFilter(None)
219 243
220 244 c.repository_requirements_missing = {}
221 245 try:
222 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 251 path_perms = self.rhodecode_vcs_repo.get_path_permissions(
225 252 c.auth_user.username)
226 253 self.path_filter = PathFilter(path_perms)
@@ -85,8 +85,6 b' class NavigationRegistry(object):'
85 85 'admin_settings_hooks'),
86 86 NavEntry('search', _('Full Text Search'),
87 87 'admin_settings_search'),
88 NavEntry('integrations', _('Integrations'),
89 'global_integrations_home'),
90 88 NavEntry('system', _('System Info'),
91 89 'admin_settings_system'),
92 90 NavEntry('exceptions', _('Exceptions Tracker'),
@@ -46,10 +46,10 b' def route_path(name, params=None, **kwar'
46 46
47 47 class TestAdminMainView(TestController):
48 48
49 def test_redirect_admin_home(self):
49 def test_access_admin_home(self):
50 50 self.log_user()
51 response = self.app.get(route_path('admin_home'), status=302)
52 assert response.location.endswith('/audit_logs')
51 response = self.app.get(route_path('admin_home'), status=200)
52 response.mustcontain("Administration area")
53 53
54 54 def test_redirect_pull_request_view(self, view):
55 55 self.log_user()
@@ -20,12 +20,12 b''
20 20
21 21 import logging
22 22
23 from pyramid.httpexceptions import HTTPFound
23 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
24 24 from pyramid.view import view_config
25 25
26 26 from rhodecode.apps._base import BaseAppView
27 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 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 35 class AdminMainView(BaseAppView):
36 def load_default_context(self):
37 c = self._get_local_tmpl_context()
38 return c
36 39
37 40 @LoginRequired()
38 @HasPermissionAllDecorator('hg.admin')
41 @NotAnonymous()
39 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 45 def admin_main(self):
42 # redirect _admin to audit logs...
43 raise HTTPFound(h.route_path('admin_audit_logs'))
46 c = self.load_default_context()
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 54 @LoginRequired()
46 55 @view_config(route_name='pull_requests_global_0', request_method='GET')
@@ -49,8 +58,7 b' class AdminMainView(BaseAppView):'
49 58 def pull_requests(self):
50 59 """
51 60 Global redirect for Pull Requests
52
53 :param pull_request_id: id of pull requests in the system
61 pull_request_id: id of pull requests in the system
54 62 """
55 63
56 64 pull_request = PullRequest.get_or_404(
@@ -38,19 +38,18 b' class LocalFileStorage(object):'
38 38 """
39 39 Resolves a unique name and the correct path. If a filename
40 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 43 :param name: base name of file
44 44 :param directory: absolute directory path
45 45 """
46 46
47 basename, ext = os.path.splitext(name)
48 47 counter = 0
49 48 while True:
50 name = '%s-%d%s' % (basename, counter, ext)
49 name = '%d-%s' % (counter, name)
51 50
52 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 53 sub_store_path = os.path.join(directory, sub_store)
55 54 if not os.path.exists(sub_store_path):
56 55 os.makedirs(sub_store_path)
@@ -209,3 +208,16 b' class LocalFileStorage(object):'
209 208 filename = os.path.join(directory, filename)
210 209
211 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 21 import pytest
22 22
23 23 from rhodecode.lib.ext_json import json
24 from rhodecode.model.db import Session, FileStore
24 25 from rhodecode.tests import TestController
25 26 from rhodecode.apps.file_store import utils, config_keys
26 27
@@ -46,9 +47,12 b' class TestFileStoreViews(TestController)'
46 47 ('abcde-0.exe', "1234567", True),
47 48 ('abcde-0.jpg', "xxxxx", False),
48 49 ])
49 def test_get_files_from_store(self, fid, content, exists, tmpdir):
50 self.log_user()
50 def test_get_files_from_store(self, fid, content, exists, tmpdir, user_util):
51 user = self.log_user()
52 user_id = user['user_id']
53 repo_id = user_util.create_repo().repo_id
51 54 store_path = self.app._pyramid_settings[config_keys.store_path]
55 store_uid = fid
52 56
53 57 if exists:
54 58 status = 200
@@ -58,17 +62,28 b' class TestFileStoreViews(TestController)'
58 62 f.write(content)
59 63
60 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 78 else:
64 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 83 if exists:
69 84 assert response.text == content
70 file_store_path = os.path.dirname(store.resolve_name(fid, store_path)[1])
71 metadata_file = os.path.join(file_store_path, fid + '.meta')
85 file_store_path = os.path.dirname(store.resolve_name(store_uid, store_path)[1])
86 metadata_file = os.path.join(file_store_path, store_uid + '.meta')
72 87 assert os.path.exists(metadata_file)
73 88 with open(metadata_file, 'rb') as f:
74 89 json_data = json.loads(f.read())
@@ -19,9 +19,10 b''
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 import os
23 22 import uuid
24 23
24 import pathlib2
25
25 26
26 27 def get_file_storage(settings):
27 28 from rhodecode.apps.file_store.local_store import LocalFileStorage
@@ -30,6 +31,11 b' def get_file_storage(settings):'
30 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 39 def uid_filename(filename, randomized=True):
34 40 """
35 41 Generates a randomized or stable (uuid) filename,
@@ -38,7 +44,8 b' def uid_filename(filename, randomized=Tr'
38 44 :param filename: the original filename
39 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 49 if randomized:
43 50 uid = uuid.uuid4()
44 51 else:
@@ -30,7 +30,7 b' from rhodecode.apps.file_store.exception'
30 30
31 31 from rhodecode.lib import helpers as h
32 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 34 from rhodecode.model.db import Session, FileStore
35 35
36 36 log = logging.getLogger(__name__)
@@ -68,7 +68,7 b' class FileStoreView(BaseAppView):'
68 68 'user_id': self._rhodecode_user.user_id,
69 69 'ip': self._rhodecode_user.ip_addr}}
70 70 try:
71 store_fid, metadata = self.storage.save_file(
71 store_uid, metadata = self.storage.save_file(
72 72 file_obj.file, filename, extra_metadata=metadata)
73 73 except FileNotAllowedException:
74 74 return {'store_fid': None,
@@ -82,7 +82,7 b' class FileStoreView(BaseAppView):'
82 82
83 83 try:
84 84 entry = FileStore.create(
85 file_uid=store_fid, filename=metadata["filename"],
85 file_uid=store_uid, filename=metadata["filename"],
86 86 file_hash=metadata["sha256"], file_size=metadata["size"],
87 87 file_description='upload attachment',
88 88 check_acl=False, user_id=self._rhodecode_user.user_id
@@ -96,8 +96,8 b' class FileStoreView(BaseAppView):'
96 96 'access_path': None,
97 97 'error': 'File {} failed to store in DB.'.format(filename)}
98 98
99 return {'store_fid': store_fid,
100 'access_path': h.route_path('download_file', fid=store_fid)}
99 return {'store_fid': store_uid,
100 'access_path': h.route_path('download_file', fid=store_uid)}
101 101
102 102 @view_config(route_name='download_file')
103 103 def download_file(self):
@@ -109,6 +109,35 b' class FileStoreView(BaseAppView):'
109 109 log.debug('File with FID:%s not found in the store', file_uid)
110 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 141 FileStore.bump_access_counter(file_uid)
113 142
114 143 file_path = self.storage.store_path(file_uid)
@@ -68,6 +68,10 b' def includeme(config):'
68 68 pattern='/_markup_preview')
69 69
70 70 config.add_route(
71 name='file_preview',
72 pattern='/_file_preview')
73
74 config.add_route(
71 75 name='store_user_session_value',
72 76 pattern='/_store_session_attr')
73 77
@@ -27,11 +27,12 b' from pyramid.view import view_config'
27 27 from rhodecode.apps._base import BaseAppView
28 28 from rhodecode.lib import helpers as h
29 29 from rhodecode.lib.auth import (
30 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator,
31 CSRFRequired)
30 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator, CSRFRequired)
31 from rhodecode.lib.codeblocks import filenode_as_lines_tokens
32 32 from rhodecode.lib.index import searcher_from_config
33 33 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
34 34 from rhodecode.lib.ext_json import json
35 from rhodecode.lib.vcs.nodes import FileNode
35 36 from rhodecode.model.db import (
36 37 func, true, or_, case, in_filter_generator, Repository, RepoGroup, User, UserGroup)
37 38 from rhodecode.model.repo import RepoModel
@@ -442,12 +443,14 b' class HomeView(BaseAppView):'
442 443 def query_modifier():
443 444 qry = query
444 445 return {'q': qry, 'type': 'content'}
445 label = u'File search for `{}` in this repository.'.format(query)
446
447 label = u'File search for `{}`'.format(h.escape(query))
446 448 file_qry = {
447 449 'id': -10,
448 450 'value': query,
449 451 'value_display': label,
450 452 'type': 'search',
453 'subtype': 'repo',
451 454 'url': h.route_path('search_repo',
452 455 repo_name=repo_name,
453 456 _query=query_modifier())
@@ -458,18 +461,19 b' class HomeView(BaseAppView):'
458 461 qry = query
459 462 return {'q': qry, 'type': 'commit'}
460 463
461 label = u'Commit search for `{}` in this repository.'.format(query)
464 label = u'Commit search for `{}`'.format(h.escape(query))
462 465 commit_qry = {
463 466 'id': -20,
464 467 'value': query,
465 468 'value_display': label,
466 469 'type': 'search',
470 'subtype': 'repo',
467 471 'url': h.route_path('search_repo',
468 472 repo_name=repo_name,
469 473 _query=query_modifier())
470 474 }
471 475
472 if repo_context in ['commit', 'changelog']:
476 if repo_context in ['commit', 'commits']:
473 477 queries.extend([commit_qry, file_qry])
474 478 elif repo_context in ['files', 'summary']:
475 479 queries.extend([file_qry, commit_qry])
@@ -482,12 +486,13 b' class HomeView(BaseAppView):'
482 486 qry = query
483 487 return {'q': qry, 'type': 'content'}
484 488
485 label = u'File search for `{}` in this repository group'.format(query)
489 label = u'File search for `{}`'.format(query)
486 490 file_qry = {
487 491 'id': -30,
488 492 'value': query,
489 493 'value_display': label,
490 494 'type': 'search',
495 'subtype': 'repo_group',
491 496 'url': h.route_path('search_repo_group',
492 497 repo_group_name=repo_group_name,
493 498 _query=query_modifier())
@@ -498,18 +503,19 b' class HomeView(BaseAppView):'
498 503 qry = query
499 504 return {'q': qry, 'type': 'commit'}
500 505
501 label = u'Commit search for `{}` in this repository group'.format(query)
506 label = u'Commit search for `{}`'.format(query)
502 507 commit_qry = {
503 508 'id': -40,
504 509 'value': query,
505 510 'value_display': label,
506 511 'type': 'search',
512 'subtype': 'repo_group',
507 513 'url': h.route_path('search_repo_group',
508 514 repo_group_name=repo_group_name,
509 515 _query=query_modifier())
510 516 }
511 517
512 if repo_context in ['commit', 'changelog']:
518 if repo_context in ['commit', 'commits']:
513 519 queries.extend([commit_qry, file_qry])
514 520 elif repo_context in ['files', 'summary']:
515 521 queries.extend([file_qry, commit_qry])
@@ -524,6 +530,7 b' class HomeView(BaseAppView):'
524 530 'value': query,
525 531 'value_display': u'File search for: `{}`'.format(query),
526 532 'type': 'search',
533 'subtype': 'global',
527 534 'url': h.route_path('search',
528 535 _query={'q': query, 'type': 'content'})
529 536 })
@@ -533,6 +540,7 b' class HomeView(BaseAppView):'
533 540 'value': query,
534 541 'value_display': u'Commit search for: `{}`'.format(query),
535 542 'type': 'search',
543 'subtype': 'global',
536 544 'url': h.route_path('search',
537 545 _query={'q': query, 'type': 'commit'})
538 546 })
@@ -703,8 +711,11 b' class HomeView(BaseAppView):'
703 711 def repo_group_main_page(self):
704 712 c = self.load_default_context()
705 713 c.repo_group = self.request.db_repo_group
706 repo_data, repo_group_data = self._get_groups_and_repos(
707 c.repo_group.group_id)
714 repo_data, repo_group_data = self._get_groups_and_repos(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()
708 719
709 720 # json used to render the grids
710 721 c.repos_data = json.dumps(repo_data)
@@ -733,6 +744,34 b' class HomeView(BaseAppView):'
733 744 @LoginRequired()
734 745 @CSRFRequired()
735 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(
736 775 route_name='store_user_session_value', request_method='POST',
737 776 renderer='string', xhr=True)
738 777 def store_user_session_attr(self):
@@ -743,4 +782,4 b' class HomeView(BaseAppView):'
743 782 if existing_value != val:
744 783 self.request.session[key] = val
745 784
746 return 'stored:{}'.format(key)
785 return 'stored:{}:{}'.format(key, val)
@@ -31,12 +31,12 b' from pyramid.renderers import render'
31 31
32 32 from rhodecode.apps._base import BaseAppView
33 33 from rhodecode.model.db import (
34 or_, joinedload, UserLog, UserFollowing, User, UserApiKeys)
34 or_, joinedload, Repository, UserLog, UserFollowing, User, UserApiKeys)
35 35 from rhodecode.model.meta import Session
36 36 import rhodecode.lib.helpers as h
37 37 from rhodecode.lib.helpers import Page
38 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 40 from rhodecode.lib.utils2 import safe_int, AttributeDict, md5_safe
41 41 from rhodecode.model.scm import ScmModel
42 42
@@ -153,7 +153,7 b' class JournalView(BaseAppView):'
153 153 desc = action_extra()
154 154 _url = h.route_url('home')
155 155 if entry.repository is not None:
156 _url = h.route_url('repo_changelog',
156 _url = h.route_url('repo_commits',
157 157 repo_name=entry.repository.repo_name)
158 158
159 159 feed.add_item(
@@ -199,7 +199,7 b' class JournalView(BaseAppView):'
199 199 desc = action_extra()
200 200 _url = h.route_url('home')
201 201 if entry.repository is not None:
202 _url = h.route_url('repo_changelog',
202 _url = h.route_url('repo_commits',
203 203 repo_name=entry.repository.repo_name)
204 204
205 205 feed.add_item(
@@ -297,18 +297,19 b' class JournalView(BaseAppView):'
297 297 user_id = self.request.POST.get('follows_user_id')
298 298 if user_id:
299 299 try:
300 ScmModel().toggle_following_user(
301 user_id, self._rhodecode_user.user_id)
300 ScmModel().toggle_following_user(user_id, self._rhodecode_user.user_id)
302 301 Session().commit()
303 302 return 'ok'
304 303 except Exception:
305 304 raise HTTPBadRequest()
306 305
307 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 311 try:
310 ScmModel().toggle_following_repo(
311 repo_id, self._rhodecode_user.user_id)
312 ScmModel().toggle_following_repo(repo_id, self._rhodecode_user.user_id)
312 313 Session().commit()
313 314 return 'ok'
314 315 except Exception:
@@ -360,7 +360,7 b' class MyAccountView(BaseAppView, DataGri'
360 360 'repository.read', 'repository.write', 'repository.admin'])
361 361
362 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 364 # json used to render the grid
365 365 return json.dumps(repos_data)
366 366
@@ -423,7 +423,7 b' class MyAccountView(BaseAppView, DataGri'
423 423 default_redirect_url = ''
424 424
425 425 # save repo
426 if entry.get('bookmark_repo'):
426 if entry.get('bookmark_repo') and safe_int(entry.get('bookmark_repo')):
427 427 repo = Repository.get(entry['bookmark_repo'])
428 428 perm_check = HasRepoPermissionAny(
429 429 'repository.read', 'repository.write', 'repository.admin')
@@ -432,7 +432,7 b' class MyAccountView(BaseAppView, DataGri'
432 432 should_save = True
433 433 default_redirect_url = '${repo_url}'
434 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 436 repo_group = RepoGroup.get(entry['bookmark_repo_group'])
437 437 perm_check = HasRepoGroupPermissionAny(
438 438 'group.read', 'group.write', 'group.admin')
@@ -90,7 +90,7 b' def includeme(config):'
90 90 # Files
91 91 config.add_route(
92 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 95 config.add_route(
96 96 name='repo_files_diff',
@@ -172,6 +172,10 b' def includeme(config):'
172 172 pattern='/{repo_name:.*?[^/]}/add_file/{commit_id}/{f_path:.*}',
173 173 repo_route=True)
174 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 179 name='repo_files_create_file',
176 180 pattern='/{repo_name:.*?[^/]}/create_file/{commit_id}/{f_path:.*}',
177 181 repo_route=True)
@@ -189,19 +193,27 b' def includeme(config):'
189 193 name='repo_stats',
190 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 211 config.add_route(
194 212 name='repo_changelog',
195 213 pattern='/{repo_name:.*?[^/]}/changelog', repo_route=True)
196 214 config.add_route(
197 215 name='repo_changelog_file',
198 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 218 # Compare
207 219 config.add_route(
@@ -312,6 +324,11 b' def includeme(config):'
312 324 pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/delete',
313 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 332 # Settings
316 333 config.add_route(
317 334 name='edit_repo',
@@ -40,11 +40,11 b' def route_path(name, params=None, **kwar'
40 40 class TestPullRequestList(object):
41 41
42 42 @pytest.mark.parametrize('params, expected_title', [
43 ({'source': 0, 'closed': 1}, 'Closed Pull Requests'),
44 ({'source': 0, 'my': 1}, 'opened by me'),
45 ({'source': 0, 'awaiting_review': 1}, 'awaiting review'),
46 ({'source': 0, 'awaiting_my_review': 1}, 'awaiting my review'),
47 ({'source': 1}, 'Pull Requests from'),
43 ({'source': 0, 'closed': 1}, 'Closed'),
44 ({'source': 0, 'my': 1}, 'Opened by me'),
45 ({'source': 0, 'awaiting_review': 1}, 'Awaiting review'),
46 ({'source': 0, 'awaiting_my_review': 1}, 'Awaiting my review'),
47 ({'source': 1}, 'From this repo'),
48 48 ])
49 49 def test_showing_list_page(self, backend, pr_util, params, expected_title):
50 50 pull_request = pr_util.create_pull_request()
@@ -55,9 +55,10 b' class TestPullRequestList(object):'
55 55 params=params))
56 56
57 57 assert_response = response.assert_response()
58 assert_response.element_equals_to('.panel-title', expected_title)
59 element = assert_response.get_element('.panel-title')
60 element_text = assert_response._element_to_string(element)
58
59 element = assert_response.get_element('.title .active')
60 element_text = element.text_content()
61 assert expected_title == element_text
61 62
62 63 def test_showing_list_page_data(self, backend, pr_util, xhr_header):
63 64 pull_request = pr_util.create_pull_request()
@@ -32,9 +32,10 b' def route_path(name, params=None, **kwar'
32 32 import urllib
33 33
34 34 base_url = {
35 'repo_changelog':'/{repo_name}/changelog',
36 'repo_changelog_file':'/{repo_name}/changelog/{commit_id}/{f_path}',
37 'repo_changelog_elements':'/{repo_name}/changelog_elements',
35 'repo_changelog': '/{repo_name}/changelog',
36 'repo_commits': '/{repo_name}/commits',
37 'repo_commits_file': '/{repo_name}/commits/{commit_id}/{f_path}',
38 'repo_commits_elements': '/{repo_name}/commits_elements',
38 39 }[name].format(**kwargs)
39 40
40 41 if params:
@@ -42,8 +43,22 b' def route_path(name, params=None, **kwar'
42 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 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 62 def test_changelog(self, backend):
48 63 self.log_user()
49 64 response = self.app.get(
@@ -62,6 +77,14 b' class TestChangelogController(TestContro'
62 77 params=dict(branch=backend.default_branch_name)),
63 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 88 @pytest.mark.backends("svn")
66 89 def test_changelog_filtered_by_branch_svn(self, autologin_user, backend):
67 90 repo = backend['svn-simple-layout']
@@ -70,27 +93,22 b' class TestChangelogController(TestContro'
70 93 params=dict(branch='trunk')),
71 94 status=200)
72 95
73 self.assert_commits_on_page(
74 response, indexes=[15, 12, 7, 3, 2, 1])
96 assert_commits_on_page(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 99 self.log_user()
78 100 branch = 'wrong-branch-name'
79 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 103 params=dict(branch=branch)),
82 104 status=302)
83 expected_url = '/{repo}/changelog/{branch}'.format(
105 expected_url = '/{repo}/commits/{branch}'.format(
84 106 repo=backend.repo_name, branch=branch)
85 107 assert expected_url in response.location
86 108 response = response.follow()
87 109 expected_warning = 'Branch {} is not found.'.format(branch)
88 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 112 @pytest.mark.xfail_backends("svn", reason="Depends on branch support")
95 113 def test_changelog_filtered_by_branch_with_merges(
96 114 self, autologin_user, backend):
@@ -112,21 +130,20 b' class TestChangelogController(TestContro'
112 130 status=200)
113 131
114 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 134 repo = backend['closed_branch']
117 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 137 params=dict(branch='experimental')),
120 138 status=200)
121 139
122 self.assert_commits_on_page(
123 response, indexes=[3, 1])
140 assert_commits_on_page(response, indexes=[3, 1])
124 141
125 142 def test_changelog_pagination(self, backend):
126 143 self.log_user()
127 144 # pagination, walk up to page 6
128 145 changelog_url = route_path(
129 'repo_changelog', repo_name=backend.repo_name)
146 'repo_commits', repo_name=backend.repo_name)
130 147
131 148 for page in range(1, 7):
132 149 response = self.app.get(changelog_url, {'page': page})
@@ -138,22 +155,30 b' class TestChangelogController(TestContro'
138 155 def assert_commit_range_on_page(
139 156 self, response, first_idx, last_idx, backend):
140 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 161 """name="%(raw_id)s" type="checkbox" value="1" />"""
143 162 )
163
144 164 commit_span_template = """<span class="commit_hash">r%s:%s</span>"""
145 165 repo = backend.repo
146 166
147 167 first_commit_on_page = repo.get_commit(commit_idx=first_idx)
148 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 173 response.mustcontain(commit_span_template % (
151 174 first_commit_on_page.idx, first_commit_on_page.short_id)
152 175 )
153 176
154 177 last_commit_on_page = repo.get_commit(commit_idx=last_idx)
155 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 182 response.mustcontain(commit_span_template % (
158 183 last_commit_on_page.idx, last_commit_on_page.short_id)
159 184 )
@@ -168,10 +193,10 b' class TestChangelogController(TestContro'
168 193 '/vcs/exceptions.py',
169 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 197 self.log_user()
173 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 200 commit_id='tip', f_path=test_path),
176 201 )
177 202
@@ -180,16 +205,16 b' class TestChangelogController(TestContro'
180 205 response.mustcontain('Added not implemented hg backend test case')
181 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 209 self.log_user()
185 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 212 commit_id='tip', f_path='/tests'),
188 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 216 self.log_user()
192 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 219 commit_id='tip', f_path='wrong_path'),
195 220 status=302)
@@ -94,6 +94,7 b' class TestCompareView(object):'
94 94 origin_repo = origin.scm_instance(cache=False)
95 95 origin_repo.config.clear_section('hooks')
96 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 99 # Verify test fixture setup
99 100 # This does not work for git
@@ -162,8 +163,7 b' class TestCompareView(object):'
162 163 compare_page.target_source_are_disabled()
163 164
164 165 @pytest.mark.xfail_backends("svn", reason="Depends on branch support")
165 def test_compare_forks_on_branch_extra_commits_origin_has_incomming(
166 self, backend):
166 def test_compare_forks_on_branch_extra_commits_origin_has_incomming(self, backend):
167 167 repo1 = backend.create_repo()
168 168
169 169 # commit something !
@@ -21,6 +21,7 b''
21 21 import pytest
22 22
23 23 from rhodecode.lib.vcs import nodes
24 from rhodecode.lib.vcs.backends.base import EmptyCommit
24 25 from rhodecode.tests.fixture import Fixture
25 26 from rhodecode.tests.utils import commit_change
26 27
@@ -43,70 +44,7 b' def route_path(name, params=None, **kwar'
43 44 @pytest.mark.usefixtures("autologin_user", "app")
44 45 class TestSideBySideDiff(object):
45 46
46 def test_diff_side_by_side(self, app, backend, backend_stub):
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):
47 def test_diff_sidebyside_single_commit(self, app, backend):
110 48 commit_id_range = {
111 49 'hg': {
112 50 'commits': ['25d7e49c18b159446cadfa506a5cf8ad1cb04067',
@@ -141,26 +79,164 b' class TestSideBySideDiff(object):'
141 79 params=dict(target_repo=backend.repo_name, diffmode='sidebyside')
142 80 ))
143 81
82 response.mustcontain(file_changes)
144 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 86 commit_id_range = {
149 87 'hg': {
150 'commits': ['25d7e49c18b159446cadfa506a5cf8ad1cb04067',
88 'commits': ['4fdd71e9427417b2e904e0464c634fdee85ec5a7',
151 89 '603d6c72c46d953420c89d36372f08d9f305f5dd'],
152 'changes': '1 file changed: 1 inserted, 1 deleted'
90 'changes': '32 files changed: 1165 inserted, 308 deleted'
153 91 },
154 92 'git': {
155 'commits': ['6fc9270775aaf5544c1deb014f4ddd60c952fcbb',
93 'commits': ['f5fbf9cfd5f1f1be146f6d3b38bcd791a7480c13',
156 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 98 'svn': {
161 'commits': ['336',
99 'commits': ['335',
162 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 242 f_path = 'docs/conf.py'
@@ -179,5 +255,5 b' class TestSideBySideDiff(object):'
179 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 259 response.mustcontain(file_changes)
@@ -243,7 +243,7 b' class TestFilesViews(object):'
243 243 repo_name=backend.repo_name,
244 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 247 response.mustcontain(msgbox % (commit.message, ))
248 248
249 249 assert_response = response.assert_response()
@@ -313,6 +313,7 b' class TestFilesViews(object):'
313 313
314 314 expected_data = json.loads(
315 315 fixture.load_resource('svn_node_history_branches.json'))
316
316 317 assert expected_data == response.json
317 318
318 319 def test_file_source_history_with_annotation(self, backend, xhr_header):
@@ -521,10 +522,10 b' class TestRepositoryArchival(object):'
521 522 def test_archival(self, backend):
522 523 backend.enable_downloads()
523 524 commit = backend.repo.get_commit(commit_idx=173)
524 for archive, info in settings.ARCHIVE_SPECS.items():
525 mime_type, arch_ext = info
526 short = commit.short_id + arch_ext
527 fname = commit.raw_id + arch_ext
525 for a_type, content_type, extension in settings.ARCHIVE_SPECS:
526
527 short = commit.short_id + extension
528 fname = commit.raw_id + extension
528 529 filename = '%s-%s' % (backend.repo_name, short)
529 530 response = self.app.get(
530 531 route_path('repo_archivefile',
@@ -534,7 +535,7 b' class TestRepositoryArchival(object):'
534 535 assert response.status == '200 OK'
535 536 headers = [
536 537 ('Content-Disposition', 'attachment; filename=%s' % filename),
537 ('Content-Type', '%s' % mime_type),
538 ('Content-Type', '%s' % content_type),
538 539 ]
539 540
540 541 for header in headers:
@@ -761,7 +762,7 b' class TestModifyFilesWithWebInterface(ob'
761 762
762 763 @pytest.mark.xfail_backends("svn", reason="Depends on online editing")
763 764 def test_add_file_into_repo_missing_content(self, backend, csrf_token):
764 repo = backend.create_repo()
765 backend.create_repo()
765 766 filename = 'init.py'
766 767 response = self.app.post(
767 768 route_path('repo_files_create_file',
@@ -770,26 +771,25 b' class TestModifyFilesWithWebInterface(ob'
770 771 params={
771 772 'content': "",
772 773 'filename': filename,
773 'location': "",
774 774 'csrf_token': csrf_token,
775 775 },
776 776 status=302)
777 assert_session_flash(response,
778 'Successfully committed new file `{}`'.format(
779 os.path.join(filename)))
777 expected_msg = 'Successfully committed new file `{}`'.format(os.path.join(filename))
778 assert_session_flash(response, expected_msg)
780 779
781 780 def test_add_file_into_repo_missing_filename(self, backend, csrf_token):
781 commit_id = backend.repo.get_commit().raw_id
782 782 response = self.app.post(
783 783 route_path('repo_files_create_file',
784 784 repo_name=backend.repo_name,
785 commit_id='tip', f_path='/'),
785 commit_id=commit_id, f_path='/'),
786 786 params={
787 787 'content': "foo",
788 788 'csrf_token': csrf_token,
789 789 },
790 790 status=302)
791 791
792 assert_session_flash(response, 'No filename')
792 assert_session_flash(response, 'No filename specified')
793 793
794 794 def test_add_file_into_repo_errors_and_no_commits(
795 795 self, backend, csrf_token):
@@ -806,7 +806,7 b' class TestModifyFilesWithWebInterface(ob'
806 806 },
807 807 status=302)
808 808
809 assert_session_flash(response, 'No filename')
809 assert_session_flash(response, 'No filename specified')
810 810
811 811 # Not allowed, redirect to the summary
812 812 redirected = response.follow()
@@ -817,52 +817,51 b' class TestModifyFilesWithWebInterface(ob'
817 817
818 818 assert redirected.request.path == summary_url
819 819
820 @pytest.mark.parametrize("location, filename", [
821 ('/abs', 'foo'),
822 ('../rel', 'foo'),
823 ('file/../foo', 'foo'),
820 @pytest.mark.parametrize("filename, clean_filename", [
821 ('/abs/foo', 'abs/foo'),
822 ('../rel/foo', 'rel/foo'),
823 ('file/../foo/foo', 'file/foo/foo'),
824 824 ])
825 def test_add_file_into_repo_bad_filenames(
826 self, location, filename, backend, csrf_token):
825 def test_add_file_into_repo_bad_filenames(self, filename, clean_filename, backend, csrf_token):
826 repo = backend.create_repo()
827 commit_id = repo.get_commit().raw_id
828
827 829 response = self.app.post(
828 830 route_path('repo_files_create_file',
829 repo_name=backend.repo_name,
830 commit_id='tip', f_path='/'),
831 repo_name=repo.repo_name,
832 commit_id=commit_id, f_path='/'),
831 833 params={
832 834 'content': "foo",
833 835 'filename': filename,
834 'location': location,
835 836 'csrf_token': csrf_token,
836 837 },
837 838 status=302)
838 839
839 assert_session_flash(
840 response,
841 'The location specified must be a relative path and must not '
842 'contain .. in the path')
840 expected_msg = 'Successfully committed new file `{}`'.format(clean_filename)
841 assert_session_flash(response, expected_msg)
843 842
844 @pytest.mark.parametrize("cnt, location, filename", [
845 (1, '', 'foo.txt'),
846 (2, 'dir', 'foo.rst'),
847 (3, 'rel/dir', 'foo.bar'),
843 @pytest.mark.parametrize("cnt, filename, content", [
844 (1, 'foo.txt', "Content"),
845 (2, 'dir/foo.rst', "Content"),
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,
850 csrf_token):
849 def test_add_file_into_empty_repo(self, cnt, filename, content, backend, csrf_token):
851 850 repo = backend.create_repo()
851 commit_id = repo.get_commit().raw_id
852 852 response = self.app.post(
853 853 route_path('repo_files_create_file',
854 854 repo_name=repo.repo_name,
855 commit_id='tip', f_path='/'),
855 commit_id=commit_id, f_path='/'),
856 856 params={
857 'content': "foo",
857 'content': content,
858 858 'filename': filename,
859 'location': location,
860 859 'csrf_token': csrf_token,
861 860 },
862 861 status=302)
863 assert_session_flash(response,
864 'Successfully committed new file `{}`'.format(
865 os.path.join(location, filename)))
862
863 expected_msg = 'Successfully committed new file `{}`'.format(filename)
864 assert_session_flash(response, expected_msg)
866 865
867 866 def test_edit_file_view(self, backend):
868 867 response = self.app.get(
@@ -884,8 +883,7 b' class TestModifyFilesWithWebInterface(ob'
884 883 f_path='vcs/nodes.py'),
885 884 status=302)
886 885 assert_session_flash(
887 response,
888 'You can only edit files with commit being a valid branch')
886 response, 'Cannot modify file. Given commit `tip` is not head of a branch.')
889 887
890 888 def test_edit_file_view_commit_changes(self, backend, csrf_token):
891 889 repo = backend.create_repo()
@@ -953,8 +951,7 b' class TestModifyFilesWithWebInterface(ob'
953 951 f_path='vcs/nodes.py'),
954 952 status=302)
955 953 assert_session_flash(
956 response,
957 'You can only delete files with commit being a valid branch')
954 response, 'Cannot modify file. Given commit `tip` is not head of a branch.')
958 955
959 956 def test_delete_file_view_commit_changes(self, backend, csrf_token):
960 957 repo = backend.create_repo()
@@ -992,7 +989,7 b' class TestFilesViewOtherCases(object):'
992 989 repo_file_add_url = route_path(
993 990 'repo_files_add_file',
994 991 repo_name=repo.repo_name,
995 commit_id=0, f_path='') + '#edit'
992 commit_id=0, f_path='')
996 993
997 994 assert_session_flash(
998 995 response,
@@ -1009,7 +1006,7 b' class TestFilesViewOtherCases(object):'
1009 1006 repo_file_add_url = route_path(
1010 1007 'repo_files_add_file',
1011 1008 repo_name=repo.repo_name,
1012 commit_id=0, f_path='') + '#edit'
1009 commit_id=0, f_path='')
1013 1010
1014 1011 response = self.app.get(
1015 1012 route_path('repo_files',
@@ -40,6 +40,8 b' def route_path(name, params=None, **kwar'
40 40 base_url = {
41 41 'repo_changelog': '/{repo_name}/changelog',
42 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 45 'pullrequest_show': '/{repo_name}/pull-request/{pull_request_id}',
44 46 'pullrequest_show_all': '/{repo_name}/pull-request',
45 47 'pullrequest_show_all_data': '/{repo_name}/pull-request-data',
@@ -998,11 +1000,11 b' class TestPullrequestsView(object):'
998 1000 assert len(target_children) == 1
999 1001
1000 1002 expected_origin_link = route_path(
1001 'repo_changelog',
1003 'repo_commits',
1002 1004 repo_name=pull_request.source_repo.scm_instance().name,
1003 1005 params=dict(branch='origin'))
1004 1006 expected_target_link = route_path(
1005 'repo_changelog',
1007 'repo_commits',
1006 1008 repo_name=pull_request.target_repo.scm_instance().name,
1007 1009 params=dict(branch='target'))
1008 1010 assert origin_children[0].attrib['href'] == expected_origin_link
@@ -350,11 +350,11 b' class TestCreateReferenceData(object):'
350 350 {
351 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 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 358 'files_url': expected_files_url + 'b/?at=b',
359 359 }
360 360 ],
@@ -363,7 +363,7 b' class TestCreateReferenceData(object):'
363 363 {
364 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 367 'files_url': expected_files_url + 'c/?at=c',
368 368 }
369 369 ],
@@ -385,12 +385,12 b' class TestCreateReferenceData(object):'
385 385 {
386 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 389 'text': 'a', 'type': 't1',
390 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 394 'text': 'b', 'type': 't1',
395 395 'files_url': expected_files_url + 'b_id/b?at=b',
396 396 }
@@ -400,7 +400,7 b' class TestCreateReferenceData(object):'
400 400 {
401 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 404 'text': 'c', 'type': 't2',
405 405 'files_url': expected_files_url + 'c_id/c?at=c',
406 406 }
@@ -516,6 +516,7 b' class TestReferenceItems(object):'
516 516 'text': ref_name,
517 517 'id': self._format_function(ref_name, ref_id),
518 518 'raw_id': ref_id,
519 'idx': 0,
519 520 'type': self.ref_type,
520 521 'files_url': self.fake_url
521 522 }
@@ -113,7 +113,7 b' class RepoChangelogView(RepoAppView):'
113 113 h.flash('Branch {} is not found.'.format(h.escape(branch_name)),
114 114 category='warning')
115 115 redirect_url = h.route_path(
116 'repo_changelog_file', repo_name=repo_name,
116 'repo_commits_file', repo_name=repo_name,
117 117 commit_id=branch_name, f_path=f_path or '')
118 118 raise HTTPFound(redirect_url)
119 119
@@ -127,13 +127,13 b' class RepoChangelogView(RepoAppView):'
127 127 if f_path:
128 128 # changelog for file
129 129 return h.route_path(
130 'repo_changelog_file',
130 'repo_commits_file',
131 131 repo_name=c.rhodecode_db_repo.repo_name,
132 132 commit_id=commit_id, f_path=f_path,
133 133 _query=query_params)
134 134 else:
135 135 return h.route_path(
136 'repo_changelog',
136 'repo_commits',
137 137 repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
138 138
139 139 c.total_cs = len(collection)
@@ -171,11 +171,18 b' class RepoChangelogView(RepoAppView):'
171 171 @HasRepoPermissionAnyDecorator(
172 172 'repository.read', 'repository.write', 'repository.admin')
173 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 181 route_name='repo_changelog', request_method='GET',
175 renderer='rhodecode:templates/changelog/changelog.mako')
182 renderer='rhodecode:templates/commits/changelog.mako')
176 183 @view_config(
177 184 route_name='repo_changelog_file', request_method='GET',
178 renderer='rhodecode:templates/changelog/changelog.mako')
185 renderer='rhodecode:templates/commits/changelog.mako')
179 186 def repo_changelog(self):
180 187 c = self.load_default_context()
181 188
@@ -224,7 +231,7 b' class RepoChangelogView(RepoAppView):'
224 231 except RepositoryError as e:
225 232 h.flash(safe_str(e), category='warning')
226 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 235 raise HTTPFound(redirect_url)
229 236 collection = list(reversed(collection))
230 237 else:
@@ -246,14 +253,14 b' class RepoChangelogView(RepoAppView):'
246 253 log.exception(safe_str(e))
247 254 h.flash(safe_str(h.escape(e)), category='error')
248 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 258 if partial_xhr or self.request.environ.get('HTTP_X_PJAX'):
252 259 # case when loading dynamic file history in file view
253 260 # loading from ajax, we don't want the first result, it's popped
254 261 # in the code above
255 262 html = render(
256 'rhodecode:templates/changelog/changelog_file_history.mako',
263 'rhodecode:templates/commits/changelog_file_history.mako',
257 264 self._get_template_context(c), self.request)
258 265 return Response(html)
259 266
@@ -271,14 +278,14 b' class RepoChangelogView(RepoAppView):'
271 278 @HasRepoPermissionAnyDecorator(
272 279 'repository.read', 'repository.write', 'repository.admin')
273 280 @view_config(
274 route_name='repo_changelog_elements', request_method=('GET', 'POST'),
275 renderer='rhodecode:templates/changelog/changelog_elements.mako',
281 route_name='repo_commits_elements', request_method=('GET', 'POST'),
282 renderer='rhodecode:templates/commits/changelog_elements.mako',
276 283 xhr=True)
277 284 @view_config(
278 route_name='repo_changelog_elements_file', request_method=('GET', 'POST'),
279 renderer='rhodecode:templates/changelog/changelog_elements.mako',
285 route_name='repo_commits_elements_file', request_method=('GET', 'POST'),
286 renderer='rhodecode:templates/commits/changelog_elements.mako',
280 287 xhr=True)
281 def repo_changelog_elements(self):
288 def repo_commits_elements(self):
282 289 c = self.load_default_context()
283 290 commit_id = self.request.matchdict.get('commit_id')
284 291 f_path = self._get_f_path(self.request.matchdict)
@@ -312,7 +319,7 b' class RepoChangelogView(RepoAppView):'
312 319 except (RepositoryError, CommitDoesNotExistError, Exception) as e:
313 320 log.exception(safe_str(e))
314 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 324 collection = base_commit.get_path_history(
318 325 f_path, limit=hist_limit, pre_load=pre_load)
@@ -105,10 +105,9 b' class RepoCommitsView(RepoAppView):'
105 105
106 106 c.commit_ranges = commits
107 107 if not c.commit_ranges:
108 raise RepositoryError(
109 'The commit range returned an empty result')
110 except CommitDoesNotExistError:
111 msg = _('No such commit exists for this repository')
108 raise RepositoryError('The commit range returned an empty result')
109 except CommitDoesNotExistError as e:
110 msg = _('No such commit exists. Org exception: `{}`').format(e)
112 111 h.flash(msg, category='error')
113 112 raise HTTPNotFound()
114 113 except Exception:
@@ -214,29 +214,23 b' class RepoCompareView(RepoAppView):'
214 214 pre_load = ["author", "branch", "date", "message"]
215 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:
224 c.commit_ranges = source_scm.compare(
225 source_commit.raw_id, target_commit.raw_id,
226 target_scm, merge, pre_load=pre_load)
227 if merge:
228 c.ancestor = source_scm.get_common_ancestor(
229 source_commit.raw_id, target_commit.raw_id, target_scm)
230 except RepositoryRequirementError:
231 msg = _('Could not compare repos with different '
232 'large file settings')
233 log.error(msg)
234 if partial:
235 return Response(msg)
236 h.flash(msg, category='error')
237 raise HTTPFound(
238 h.route_path('repo_compare_select',
239 repo_name=self.db_repo_name))
217 try:
218 c.commit_ranges = source_scm.compare(
219 source_commit.raw_id, target_commit.raw_id,
220 target_scm, merge, pre_load=pre_load) or []
221 if merge:
222 c.ancestor = source_scm.get_common_ancestor(
223 source_commit.raw_id, target_commit.raw_id, target_scm)
224 except RepositoryRequirementError:
225 msg = _('Could not compare repos with different '
226 'large file settings')
227 log.error(msg)
228 if partial:
229 return Response(msg)
230 h.flash(msg, category='error')
231 raise HTTPFound(
232 h.route_path('repo_compare_select',
233 repo_name=self.db_repo_name))
240 234
241 235 c.statuses = self.db_repo.statuses(
242 236 [x.raw_id for x in c.commit_ranges])
This diff has been collapsed as it changes many lines, (503 lines changed) Show them Hide them
@@ -25,6 +25,7 b' import shutil'
25 25 import tempfile
26 26 import collections
27 27 import urllib
28 import pathlib2
28 29
29 30 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound
30 31 from pyramid.view import view_config
@@ -42,7 +43,7 b' from rhodecode.lib.exceptions import Non'
42 43 from rhodecode.lib.codeblocks import (
43 44 filenode_as_lines_tokens, filenode_as_annotated_lines_tokens)
44 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 47 from rhodecode.lib.auth import (
47 48 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
48 49 from rhodecode.lib.vcs import path as vcspath
@@ -87,7 +88,7 b' class RepoFilesView(RepoAppView):'
87 88 c.enable_downloads = self.db_repo.enable_downloads
88 89 return c
89 90
90 def _ensure_not_locked(self):
91 def _ensure_not_locked(self, commit_id='tip'):
91 92 _ = self.request.translate
92 93
93 94 repo = self.db_repo
@@ -98,21 +99,41 b' class RepoFilesView(RepoAppView):'
98 99 'warning')
99 100 files_url = h.route_path(
100 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 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 122 _ = self.request.translate
106 123
107 124 rule, branch_perm = self._rhodecode_user.get_rule_and_branch_permission(
108 125 self.db_repo_name, branch_name)
109 126 if branch_perm and branch_perm not in ['branch.push', 'branch.push_force']:
110 h.flash(
111 _('Branch `{}` changes forbidden by rule {}.').format(branch_name, rule),
112 'warning')
127 message = _('Branch `{}` changes forbidden by rule {}.').format(
128 branch_name, rule)
129 h.flash(message, 'warning')
130
131 if json_mode:
132 return message
133
113 134 files_url = h.route_path(
114 'repo_files:default_path',
115 repo_name=self.db_repo_name, commit_id='tip')
135 'repo_files:default_path', repo_name=self.db_repo_name, commit_id=commit_id)
136
116 137 raise HTTPFound(files_url)
117 138
118 139 def _get_commit_and_path(self):
@@ -146,8 +167,7 b' class RepoFilesView(RepoAppView):'
146 167
147 168 _url = h.route_path(
148 169 'repo_files_add_file',
149 repo_name=self.db_repo_name, commit_id=0, f_path='',
150 _anchor='edit')
170 repo_name=self.db_repo_name, commit_id=0, f_path='')
151 171
152 172 if h.HasRepoPermissionAny(
153 173 'repository.write', 'repository.admin')(self.db_repo_name):
@@ -185,8 +205,7 b' class RepoFilesView(RepoAppView):'
185 205 h.flash(_('No such commit exists for this repository'), category='error')
186 206 raise HTTPNotFound()
187 207 except RepositoryError as e:
188 log.warning('Repository error while fetching '
189 'filenode `%s`. Err:%s', path, e)
208 log.warning('Repository error while fetching filenode `%s`. Err:%s', path, e)
190 209 h.flash(safe_str(h.escape(e)), category='error')
191 210 raise HTTPNotFound()
192 211
@@ -195,12 +214,7 b' class RepoFilesView(RepoAppView):'
195 214 def _is_valid_head(self, commit_id, repo):
196 215 branch_name = sha_commit_id = ''
197 216 is_head = False
198
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
217 log.debug('Checking if commit_id `%s` is a head for %s.', commit_id, repo)
204 218
205 219 for _branch_name, branch_commit_id in repo.branches.items():
206 220 # simple case we pass in branch name, it's a HEAD
@@ -216,8 +230,14 b' class RepoFilesView(RepoAppView):'
216 230 sha_commit_id = branch_commit_id
217 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 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 241 commit = repo.get_commit(commit_id=commit_id)
222 242 if commit:
223 243 branch_name = commit.branch
@@ -225,8 +245,7 b' class RepoFilesView(RepoAppView):'
225 245
226 246 return branch_name, sha_commit_id, is_head
227 247
228 def _get_tree_at_commit(
229 self, c, commit_id, f_path, full_load=False):
248 def _get_tree_at_commit(self, c, commit_id, f_path, full_load=False):
230 249
231 250 repo_id = self.db_repo.repo_id
232 251 force_recache = self.get_recache_flag()
@@ -244,16 +263,16 b' class RepoFilesView(RepoAppView):'
244 263
245 264 @region.conditional_cache_on_arguments(namespace=cache_namespace_uid,
246 265 condition=cache_on)
247 def compute_file_tree(repo_id, commit_id, f_path, full_load):
248 log.debug('Generating cached file tree for repo_id: %s, %s, %s',
249 repo_id, commit_id, f_path)
266 def compute_file_tree(ver, repo_id, commit_id, f_path, full_load):
267 log.debug('Generating cached file tree at ver:%s for repo_id: %s, %s, %s',
268 ver, repo_id, commit_id, f_path)
250 269
251 270 c.full_load = full_load
252 271 return render(
253 272 'rhodecode:templates/files/files_browser_tree.mako',
254 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 277 def _get_archive_spec(self, fname):
259 278 log.debug('Detecting archive spec for: `%s`', fname)
@@ -261,8 +280,7 b' class RepoFilesView(RepoAppView):'
261 280 fileformat = None
262 281 ext = None
263 282 content_type = None
264 for a_type, ext_data in settings.ARCHIVE_SPECS.items():
265 content_type, extension = ext_data
283 for a_type, content_type, extension in settings.ARCHIVE_SPECS:
266 284
267 285 if fname.endswith(extension):
268 286 fileformat = a_type
@@ -278,6 +296,15 b' class RepoFilesView(RepoAppView):'
278 296
279 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 308 @LoginRequired()
282 309 @HasRepoPermissionAnyDecorator(
283 310 'repository.read', 'repository.write', 'repository.admin')
@@ -289,9 +316,10 b' class RepoFilesView(RepoAppView):'
289 316 from rhodecode import CONFIG
290 317 _ = self.request.translate
291 318 self.load_default_context()
292
319 default_at_path = '/'
293 320 fname = self.request.matchdict['fname']
294 321 subrepos = self.request.GET.get('subrepos') == 'true'
322 at_path = self.request.GET.get('at_path') or default_at_path
295 323
296 324 if not self.db_repo.enable_downloads:
297 325 return Response(_('Downloads disabled'))
@@ -311,10 +339,31 b' class RepoFilesView(RepoAppView):'
311 339 except EmptyRepositoryError:
312 340 return Response(_('Empty repository'))
313 341
314 archive_name = '%s-%s%s%s' % (
315 safe_str(self.db_repo_name.replace('/', '_')),
316 '-sub' if subrepos else '',
317 safe_str(commit.short_id), ext)
342 try:
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,
356 '-sub' if subrepos else '',
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 368 use_cached_archive = False
320 369 archive_cache_enabled = CONFIG.get(
@@ -339,7 +388,8 b' class RepoFilesView(RepoAppView):'
339 388 fd, archive = tempfile.mkstemp()
340 389 log.debug('Creating new temp archive in %s', archive)
341 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 393 except ImproperArchiveTypeError:
344 394 return _('Unknown archive type')
345 395 if archive_cache_enabled:
@@ -632,8 +682,7 b' class RepoFilesView(RepoAppView):'
632 682 c.authors = []
633 683 # this loads a simple tree without metadata to speed things up
634 684 # later via ajax we call repo_nodetree_full and fetch whole
635 c.file_tree = self._get_tree_at_commit(
636 c, c.commit.raw_id, f_path)
685 c.file_tree = self._get_tree_at_commit(c, c.commit.raw_id, f_path)
637 686
638 687 except RepositoryError as e:
639 688 h.flash(safe_str(h.escape(e)), category='error')
@@ -875,18 +924,17 b' class RepoFilesView(RepoAppView):'
875 924 self.db_repo_name, self.db_repo.repo_id, commit.raw_id, f_path)
876 925 return {'nodes': metadata}
877 926
878 def _create_references(
879 self, branches_or_tags, symbolic_reference, f_path):
927 def _create_references(self, branches_or_tags, symbolic_reference, f_path, ref_type):
880 928 items = []
881 929 for name, commit_id in branches_or_tags.items():
882 sym_ref = symbolic_reference(commit_id, name, f_path)
883 items.append((sym_ref, name))
930 sym_ref = symbolic_reference(commit_id, name, f_path, ref_type)
931 items.append((sym_ref, name, ref_type))
884 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 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 938 new_f_path = vcspath.join(name, f_path)
891 939 return u'%s@%s' % (new_f_path, commit_id)
892 940
@@ -916,7 +964,7 b' class RepoFilesView(RepoAppView):'
916 964 for commit in commits:
917 965 branch = ' (%s)' % commit.branch if commit.branch else ''
918 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 968 history.append(commits_group)
921 969
922 970 symbolic_reference = self._symbolic_reference
@@ -932,11 +980,11 b' class RepoFilesView(RepoAppView):'
932 980 symbolic_reference = self._symbolic_reference_svn
933 981
934 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 984 branches_group = (branches, _("Branches"))
937 985
938 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 988 tags_group = (tags, _("Tags"))
941 989
942 990 history.append(branches_group)
@@ -964,7 +1012,7 b' class RepoFilesView(RepoAppView):'
964 1012 for obj in file_history:
965 1013 res.append({
966 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 1018 data = {
@@ -1035,15 +1083,9 b' class RepoFilesView(RepoAppView):'
1035 1083 _branch_name, _sha_commit_id, is_head = \
1036 1084 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1037 1085
1038 if not is_head:
1039 h.flash(_('You can only delete files with commit '
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))
1086 self.forbid_non_head(is_head, f_path)
1087 self.check_branch_permission(_branch_name)
1045 1088
1046 self.check_branch_permission(_branch_name)
1047 1089 c.commit = self._get_commit_or_redirect(commit_id)
1048 1090 c.file = self._get_filenode_or_redirect(c.commit, f_path)
1049 1091
@@ -1069,13 +1111,7 b' class RepoFilesView(RepoAppView):'
1069 1111 _branch_name, _sha_commit_id, is_head = \
1070 1112 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1071 1113
1072 if not is_head:
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))
1114 self.forbid_non_head(is_head, f_path)
1079 1115 self.check_branch_permission(_branch_name)
1080 1116
1081 1117 c.commit = self._get_commit_or_redirect(commit_id)
@@ -1125,14 +1161,8 b' class RepoFilesView(RepoAppView):'
1125 1161 _branch_name, _sha_commit_id, is_head = \
1126 1162 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1127 1163
1128 if not is_head:
1129 h.flash(_('You can only edit files with commit '
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)
1164 self.forbid_non_head(is_head, f_path, commit_id=commit_id)
1165 self.check_branch_permission(_branch_name, commit_id=commit_id)
1136 1166
1137 1167 c.commit = self._get_commit_or_redirect(commit_id)
1138 1168 c.file = self._get_filenode_or_redirect(c.commit, f_path)
@@ -1144,8 +1174,7 b' class RepoFilesView(RepoAppView):'
1144 1174 commit_id=c.commit.raw_id, f_path=f_path)
1145 1175 raise HTTPFound(files_url)
1146 1176
1147 c.default_message = _(
1148 'Edited file {} via RhodeCode Enterprise').format(f_path)
1177 c.default_message = _('Edited file {} via RhodeCode Enterprise').format(f_path)
1149 1178 c.f_path = f_path
1150 1179
1151 1180 return self._get_template_context(c)
@@ -1162,32 +1191,23 b' class RepoFilesView(RepoAppView):'
1162 1191 commit_id, f_path = self._get_commit_and_path()
1163 1192
1164 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 1195 c.commit = self._get_commit_or_redirect(commit_id)
1179 1196 c.file = self._get_filenode_or_redirect(c.commit, f_path)
1180 1197
1181 1198 if c.file.is_binary:
1182 raise HTTPFound(
1183 h.route_path('repo_files',
1184 repo_name=self.db_repo_name,
1185 commit_id=c.commit.raw_id,
1186 f_path=f_path))
1199 raise HTTPFound(h.route_path('repo_files', repo_name=self.db_repo_name,
1200 commit_id=c.commit.raw_id, f_path=f_path))
1201
1202 _branch_name, _sha_commit_id, is_head = \
1203 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1187 1204
1188 c.default_message = _(
1189 'Edited file {} via RhodeCode Enterprise').format(f_path)
1205 self.forbid_non_head(is_head, f_path, commit_id=commit_id)
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 1209 c.f_path = f_path
1210
1191 1211 old_content = c.file.content
1192 1212 sl = old_content.splitlines(1)
1193 1213 first_line = sl[0] if sl else ''
@@ -1198,20 +1218,25 b' class RepoFilesView(RepoAppView):'
1198 1218 content = convert_line_endings(r_post.get('content', ''), line_ending_mode)
1199 1219
1200 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 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:
1206 h.flash(_('No changes'), category='warning')
1207 raise HTTPFound(
1208 h.route_path('repo_commit', repo_name=self.db_repo_name,
1209 commit_id='tip'))
1228 default_redirect_url = h.route_path('repo_commit', repo_name=self.db_repo_name,
1229 commit_id=commit_id)
1230 if content == old_content and node_path == org_node_path:
1231 h.flash(_('No changes detected on {}').format(org_node_path),
1232 category='warning')
1233 raise HTTPFound(default_redirect_url)
1234
1210 1235 try:
1211 1236 mapping = {
1212 org_f_path: {
1213 'org_filename': org_f_path,
1214 'filename': os.path.join(c.file.dir_path, filename),
1237 org_node_path: {
1238 'org_filename': org_node_path,
1239 'filename': node_path,
1215 1240 'content': content,
1216 1241 'lexer': '',
1217 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 1248 user=self._rhodecode_db_user.user_id,
1224 1249 repo=self.db_repo,
1225 1250 message=message,
@@ -1227,21 +1252,25 b' class RepoFilesView(RepoAppView):'
1227 1252 parent_commit=c.commit,
1228 1253 )
1229 1254
1230 h.flash(
1231 _('Successfully committed changes to file `{}`').format(
1255 h.flash(_('Successfully committed changes to file `{}`').format(
1232 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 1260 except Exception:
1234 1261 log.exception('Error occurred during commit')
1235 1262 h.flash(_('Error occurred during commit'), category='error')
1236 raise HTTPFound(
1237 h.route_path('repo_commit', repo_name=self.db_repo_name,
1238 commit_id='tip'))
1263
1264 raise HTTPFound(default_redirect_url)
1239 1265
1240 1266 @LoginRequired()
1241 1267 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
1242 1268 @view_config(
1243 1269 route_name='repo_files_add_file', request_method='GET',
1244 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 1274 def repo_files_add_file(self):
1246 1275 _ = self.request.translate
1247 1276 c = self.load_default_context()
@@ -1252,27 +1281,20 b' class RepoFilesView(RepoAppView):'
1252 1281 c.commit = self._get_commit_or_redirect(commit_id, redirect_after=False)
1253 1282 if c.commit is None:
1254 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 1286 # for empty repository we cannot check for current branch, we rely on
1260 1287 # c.commit.branch instead
1261 _branch_name = c.commit.branch
1262 is_head = True
1288 _branch_name, _sha_commit_id, is_head = c.commit.branch, '', True
1263 1289 else:
1264 1290 _branch_name, _sha_commit_id, is_head = \
1265 1291 self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
1266 1292
1267 if not is_head:
1268 h.flash(_('You can only add files with commit '
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))
1293 self.forbid_non_head(is_head, f_path, commit_id=commit_id)
1294 self.check_branch_permission(_branch_name, commit_id=commit_id)
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 1299 return self._get_template_context(c)
1278 1300
@@ -1289,86 +1311,62 b' class RepoFilesView(RepoAppView):'
1289 1311
1290 1312 self._ensure_not_locked()
1291 1313
1292 r_post = self.request.POST
1293
1294 c.commit = self._get_commit_or_redirect(
1295 commit_id, redirect_after=False)
1314 c.commit = self._get_commit_or_redirect(commit_id, redirect_after=False)
1296 1315 if c.commit is None:
1297 1316 c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias)
1298 1317
1299 if self.rhodecode_vcs_repo.is_empty:
1300 # for empty repository we cannot check for current branch, we rely on
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:
1318 # calculate redirect URL
1319 if self.rhodecode_vcs_repo.is_empty():
1337 1320 default_redirect_url = h.route_path(
1338 1321 'repo_summary', repo_name=self.db_repo_name)
1339 1322 else:
1340 1323 default_redirect_url = h.route_path(
1341 1324 'repo_commit', repo_name=self.db_repo_name, commit_id='tip')
1342 1325
1343 # If there's no commit, redirect to repo summary
1344 if type(c.commit) is EmptyCommit:
1345 redirect_url = h.route_path(
1346 'repo_summary', repo_name=self.db_repo_name)
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
1347 1330 else:
1348 redirect_url = default_redirect_url
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)
1349 1345
1350 1346 if not filename:
1351 h.flash(_('No filename'), category='warning')
1347 # If there's no commit, redirect to repo summary
1348 if type(c.commit) is EmptyCommit:
1349 redirect_url = h.route_path(
1350 'repo_summary', repo_name=self.db_repo_name)
1351 else:
1352 redirect_url = default_redirect_url
1353 h.flash(_('No filename specified'), category='warning')
1352 1354 raise HTTPFound(redirect_url)
1353 1355
1354 # extract the location from filename,
1355 # allows using foo/bar.txt syntax to create subdirectories
1356 subdir_loc = filename.rsplit('/', 1)
1357 if len(subdir_loc) == 2:
1358 location = os.path.join(location, subdir_loc[0])
1356 root_path = f_path
1357 pure_path = self.create_pure_path(root_path, filename)
1358 node_path = safe_unicode(bytes(pure_path).lstrip('/'))
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 1360 author = self._rhodecode_db_user.full_contact
1361 nodes = {
1362 node_path: {
1363 'content': content
1364 }
1365 }
1364 1366
1365 1367 try:
1366 nodes = {
1367 node_path: {
1368 'content': content
1369 }
1370 }
1371 ScmModel().create_nodes(
1368
1369 commit = ScmModel().create_nodes(
1372 1370 user=self._rhodecode_db_user.user_id,
1373 1371 repo=self.db_repo,
1374 1372 message=message,
@@ -1377,14 +1375,16 b' class RepoFilesView(RepoAppView):'
1377 1375 author=author,
1378 1376 )
1379 1377
1380 h.flash(
1381 _('Successfully committed new file `{}`').format(
1378 h.flash(_('Successfully committed new file `{}`').format(
1382 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 1384 except NonRelativePathError:
1384 1385 log.exception('Non Relative path found')
1385 h.flash(_(
1386 'The location specified must be a relative path and must not '
1387 'contain .. in the path'), category='warning')
1386 h.flash(_('The location specified must be a relative path and must not '
1387 'contain .. in the path'), category='warning')
1388 1388 raise HTTPFound(default_redirect_url)
1389 1389 except (NodeError, NodeAlreadyExistsError) as e:
1390 1390 h.flash(_(h.escape(e)), category='error')
@@ -1393,3 +1393,134 b' class RepoFilesView(RepoAppView):'
1393 1393 h.flash(_('Error occurred during commit'), category='error')
1394 1394
1395 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 72 log.debug("Searching for a README file.")
73 73 readme_node = ReadmeFinder(_renderer_type).search(commit)
74 74 if readme_node:
75 log.debug('Found README node: %s', readme_node)
75 76 relative_urls = {
76 77 'raw': h.route_path(
77 78 'repo_file_raw', repo_name=_repo_name,
@@ -82,7 +83,8 b' class RepoSummaryView(RepoAppView):'
82 83 }
83 84 readme_data = self._render_readme_or_none(
84 85 commit, readme_node, relative_urls)
85 readme_filename = readme_node.path
86 readme_filename = readme_node.unicode_path
87
86 88 return readme_data, readme_filename
87 89
88 90 inv_context_manager = rc_cache.InvalidationContext(
@@ -202,6 +204,10 b' class RepoSummaryView(RepoAppView):'
202 204 # Prepare the clone URL
203 205 self._prepare_and_set_clone_url(c)
204 206
207 # update every 5 min
208 if self.db_repo.last_commit_cache_update_diff > 60 * 5:
209 self.db_repo.update_commit_cache()
210
205 211 # If enabled, get statistics data
206 212
207 213 c.show_stats = bool(self.db_repo.enable_statistics)
@@ -233,8 +239,6 b' class RepoSummaryView(RepoAppView):'
233 239 c.enable_downloads = self.db_repo.enable_downloads
234 240 c.repository_followers = scm_model.get_followers(self.db_repo)
235 241 c.repository_forks = scm_model.get_forks(self.db_repo)
236 c.repository_is_user_following = scm_model.is_following_repo(
237 self.db_repo_name, self._rhodecode_user.user_id)
238 242
239 243 # first interaction with the VCS instance after here...
240 244 if c.repository_requirements_missing:
@@ -319,8 +323,7 b' class RepoSummaryView(RepoAppView):'
319 323 (_("Tag"), repo.tags, 'tag'),
320 324 (_("Bookmark"), repo.bookmarks, 'book'),
321 325 ]
322 res = self._create_reference_data(
323 repo, self.db_repo_name, refs_to_create)
326 res = self._create_reference_data(repo, self.db_repo_name, refs_to_create)
324 327 data = {
325 328 'more': False,
326 329 'results': res
@@ -367,8 +370,7 b' class RepoSummaryView(RepoAppView):'
367 370 })
368 371 return result
369 372
370 def _create_reference_items(self, repo, full_repo_name, refs, ref_type,
371 format_ref_id):
373 def _create_reference_items(self, repo, full_repo_name, refs, ref_type, format_ref_id):
372 374 result = []
373 375 is_svn = h.is_svn(repo)
374 376 for ref_name, raw_id in refs.iteritems():
@@ -380,6 +382,7 b' class RepoSummaryView(RepoAppView):'
380 382 'raw_id': raw_id,
381 383 'type': ref_type,
382 384 'files_url': files_url,
385 'idx': 0,
383 386 })
384 387 return result
385 388
@@ -250,7 +250,7 b' def includeme(config):'
250 250
251 251 # Includes which are required. The application would fail without them.
252 252 config.include('pyramid_mako')
253 config.include('pyramid_beaker')
253 config.include('rhodecode.lib.rc_beaker')
254 254 config.include('rhodecode.lib.rc_cache')
255 255
256 256 config.include('rhodecode.apps._base.navigation')
@@ -28,8 +28,8 b' def _pre_push_hook(*args, **kwargs):'
28 28 [{u'hg_env|git_env': ...,
29 29 u'multiple_heads': [],
30 30 u'name': u'default',
31 u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
32 u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
31 u'new_rev': u'd0b2ae0692e722e01d5677f27a104631cf798b69',
32 u'old_rev': u'd0b1ae0692e722e01d5677f27a104631cf798b69',
33 33 u'ref': u'',
34 34 u'total_commits': 2,
35 35 u'type': u'branch'}]
@@ -47,13 +47,17 b' def _pre_push_hook(*args, **kwargs):'
47 47 forbid_files = repo_extra_fields.get('forbid_files_glob', {}).get('field_value')
48 48 forbid_files = aslist(forbid_files)
49 49
50 # forbid_files = ['*'] # example pattern
51
50 52 # optionally get bytes limit for a single file, e.g 1024 for 1KB
51 53 forbid_size_over = repo_extra_fields.get('forbid_size_over', {}).get('field_value')
52 54 forbid_size_over = int(forbid_size_over or 0)
53 55
56 # forbid_size_over = 1024 # example 1024
57
54 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 61 It should return a valid boolean, and a reason for failure
58 62
59 63 file_data =[
@@ -87,7 +91,10 b' def _pre_push_hook(*args, **kwargs):'
87 91
88 92 # validate A(dded) files and size
89 93 if size_limit and operation == 'A':
90 size = len(file_data['raw_diff'])
94 if 'file_size' in file_data:
95 size = file_data['file_size']
96 else:
97 size = len(file_data['raw_diff'])
91 98
92 99 reason = 'File {} size of {} bytes exceeds limit {}'.format(
93 100 file_name, format_byte_size_binary(size),
@@ -34,12 +34,51 b' from rhodecode.lib.vcs.backends.hg.diff '
34 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 77 files = []
39 78 return files
40 79
41 80
42 def get_git_files(repo, refs):
81 def get_git_files(repo, vcs_repo, refs):
43 82 files = []
44 83
45 84 for data in refs:
@@ -57,7 +96,7 b' def get_git_files(repo, refs):'
57 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 100 vcs_diff = GitDiff(stdout)
62 101
63 102 diff_processor = diffs.DiffProcessor(vcs_diff, format='newdiff')
@@ -86,11 +125,14 b' def run(*args, **kwargs):'
86 125 if vcs_type == 'git':
87 126 for rev_data in kwargs['commit_ids']:
88 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 130 if vcs_type == 'hg':
92 131 for rev_data in kwargs['commit_ids']:
93 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 138 return files
@@ -402,7 +402,8 b' class RepoIntegrationsView(IntegrationSe'
402 402 c.rhodecode_db_repo = self.repo
403 403 c.repo_name = self.db_repo.repo_name
404 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 407 c.has_origin_repo_read_perm = False
407 408 if self.db_repo.fork:
408 409 c.has_origin_repo_read_perm = h.HasRepoPermissionAny(
@@ -92,6 +92,9 b' ACTIONS_V1 = {'
92 92 'repo.commit.comment.delete': {'data': {}},
93 93 'repo.commit.vote': '',
94 94
95 'repo.artifact.add': '',
96 'repo.artifact.delete': '',
97
95 98 'repo_group.create': {'data': {}},
96 99 'repo_group.edit': {'old_data': {}},
97 100 'repo_group.edit.permissions': {},
@@ -2078,8 +2078,7 b' class HasRepoPermissionAny(PermsFunction'
2078 2078 class HasRepoGroupPermissionAny(PermsFunction):
2079 2079 def __call__(self, group_name=None, check_location='', user=None):
2080 2080 self.repo_group_name = group_name
2081 return super(HasRepoGroupPermissionAny, self).__call__(
2082 check_location, user)
2081 return super(HasRepoGroupPermissionAny, self).__call__(check_location, user)
2083 2082
2084 2083 def check_permissions(self, user):
2085 2084 perms = user.permissions
@@ -2095,8 +2094,7 b' class HasRepoGroupPermissionAny(PermsFun'
2095 2094 class HasRepoGroupPermissionAll(PermsFunction):
2096 2095 def __call__(self, group_name=None, check_location='', user=None):
2097 2096 self.repo_group_name = group_name
2098 return super(HasRepoGroupPermissionAll, self).__call__(
2099 check_location, user)
2097 return super(HasRepoGroupPermissionAll, self).__call__(check_location, user)
2100 2098
2101 2099 def check_permissions(self, user):
2102 2100 perms = user.permissions
@@ -2112,8 +2110,7 b' class HasRepoGroupPermissionAll(PermsFun'
2112 2110 class HasUserGroupPermissionAny(PermsFunction):
2113 2111 def __call__(self, user_group_name=None, check_location='', user=None):
2114 2112 self.user_group_name = user_group_name
2115 return super(HasUserGroupPermissionAny, self).__call__(
2116 check_location, user)
2113 return super(HasUserGroupPermissionAny, self).__call__(check_location, user)
2117 2114
2118 2115 def check_permissions(self, user):
2119 2116 perms = user.permissions
@@ -2129,8 +2126,7 b' class HasUserGroupPermissionAny(PermsFun'
2129 2126 class HasUserGroupPermissionAll(PermsFunction):
2130 2127 def __call__(self, user_group_name=None, check_location='', user=None):
2131 2128 self.user_group_name = user_group_name
2132 return super(HasUserGroupPermissionAll, self).__call__(
2133 check_location, user)
2129 return super(HasUserGroupPermissionAll, self).__call__(check_location, user)
2134 2130
2135 2131 def check_permissions(self, user):
2136 2132 perms = user.permissions
@@ -288,7 +288,6 b' def attach_context_attributes(context, r'
288 288 """
289 289 config = request.registry.settings
290 290
291
292 291 rc_config = SettingsModel().get_all_settings(cache=True)
293 292
294 293 context.rhodecode_version = rhodecode.__version__
@@ -375,20 +374,25 b' def attach_context_attributes(context, r'
375 374 "sideside": "sideside"
376 375 }.get(request.GET.get('diffmode'))
377 376
378 if diffmode and diffmode != request.session.get('rc_user_session_attr.diffmode'):
379 request.session['rc_user_session_attr.diffmode'] = diffmode
380
381 # session settings per user
377 is_api = hasattr(request, 'rpc_user')
382 378 session_attrs = {
383 379 # defaults
384 380 "clone_url_format": "http",
385 381 "diffmode": "sideside"
386 382 }
387 for k, v in request.session.items():
388 pref = 'rc_user_session_attr.'
389 if k and k.startswith(pref):
390 k = k[len(pref):]
391 session_attrs[k] = v
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
391 for k, v in request.session.items():
392 pref = 'rc_user_session_attr.'
393 if k and k.startswith(pref):
394 k = k[len(pref):]
395 session_attrs[k] = v
392 396
393 397 context.user_session_attrs = session_attrs
394 398
@@ -420,8 +424,12 b' def attach_context_attributes(context, r'
420 424 'extra': {'plugins': {}}
421 425 }
422 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 433 context.backends = rhodecode.BACKENDS.keys()
426 434 context.backends.sort()
427 435 unread_count = 0
@@ -537,7 +545,7 b' def bootstrap_config(request):'
537 545
538 546 # allow pyramid lookup in testing
539 547 config.include('pyramid_mako')
540 config.include('pyramid_beaker')
548 config.include('rhodecode.lib.rc_beaker')
541 549 config.include('rhodecode.lib.rc_cache')
542 550
543 551 add_events_routes(config)
@@ -485,9 +485,6 b' class DbManage(object):'
485 485 self.populate_default_permissions()
486 486 return fixed
487 487
488 def update_repo_info(self):
489 RepoModel.update_repoinfo()
490
491 488 def config_prompt(self, test_repo_path='', retries=3):
492 489 defaults = self.cli_args
493 490 _path = defaults.get('repos_location')
@@ -614,7 +614,7 b' class Repository(Base, BaseModel):'
614 614 if (cs_cache != self.changeset_cache or not self.changeset_cache):
615 615 _default = datetime.datetime.fromtimestamp(0)
616 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 618 self.updated_on = last_change
619 619 self.changeset_cache = cs_cache
620 620 Session().add(self)
@@ -2164,7 +2164,7 b' class Repository(Base, BaseModel):'
2164 2164 if is_outdated(cs_cache) or not self.changeset_cache:
2165 2165 _default = datetime.datetime.fromtimestamp(0)
2166 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 2168 self.repo_name, cs_cache)
2169 2169 self.updated_on = last_change
2170 2170 self.changeset_cache = cs_cache
@@ -2230,7 +2230,7 b' class Repository(Base, BaseModel):'
2230 2230 if is_outdated(cs_cache) or not self.changeset_cache:
2231 2231 _default = datetime.datetime.fromtimestamp(0)
2232 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 2234 self.repo_name, cs_cache)
2235 2235 self.updated_on = last_change
2236 2236 self.changeset_cache = cs_cache
@@ -2278,7 +2278,7 b' class Repository(Base, BaseModel):'
2278 2278 # if yes, we use the current timestamp instead. Imagine you get
2279 2279 # old commit pushed 1y ago, we'd set last update 1y to ago.
2280 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 2282 self.repo_name, cs_cache)
2283 2283 self.updated_on = last_change
2284 2284 self.changeset_cache = cs_cache
@@ -2301,7 +2301,7 b' class Repository(Base, BaseModel):'
2301 2301 # if yes, we use the current timestamp instead. Imagine you get
2302 2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2303 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 2305 self.repo_name, cs_cache)
2306 2306 self.updated_on = last_change
2307 2307 self.changeset_cache = cs_cache
@@ -2301,7 +2301,7 b' class Repository(Base, BaseModel):'
2301 2301 # if yes, we use the current timestamp instead. Imagine you get
2302 2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2303 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 2305 self.repo_name, cs_cache)
2306 2306 self.updated_on = last_change
2307 2307 self.changeset_cache = cs_cache
@@ -1865,7 +1865,7 b' class Repository(Base, BaseModel):'
1865 1865 if is_outdated(cs_cache) or not self.changeset_cache:
1866 1866 _default = datetime.datetime.fromtimestamp(0)
1867 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 1869 self.repo_name, cs_cache)
1870 1870 self.updated_on = last_change
1871 1871 self.changeset_cache = cs_cache
@@ -1868,7 +1868,7 b' class Repository(Base, BaseModel):'
1868 1868 if is_outdated(cs_cache) or not self.changeset_cache:
1869 1869 _default = datetime.datetime.fromtimestamp(0)
1870 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 1872 self.repo_name, cs_cache)
1873 1873 self.updated_on = last_change
1874 1874 self.changeset_cache = cs_cache
@@ -1867,7 +1867,7 b' class Repository(Base, BaseModel):'
1867 1867 if is_outdated(cs_cache) or not self.changeset_cache:
1868 1868 _default = datetime.datetime.fromtimestamp(0)
1869 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 1871 self.repo_name, cs_cache)
1872 1872 self.updated_on = last_change
1873 1873 self.changeset_cache = cs_cache
@@ -1869,7 +1869,7 b' class Repository(Base, BaseModel):'
1869 1869 if is_outdated(cs_cache) or not self.changeset_cache:
1870 1870 _default = datetime.datetime.fromtimestamp(0)
1871 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 1873 self.repo_name, cs_cache)
1874 1874 self.updated_on = last_change
1875 1875 self.changeset_cache = cs_cache
@@ -1869,7 +1869,7 b' class Repository(Base, BaseModel):'
1869 1869 if is_outdated(cs_cache) or not self.changeset_cache:
1870 1870 _default = datetime.datetime.fromtimestamp(0)
1871 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 1873 self.repo_name, cs_cache)
1874 1874 self.updated_on = last_change
1875 1875 self.changeset_cache = cs_cache
@@ -1912,7 +1912,7 b' class Repository(Base, BaseModel):'
1912 1912 if is_outdated(cs_cache) or not self.changeset_cache:
1913 1913 _default = datetime.datetime.fromtimestamp(0)
1914 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 1916 self.repo_name, cs_cache)
1917 1917 self.updated_on = last_change
1918 1918 self.changeset_cache = cs_cache
@@ -1913,7 +1913,7 b' class Repository(Base, BaseModel):'
1913 1913 if is_outdated(cs_cache) or not self.changeset_cache:
1914 1914 _default = datetime.datetime.fromtimestamp(0)
1915 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 1917 self.repo_name, cs_cache)
1918 1918 self.updated_on = last_change
1919 1919 self.changeset_cache = cs_cache
@@ -2100,7 +2100,7 b' class Repository(Base, BaseModel):'
2100 2100 if is_outdated(cs_cache) or not self.changeset_cache:
2101 2101 _default = datetime.datetime.fromtimestamp(0)
2102 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 2104 self.repo_name, cs_cache)
2105 2105 self.updated_on = last_change
2106 2106 self.changeset_cache = cs_cache
@@ -8,6 +8,7 b' from sqlalchemy import String, Column'
8 8 from sqlalchemy.sql import text
9 9
10 10 from rhodecode.lib.dbmigrate.versions import _reset_base
11 from rhodecode.lib.utils2 import safe_str
11 12 from rhodecode.model import meta, init_model_encryption
12 13 from rhodecode.model.db import RepoGroup
13 14
@@ -29,7 +30,7 b' def upgrade(migrate_engine):'
29 30 op = Operations(context)
30 31
31 32 repo_group = db_4_16_0_2.RepoGroup.__table__
32
33
33 34 with op.batch_alter_table(repo_group.name) as batch_op:
34 35 batch_op.add_column(
35 36 Column("repo_group_name_hash", String(1024), nullable=True, unique=False))
@@ -44,7 +45,7 b' def downgrade(migrate_engine):'
44 45 def _generate_repo_group_name_hashes(models, op, session):
45 46 repo_groups = models.RepoGroup.get_all()
46 47 for repo_group in repo_groups:
47 print(repo_group.group_name)
48 print(safe_str(repo_group.group_name))
48 49 hash_ = RepoGroup.hash_repo_group_name(repo_group.group_name)
49 50 params = {'hash': hash_, 'id': repo_group.group_id}
50 51 query = text(
@@ -26,14 +26,10 b' def upgrade(migrate_engine):'
26 26 op = Operations(context)
27 27
28 28 repo_group = db_4_16_0_2.RepoGroup.__table__
29
29
30 30 with op.batch_alter_table(repo_group.name) as batch_op:
31 31 batch_op.alter_column("repo_group_name_hash", nullable=False)
32 32
33 33
34 34 def downgrade(migrate_engine):
35 35 pass
36
37
38 def _generate_repo_group_name_hashes(models, op, session):
39 pass
@@ -199,6 +199,7 b' class _GetError(object):'
199 199 if form_errors and field_name in form_errors:
200 200 return literal(tmpl % form_errors.get(field_name))
201 201
202
202 203 get_error = _GetError()
203 204
204 205
@@ -214,38 +215,45 b' class _ToolTip(object):'
214 215 tooltip_title = escape(tooltip_title)
215 216 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
216 217 return tooltip_title
218
219
217 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 226 if isinstance(file_path, str):
222 227 file_path = safe_unicode(file_path)
223 228
224 # TODO: johbo: Is this always a url like path, or is this operating
225 # system dependent?
226 path_segments = file_path.split('/')
229 route_qry = {'at': at_ref} if at_ref else None
227 230
228 repo_name_html = escape(repo_name)
229 if len(path_segments) == 1 and path_segments[0] == '':
230 url_segments = [repo_name_html]
231 else:
232 url_segments = [
233 link_to(
234 repo_name_html,
235 route_path(
236 'repo_files',
237 repo_name=repo_name,
238 commit_id=commit_id,
239 f_path=''),
240 class_='pjax-link')]
231 # first segment is a `..` link to repo files
232 root_name = literal(u'<i class="icon-home"></i>')
233 url_segments = [
234 link_to(
235 root_name,
236 route_path(
237 'repo_files',
238 repo_name=repo_name,
239 commit_id=commit_id,
240 f_path='',
241 _query=route_qry),
242 )]
241 243
244 path_segments = file_path.split('/')
242 245 last_cnt = len(path_segments) - 1
243 246 for cnt, segment in enumerate(path_segments):
244 247 if not segment:
245 248 continue
246 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 257 url_segments.append(
250 258 link_to(
251 259 segment_html,
@@ -253,12 +261,32 b' def files_breadcrumbs(repo_name, commit_'
253 261 'repo_files',
254 262 repo_name=repo_name,
255 263 commit_id=commit_id,
256 f_path='/'.join(path_segments[:cnt + 1])),
257 class_='pjax-link'))
258 else:
259 url_segments.append(segment_html)
264 f_path='/'.join(path_segments[:cnt + 1]),
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
260 271
261 return literal('/'.join(url_segments))
272 full_path = file_path
273 icon = files_icon.format(escape(full_path))
274 if file_path == '':
275 return root_name
276 else:
277 return literal(' / '.join(url_segments) + icon)
278
279
280 def files_url_data(request):
281 matchdict = request.matchdict
282
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 292 def code_highlight(code, lexer, formatter, use_hl_filter=False):
@@ -1196,7 +1224,7 b' class InitialsGravatar(object):'
1196 1224 </text>
1197 1225 </svg>""".format(
1198 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 1228 background=self.background,
1201 1229 text_color=self.text_color,
1202 1230 text=initials.upper(),
@@ -1486,10 +1514,12 b' def breadcrumb_repo_link(repo):'
1486 1514 """
1487 1515
1488 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 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 1525 return literal(' &raquo; '.join(path))
@@ -1507,11 +1537,13 b' def breadcrumb_repo_group_link(repo_grou'
1507 1537
1508 1538 path = [
1509 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 1542 for group in repo_group.parents
1512 1543 ] + [
1513 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 1549 return literal(' &raquo; '.join(path))
@@ -1907,23 +1939,26 b' def secure_form(form_url, method="POST",'
1907 1939
1908 1940 def dropdownmenu(name, selected, options, enable_filter=False, **attrs):
1909 1941 select_html = select(name, selected, options, **attrs)
1942
1910 1943 select2 = """
1911 1944 <script>
1912 1945 $(document).ready(function() {
1913 1946 $('#%s').select2({
1914 containerCssClass: 'drop-menu',
1947 containerCssClass: 'drop-menu %s',
1915 1948 dropdownCssClass: 'drop-menu-dropdown',
1916 1949 dropdownAutoWidth: true%s
1917 1950 });
1918 1951 });
1919 1952 </script>
1920 1953 """
1954
1921 1955 filter_option = """,
1922 1956 minimumResultsForSearch: -1
1923 1957 """
1924 1958 input_id = attrs.get('id') or name
1959 extra_classes = ' '.join(attrs.pop('extra_classes', []))
1925 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 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 1980 def get_last_path_part(file_node):
1946 1981 if not file_node.path:
1947 return u''
1982 return u'/'
1948 1983
1949 1984 path = safe_unicode(file_node.path.split('/')[-1])
1950 1985 return u'../' + path
@@ -2033,7 +2068,8 b' def reviewer_as_json(*args, **kwargs):'
2033 2068 def get_repo_view_type(request):
2034 2069 route_name = request.matched_route.name
2035 2070 route_to_view_type = {
2036 'repo_changelog': 'changelog',
2071 'repo_changelog': 'commits',
2072 'repo_commits': 'commits',
2037 2073 'repo_files': 'files',
2038 2074 'repo_summary': 'summary',
2039 2075 'repo_commit': 'commit'
@@ -20,7 +20,55 b''
20 20
21 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 74 # Global Vars
@@ -33,6 +33,8 b' import collections'
33 33 import warnings
34 34
35 35 from zope.cachedescriptors.property import Lazy as LazyProperty
36 from zope.cachedescriptors.property import CachedProperty
37
36 38 from pyramid import compat
37 39
38 40 from rhodecode.translation import lazy_ugettext
@@ -53,6 +55,7 b' log = logging.getLogger(__name__)'
53 55
54 56 FILEMODE_DEFAULT = 0o100644
55 57 FILEMODE_EXECUTABLE = 0o100755
58 EMPTY_COMMIT_ID = '0' * 40
56 59
57 60 Reference = collections.namedtuple('Reference', ('type', 'name', 'commit_id'))
58 61
@@ -261,6 +264,7 b' class BaseRepository(object):'
261 264 EMPTY_COMMIT_ID = '0' * 40
262 265
263 266 path = None
267 _commit_ids_ver = 0
264 268
265 269 def __init__(self, repo_path, config=None, create=False, **kwargs):
266 270 """
@@ -383,7 +387,7 b' class BaseRepository(object):'
383 387 return commit.size
384 388
385 389 def is_empty(self):
386 return not bool(self.commit_ids)
390 return self._remote.is_empty()
387 391
388 392 @staticmethod
389 393 def check_url(url, config):
@@ -404,6 +408,15 b' class BaseRepository(object):'
404 408 # COMMITS
405 409 # ==========================================================================
406 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
407 420 def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, translate_tag=None):
408 421 """
409 422 Returns instance of `BaseCommit` class. If `commit_id` and `commit_idx`
@@ -1094,12 +1107,12 b' class BaseCommit(object):'
1094 1107 """
1095 1108 return None
1096 1109
1097 def archive_repo(self, file_path, kind='tgz', subrepos=None,
1098 prefix=None, write_metadata=False, mtime=None):
1110 def archive_repo(self, archive_dest_path, kind='tgz', subrepos=None,
1111 prefix=None, write_metadata=False, mtime=None, archive_at_path='/'):
1099 1112 """
1100 1113 Creates an archive containing the contents of the repository.
1101 1114
1102 :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.
1103 1116 :param kind: one of following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
1104 1117 :param prefix: name of root directory in archive.
1105 1118 Default is repository name and commit's short_id joined with dash:
@@ -1107,10 +1120,11 b' class BaseCommit(object):'
1107 1120 :param write_metadata: write a metadata file into archive.
1108 1121 :param mtime: custom modification time for archive creation, defaults
1109 1122 to time.time() if not given.
1123 :param archive_at_path: pack files at this path (default '/')
1110 1124
1111 1125 :raise VCSError: If prefix has a problem.
1112 1126 """
1113 allowed_kinds = settings.ARCHIVE_SPECS.keys()
1127 allowed_kinds = [x[0] for x in settings.ARCHIVE_SPECS]
1114 1128 if kind not in allowed_kinds:
1115 1129 raise ImproperArchiveTypeError(
1116 1130 'Archive kind (%s) not supported use one of %s' %
@@ -1118,11 +1132,11 b' class BaseCommit(object):'
1118 1132
1119 1133 prefix = self._validate_archive_prefix(prefix)
1120 1134
1121 mtime = mtime or time.mktime(self.date.timetuple())
1135 mtime = mtime is not None or time.mktime(self.date.timetuple())
1122 1136
1123 1137 file_info = []
1124 1138 cur_rev = self.repository.get_commit(commit_id=self.raw_id)
1125 for _r, _d, files in cur_rev.walk('/'):
1139 for _r, _d, files in cur_rev.walk(archive_at_path):
1126 1140 for f in files:
1127 1141 f_path = os.path.join(prefix, f.path)
1128 1142 file_info.append(
@@ -1131,15 +1145,15 b' class BaseCommit(object):'
1131 1145 if write_metadata:
1132 1146 metadata = [
1133 1147 ('repo_name', self.repository.name),
1134 ('rev', self.raw_id),
1135 ('create_time', mtime),
1148 ('commit_id', self.raw_id),
1149 ('mtime', mtime),
1136 1150 ('branch', self.branch),
1137 1151 ('tags', ','.join(self.tags)),
1138 1152 ]
1139 1153 meta = ["%s:%s" % (f_name, value) for f_name, value in metadata]
1140 1154 file_info.append(('.archival.txt', 0o644, False, '\n'.join(meta)))
1141 1155
1142 connection.Hg.archive_repo(file_path, mtime, file_info, kind)
1156 connection.Hg.archive_repo(archive_dest_path, mtime, file_info, kind)
1143 1157
1144 1158 def _validate_archive_prefix(self, prefix):
1145 1159 if prefix is None:
@@ -1508,9 +1522,7 b' class BaseInMemoryCommit(object):'
1508 1522 "Cannot remove node at %s from "
1509 1523 "following parents: %s" % (not_removed, parents))
1510 1524
1511 def commit(
1512 self, message, author, parents=None, branch=None, date=None,
1513 **kwargs):
1525 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
1514 1526 """
1515 1527 Performs in-memory commit (doesn't check workdir in any way) and
1516 1528 returns newly created :class:`BaseCommit`. Updates repository's
@@ -1558,7 +1570,7 b' class EmptyCommit(BaseCommit):'
1558 1570 """
1559 1571
1560 1572 def __init__(
1561 self, commit_id='0' * 40, repo=None, alias=None, idx=-1,
1573 self, commit_id=EMPTY_COMMIT_ID, repo=None, alias=None, idx=-1,
1562 1574 message='', author='', date=None):
1563 1575 self._empty_commit_id = commit_id
1564 1576 # TODO: johbo: Solve idx parameter, default value does not make
@@ -1618,7 +1630,7 b' class EmptyChangeset(EmptyCommit):'
1618 1630 "Use EmptyCommit instead of EmptyChangeset", DeprecationWarning)
1619 1631 return super(EmptyCommit, cls).__new__(cls, *args, **kwargs)
1620 1632
1621 def __init__(self, cs='0' * 40, repo=None, requested_revision=None,
1633 def __init__(self, cs=EMPTY_COMMIT_ID, repo=None, requested_revision=None,
1622 1634 alias=None, revision=-1, message='', author='', date=None):
1623 1635 if requested_revision is not None:
1624 1636 warnings.warn(
@@ -234,8 +234,7 b' class GitCommit(base.BaseCommit):'
234 234 path = self._fix_path(path)
235 235 if self._get_kind(path) != NodeKind.FILE:
236 236 raise CommitError(
237 "File does not exist for commit %s at '%s'" %
238 (self.raw_id, path))
237 "File does not exist for commit %s at '%s'" % (self.raw_id, path))
239 238 return path
240 239
241 240 def _get_file_nodes(self):
@@ -353,8 +352,7 b' class GitCommit(base.BaseCommit):'
353 352 def get_nodes(self, path):
354 353 if self._get_kind(path) != NodeKind.DIR:
355 354 raise CommitError(
356 "Directory does not exist for commit %s at "
357 " '%s'" % (self.raw_id, path))
355 "Directory does not exist for commit %s at '%s'" % (self.raw_id, path))
358 356 path = self._fix_path(path)
359 357 id_, _ = self._get_id_for_path(path)
360 358 tree_id = self._remote[id_]['id']
@@ -29,8 +29,7 b' from rhodecode.lib.vcs.backends import b'
29 29
30 30 class GitInMemoryCommit(base.BaseInMemoryCommit):
31 31
32 def commit(self, message, author, parents=None, branch=None, date=None,
33 **kwargs):
32 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
34 33 """
35 34 Performs in-memory commit (doesn't check workdir in any way) and
36 35 returns newly created `GitCommit`. Updates repository's
@@ -94,12 +93,12 b' class GitInMemoryCommit(base.BaseInMemor'
94 93 commit_data, branch, commit_tree, updated, removed)
95 94
96 95 # Update vcs repository object
97 self.repository.commit_ids.append(commit_id)
98 self.repository._rebuild_cache(self.repository.commit_ids)
96 self.repository.append_commit_id(commit_id)
99 97
100 98 # invalidate parsed refs after commit
101 99 self.repository._refs = self.repository._get_refs()
102 100 self.repository.branches = self.repository._get_branches()
103 tip = self.repository.get_commit()
101 tip = self.repository.get_commit(commit_id)
102
104 103 self.reset()
105 104 return tip
@@ -25,8 +25,10 b' GIT repository module'
25 25 import logging
26 26 import os
27 27 import re
28 import time
28 29
29 30 from zope.cachedescriptors.property import Lazy as LazyProperty
31 from zope.cachedescriptors.property import CachedProperty
30 32
31 33 from rhodecode.lib.compat import OrderedDict
32 34 from rhodecode.lib.datelib import (
@@ -69,6 +71,9 b' class GitRepository(BaseRepository):'
69 71 # caches
70 72 self._commit_ids = {}
71 73
74 # dependent that trigger re-computation of commit_ids
75 self._commit_ids_ver = 0
76
72 77 @LazyProperty
73 78 def _remote(self):
74 79 return connection.Git(self.path, self.config, with_wire=self.with_wire)
@@ -81,7 +86,7 b' class GitRepository(BaseRepository):'
81 86 def head(self):
82 87 return self._remote.head()
83 88
84 @LazyProperty
89 @CachedProperty('_commit_ids_ver')
85 90 def commit_ids(self):
86 91 """
87 92 Returns list of commit ids, in ascending order. Being lazy
@@ -222,13 +227,10 b' class GitRepository(BaseRepository):'
222 227 return []
223 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 231 def is_null(value):
227 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 234 if commit_id_or_idx in (None, '', 'tip', 'HEAD', 'head', -1):
233 235 return self.commit_ids[-1]
234 236
@@ -238,8 +240,7 b' class GitRepository(BaseRepository):'
238 240 try:
239 241 commit_id_or_idx = self.commit_ids[int(commit_id_or_idx)]
240 242 except Exception:
241 msg = "Commit %s does not exist for %s" % (
242 commit_id_or_idx, self)
243 msg = "Commit {} does not exist for `{}`".format(commit_id_or_idx, self.name)
243 244 raise CommitDoesNotExistError(msg)
244 245
245 246 elif is_bstr:
@@ -261,8 +262,7 b' class GitRepository(BaseRepository):'
261 262
262 263 if (not SHA_PATTERN.match(commit_id_or_idx) or
263 264 commit_id_or_idx not in self.commit_ids):
264 msg = "Commit %s does not exist for %s" % (
265 commit_id_or_idx, self)
265 msg = "Commit {} does not exist for `{}`".format(commit_id_or_idx, self.name)
266 266 raise CommitDoesNotExistError(msg)
267 267
268 268 # Ensure we return full id
@@ -431,19 +431,42 b' class GitRepository(BaseRepository):'
431 431 Returns `GitCommit` object representing commit from git repository
432 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 437 if commit_id is not None:
435 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 446 elif commit_idx is not None:
437 447 self._validate_commit_idx(commit_idx)
438 commit_id = commit_idx
439 commit_id = self._get_commit_id(commit_id)
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:
454 commit_id = commit_idx
455 else:
456 commit_id = "tip"
457
458 commit_id = self._lookup_commit(commit_id)
459 remote_idx = None
460 if translate_tag:
461 # Need to call remote to translate id for tagging scenario
462 remote_data = self._remote.get_object(commit_id)
463 commit_id = remote_data["commit_id"]
464 remote_idx = remote_data["idx"]
465
440 466 try:
441 if translate_tag:
442 # Need to call remote to translate id for tagging scenario
443 commit_id = self._remote.get_object(commit_id)["commit_id"]
444 467 idx = self._commit_ids[commit_id]
445 468 except KeyError:
446 raise RepositoryError("Cannot get object with id %s" % commit_id)
469 idx = remote_idx or 0
447 470
448 471 return GitCommit(self, commit_id, idx, pre_load=pre_load)
449 472
@@ -472,6 +495,7 b' class GitRepository(BaseRepository):'
472 495 """
473 496 if self.is_empty():
474 497 raise EmptyRepositoryError("There are no commits yet")
498
475 499 self._validate_branch_name(branch_name)
476 500
477 501 if start_id is not None:
@@ -479,9 +503,9 b' class GitRepository(BaseRepository):'
479 503 if end_id is not None:
480 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 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 509 end_pos = max(0, self._commit_ids[end_raw_id]) if end_id else None
486 510
487 511 if None not in [start_id, end_id] and start_pos > end_pos:
@@ -589,8 +613,9 b' class GitRepository(BaseRepository):'
589 613 commit = commit.parents[0]
590 614 self._remote.set_refs('refs/heads/%s' % branch_name, commit.raw_id)
591 615
592 self.commit_ids = self._get_all_commit_ids()
593 self._rebuild_cache(self.commit_ids)
616 self._commit_ids_ver = time.time()
617 # we updated _commit_ids_ver so accessing self.commit_ids will re-compute it
618 return len(self.commit_ids)
594 619
595 620 def get_common_ancestor(self, commit_id1, commit_id2, repo2):
596 621 if commit_id1 == commit_id2:
@@ -30,8 +30,7 b' from rhodecode.lib.vcs.exceptions import'
30 30
31 31 class MercurialInMemoryCommit(BaseInMemoryCommit):
32 32
33 def commit(self, message, author, parents=None, branch=None, date=None,
34 **kwargs):
33 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
35 34 """
36 35 Performs in-memory commit (doesn't check workdir in any way) and
37 36 returns newly created `MercurialCommit`. Updates repository's
@@ -83,15 +82,14 b' class MercurialInMemoryCommit(BaseInMemo'
83 82
84 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 86 message=message, parents=parent_ids,
88 87 commit_time=date, commit_timezone=tz, user=author,
89 88 files=self.get_paths(), extra=kwargs, removed=removed,
90 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 92 self.repository.branches = self.repository._get_branches()
95 tip = self.repository.get_commit()
93 tip = self.repository.get_commit(commit_id)
96 94 self.reset()
97 95 return tip
@@ -24,9 +24,11 b' HG repository module'
24 24 import os
25 25 import logging
26 26 import binascii
27 import time
27 28 import urllib
28 29
29 30 from zope.cachedescriptors.property import Lazy as LazyProperty
31 from zope.cachedescriptors.property import CachedProperty
30 32
31 33 from rhodecode.lib.compat import OrderedDict
32 34 from rhodecode.lib.datelib import (
@@ -85,11 +87,14 b' class MercurialRepository(BaseRepository'
85 87 # caches
86 88 self._commit_ids = {}
87 89
90 # dependent that trigger re-computation of commit_ids
91 self._commit_ids_ver = 0
92
88 93 @LazyProperty
89 94 def _remote(self):
90 95 return connection.Hg(self.path, self.config, with_wire=self.with_wire)
91 96
92 @LazyProperty
97 @CachedProperty('_commit_ids_ver')
93 98 def commit_ids(self):
94 99 """
95 100 Returns list of commit ids, in ascending order. Being lazy
@@ -157,8 +162,7 b' class MercurialRepository(BaseRepository'
157 162
158 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,
161 **kwargs):
165 def tag(self, name, user, commit_id=None, message=None, date=None, **kwargs):
162 166 """
163 167 Creates and returns a tag for the given ``commit_id``.
164 168
@@ -172,6 +176,7 b' class MercurialRepository(BaseRepository'
172 176 """
173 177 if name in self.tags:
174 178 raise TagAlreadyExistError("Tag %s already exists" % name)
179
175 180 commit = self.get_commit(commit_id=commit_id)
176 181 local = kwargs.setdefault('local', False)
177 182
@@ -180,8 +185,7 b' class MercurialRepository(BaseRepository'
180 185
181 186 date, tz = date_to_timestamp_plus_offset(date)
182 187
183 self._remote.tag(
184 name, commit.raw_id, message, local, user, date, tz)
188 self._remote.tag(name, commit.raw_id, message, local, user, date, tz)
185 189 self._remote.invalidate_vcs_cache()
186 190
187 191 # Reinitialize tags
@@ -203,6 +207,7 b' class MercurialRepository(BaseRepository'
203 207 """
204 208 if name not in self.tags:
205 209 raise TagDoesNotExistError("Tag %s does not exist" % name)
210
206 211 if message is None:
207 212 message = "Removed tag %s" % name
208 213 local = False
@@ -271,8 +276,9 b' class MercurialRepository(BaseRepository'
271 276 self._remote.strip(commit_id, update=False, backup="none")
272 277
273 278 self._remote.invalidate_vcs_cache()
274 self.commit_ids = self._get_all_commit_ids()
275 self._rebuild_cache(self.commit_ids)
279 self._commit_ids_ver = time.time()
280 # we updated _commit_ids_ver so accessing self.commit_ids will re-compute it
281 return len(self.commit_ids)
276 282
277 283 def verify(self):
278 284 verify = self._remote.verify()
@@ -425,18 +431,20 b' class MercurialRepository(BaseRepository'
425 431 if commit_id is not None:
426 432 self._validate_commit_id(commit_id)
427 433 try:
434 # we have cached idx, use it without contacting the remote
428 435 idx = self._commit_ids[commit_id]
429 436 return MercurialCommit(self, commit_id, idx, pre_load=pre_load)
430 437 except KeyError:
431 438 pass
439
432 440 elif commit_idx is not None:
433 441 self._validate_commit_idx(commit_idx)
434 442 try:
435 id_ = self.commit_ids[commit_idx]
443 _commit_id = self.commit_ids[commit_idx]
436 444 if commit_idx < 0:
437 commit_idx += len(self.commit_ids)
438 return MercurialCommit(
439 self, id_, commit_idx, pre_load=pre_load)
445 commit_idx = self.commit_ids.index(_commit_id)
446
447 return MercurialCommit(self, _commit_id, commit_idx, pre_load=pre_load)
440 448 except IndexError:
441 449 commit_id = commit_idx
442 450 else:
@@ -448,8 +456,8 b' class MercurialRepository(BaseRepository'
448 456 try:
449 457 raw_id, idx = self._remote.lookup(commit_id, both=True)
450 458 except CommitDoesNotExistError:
451 msg = "Commit %s does not exist for %s" % (
452 commit_id, self)
459 msg = "Commit {} does not exist for `{}`".format(
460 *map(safe_str, [commit_id, self.name]))
453 461 raise CommitDoesNotExistError(msg)
454 462
455 463 return MercurialCommit(self, raw_id, idx, pre_load=pre_load)
@@ -477,11 +485,11 b' class MercurialRepository(BaseRepository'
477 485 ``end`` could not be found.
478 486 """
479 487 # actually we should check now if it's not an empty repo
480 branch_ancestors = False
481 488 if self.is_empty():
482 489 raise EmptyRepositoryError("There are no commits yet")
483 490 self._validate_branch_name(branch_name)
484 491
492 branch_ancestors = False
485 493 if start_id is not None:
486 494 self._validate_commit_id(start_id)
487 495 c_start = self.get_commit(commit_id=start_id)
@@ -30,8 +30,7 b' from rhodecode.lib.vcs.backends import b'
30 30
31 31 class SubversionInMemoryCommit(base.BaseInMemoryCommit):
32 32
33 def commit(self, message, author, parents=None, branch=None, date=None,
34 **kwargs):
33 def commit(self, message, author, parents=None, branch=None, date=None, **kwargs):
35 34 if branch not in (None, self.repository.DEFAULT_BRANCH_NAME):
36 35 raise NotImplementedError("Branches are not yet supported")
37 36
@@ -74,8 +73,7 b' class SubversionInMemoryCommit(base.Base'
74 73 # we should not add the commit_id, if it is already evaluated, it
75 74 # will not be evaluated again.
76 75 commit_id = str(svn_rev)
77 if commit_id not in self.repository.commit_ids:
78 self.repository.commit_ids.append(commit_id)
76 self.repository.append_commit_id(commit_id)
79 77 tip = self.repository.get_commit()
80 78 self.reset()
81 79 return tip
@@ -27,6 +27,7 b' import os'
27 27 import urllib
28 28
29 29 from zope.cachedescriptors.property import Lazy as LazyProperty
30 from zope.cachedescriptors.property import CachedProperty
30 31
31 32 from rhodecode.lib.compat import OrderedDict
32 33 from rhodecode.lib.datelib import date_astimestamp
@@ -75,6 +76,9 b' class SubversionRepository(base.BaseRepo'
75 76
76 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 82 @LazyProperty
79 83 def _remote(self):
80 84 return connection.Svn(self.path, self.config)
@@ -93,11 +97,14 b' class SubversionRepository(base.BaseRepo'
93 97 else:
94 98 self._check_path()
95 99
96 @LazyProperty
100 @CachedProperty('_commit_ids_ver')
97 101 def commit_ids(self):
98 102 head = self._remote.lookup(None)
99 103 return [str(r) for r in xrange(1, head + 1)]
100 104
105 def _rebuild_cache(self, commit_ids):
106 pass
107
101 108 def run_svn_command(self, cmd, **opts):
102 109 """
103 110 Runs given ``cmd`` as svn command and returns tuple
@@ -277,7 +284,7 b' class SubversionRepository(base.BaseRepo'
277 284 try:
278 285 commit_id = self.commit_ids[commit_idx]
279 286 except IndexError:
280 raise CommitDoesNotExistError
287 raise CommitDoesNotExistError('No commit with idx: {}'.format(commit_idx))
281 288
282 289 commit_id = self._sanitize_commit_id(commit_id)
283 290 commit = SubversionCommit(repository=self, commit_id=commit_id)
@@ -42,12 +42,16 b' BACKENDS = {'
42 42 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository',
43 43 }
44 44
45 # TODO: Remove once controllers/files.py is adjusted
46 ARCHIVE_SPECS = {
47 'tbz2': ('application/x-bzip2', '.tar.bz2'),
48 'tgz': ('application/x-gzip', '.tar.gz'),
49 'zip': ('application/zip', '.zip'),
50 }
45
46 ARCHIVE_SPECS = [
47 ('tbz2', 'application/x-bzip2', 'tbz2'),
48 ('tbz2', 'application/x-bzip2', '.tar.bz2'),
49
50 ('tgz', 'application/x-gzip', '.tgz'),
51 ('tgz', 'application/x-gzip', '.tar.gz'),
52
53 ('zip', 'application/zip', '.zip'),
54 ]
51 55
52 56 HOOKS_PROTOCOL = None
53 57 HOOKS_DIRECT_CALLS = False
@@ -101,23 +101,35 b' def parse_datetime(text):'
101 101 :param text: string of desired date/datetime or something more verbose,
102 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 114 '%Y-%m-%d %H:%M:%S',
115 '%Y-%m-%dt%H:%M:%S',
109 116 '%Y-%m-%d %H:%M',
117 '%Y-%m-%dt%H:%M',
110 118 '%Y-%m-%d',
111 119 '%m/%d/%Y %H:%M:%S',
120 '%m/%d/%Yt%H:%M:%S',
112 121 '%m/%d/%Y %H:%M',
122 '%m/%d/%Yt%H:%M',
113 123 '%m/%d/%Y',
114 124 '%m/%d/%y %H:%M:%S',
125 '%m/%d/%yt%H:%M:%S',
115 126 '%m/%d/%y %H:%M',
127 '%m/%d/%yt%H:%M',
116 128 '%m/%d/%y',
117 129 )
118 for format in INPUT_FORMATS:
130 for format_def in input_formats:
119 131 try:
120 return datetime.datetime(*time.strptime(text, format)[:6])
132 return datetime.datetime(*time.strptime(text, format_def)[:6])
121 133 except ValueError:
122 134 pass
123 135
@@ -59,7 +59,7 b' from rhodecode.lib.vcs.backends.base imp'
59 59 from rhodecode.lib.utils2 import (
60 60 str2bool, safe_str, get_commit_safe, safe_unicode, sha1_safe,
61 61 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict,
62 glob2re, StrictAttributeDict, cleaned_uri)
62 glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time, OrderedDefaultDict)
63 63 from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \
64 64 JsonRaw
65 65 from rhodecode.lib.ext_json import json
@@ -1678,11 +1678,12 b' class Repository(Base, BaseModel):'
1678 1678 cascade="all, delete, delete-orphan")
1679 1679 ui = relationship('RepoRhodeCodeUi', cascade="all")
1680 1680 settings = relationship('RepoRhodeCodeSetting', cascade="all")
1681 integrations = relationship('Integration',
1682 cascade="all, delete, delete-orphan")
1681 integrations = relationship('Integration', cascade="all, delete, delete-orphan")
1683 1682
1684 1683 scoped_tokens = relationship('UserApiKeys', cascade="all")
1685 1684
1685 artifacts = relationship('FileStore', cascade="all")
1686
1686 1687 def __unicode__(self):
1687 1688 return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id,
1688 1689 safe_unicode(self.repo_name))
@@ -1730,7 +1731,9 b' class Repository(Base, BaseModel):'
1730 1731 from rhodecode.lib.vcs.backends.base import EmptyCommit
1731 1732 dummy = EmptyCommit().__json__()
1732 1733 if not self._changeset_cache:
1733 return dummy
1734 dummy['source_repo_id'] = self.repo_id
1735 return json.loads(json.dumps(dummy))
1736
1734 1737 try:
1735 1738 return json.loads(self._changeset_cache)
1736 1739 except TypeError:
@@ -2183,6 +2186,20 b' class Repository(Base, BaseModel):'
2183 2186 return make_lock, currently_locked, lock_info
2184 2187
2185 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
2186 2203 def last_db_change(self):
2187 2204 return self.updated_on
2188 2205
@@ -2275,6 +2292,7 b' class Repository(Base, BaseModel):'
2275 2292 """
2276 2293 Update cache of last changeset for repository, keys should be::
2277 2294
2295 source_repo_id
2278 2296 short_id
2279 2297 raw_id
2280 2298 revision
@@ -2282,15 +2300,15 b' class Repository(Base, BaseModel):'
2282 2300 message
2283 2301 date
2284 2302 author
2285
2286 :param cs_cache:
2303 updated_on
2304
2287 2305 """
2288 2306 from rhodecode.lib.vcs.backends.base import BaseChangeset
2289 2307 if cs_cache is None:
2290 2308 # use no-cache version here
2291 2309 scm_repo = self.scm_instance(cache=False, config=config)
2292 2310
2293 empty = not scm_repo or scm_repo.is_empty()
2311 empty = scm_repo is None or scm_repo.is_empty()
2294 2312 if not empty:
2295 2313 cs_cache = scm_repo.get_commit(
2296 2314 pre_load=["author", "date", "message", "parents"])
@@ -2310,18 +2328,28 b' class Repository(Base, BaseModel):'
2310 2328 if is_outdated(cs_cache) or not self.changeset_cache:
2311 2329 _default = datetime.datetime.utcnow()
2312 2330 last_change = cs_cache.get('date') or _default
2313 if self.updated_on and self.updated_on > last_change:
2314 # we check if last update is newer than the new value
2315 # if yes, we use the current timestamp instead. Imagine you get
2316 # old commit pushed 1y ago, we'd set last update 1y to ago.
2317 last_change = _default
2318 log.debug('updated repo %s with new cs cache %s',
2319 self.repo_name, cs_cache)
2320 self.updated_on = last_change
2331 # we check if last update is newer than the new value
2332 # if yes, we use the current timestamp instead. Imagine you get
2333 # old commit pushed 1y ago, we'd set last update 1y to ago.
2334 last_change_timestamp = datetime_to_time(last_change)
2335 current_timestamp = datetime_to_time(last_change)
2336 if last_change_timestamp > current_timestamp:
2337 cs_cache['date'] = _default
2338
2339 cs_cache['updated_on'] = time.time()
2321 2340 self.changeset_cache = cs_cache
2322 2341 Session().add(self)
2323 2342 Session().commit()
2343
2344 log.debug('updated repo %s with new commit cache %s',
2345 self.repo_name, cs_cache)
2324 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
2325 2353 log.debug('Skipping update_commit_cache for repo:`%s` '
2326 2354 'commit already with latest changes', self.repo_name)
2327 2355
@@ -2410,6 +2438,7 b' class Repository(Base, BaseModel):'
2410 2438 # control over cache behaviour
2411 2439 if cache is None and full_cache and not config:
2412 2440 return self._get_instance_cached()
2441 # cache here is sent to the "vcs server"
2413 2442 return self._get_instance(cache=bool(cache), config=config)
2414 2443
2415 2444 def _get_instance_cached(self):
@@ -2438,8 +2467,7 b' class Repository(Base, BaseModel):'
2438 2467 else:
2439 2468 instance = get_instance_cached(*args)
2440 2469
2441 log.debug(
2442 'Repo instance fetched in %.3fs', inv_context_manager.compute_time)
2470 log.debug('Repo instance fetched in %.3fs', inv_context_manager.compute_time)
2443 2471 return instance
2444 2472
2445 2473 def _get_instance(self, cache=True, config=None):
@@ -2453,7 +2481,8 b' class Repository(Base, BaseModel):'
2453 2481 with_wire=custom_wire,
2454 2482 create=False,
2455 2483 _vcs_alias=self.repo_type)
2456
2484 if repo is not None:
2485 repo.count() # cache rebuild
2457 2486 return repo
2458 2487
2459 2488 def __json__(self):
@@ -2489,6 +2518,8 b' class RepoGroup(Base, BaseModel):'
2489 2518 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
2490 2519 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
2491 2520 personal = Column('personal', Boolean(), nullable=True, unique=None, default=None)
2521 _changeset_cache = Column(
2522 "changeset_cache", LargeBinary(), nullable=True) # JSON data
2492 2523
2493 2524 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
2494 2525 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
@@ -2513,6 +2544,29 b' class RepoGroup(Base, BaseModel):'
2513 2544 self._group_name = value
2514 2545 self.group_name_hash = self.hash_repo_group_name(value)
2515 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
2516 2570 @validates('group_parent_id')
2517 2571 def validate_group_parent_id(self, key, val):
2518 2572 """
@@ -2608,8 +2662,7 b' class RepoGroup(Base, BaseModel):'
2608 2662 return q.all()
2609 2663
2610 2664 @property
2611 def parents(self):
2612 parents_recursion_limit = 10
2665 def parents(self, parents_recursion_limit = 10):
2613 2666 groups = []
2614 2667 if self.parent_group is None:
2615 2668 return groups
@@ -2632,6 +2685,20 b' class RepoGroup(Base, BaseModel):'
2632 2685 return groups
2633 2686
2634 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
2635 2702 def last_db_change(self):
2636 2703 return self.updated_on
2637 2704
@@ -2670,7 +2737,7 b' class RepoGroup(Base, BaseModel):'
2670 2737
2671 2738 return cnt + children_count(self)
2672 2739
2673 def _recursive_objects(self, include_repos=True):
2740 def _recursive_objects(self, include_repos=True, include_groups=True):
2674 2741 all_ = []
2675 2742
2676 2743 def _get_members(root_gr):
@@ -2680,11 +2747,16 b' class RepoGroup(Base, BaseModel):'
2680 2747 childs = root_gr.children.all()
2681 2748 if childs:
2682 2749 for gr in childs:
2683 all_.append(gr)
2750 if include_groups:
2751 all_.append(gr)
2684 2752 _get_members(gr)
2685 2753
2754 root_group = []
2755 if include_groups:
2756 root_group = [self]
2757
2686 2758 _get_members(self)
2687 return [self] + all_
2759 return root_group + all_
2688 2760
2689 2761 def recursive_groups_and_repos(self):
2690 2762 """
@@ -2698,6 +2770,12 b' class RepoGroup(Base, BaseModel):'
2698 2770 """
2699 2771 return self._recursive_objects(include_repos=False)
2700 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
2701 2779 def get_new_name(self, group_name):
2702 2780 """
2703 2781 returns new full group name based on parent and new name
@@ -2708,6 +2786,63 b' class RepoGroup(Base, BaseModel):'
2708 2786 self.parent_group else [])
2709 2787 return RepoGroup.url_sep().join(path_prefix + [group_name])
2710 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
2711 2846 def permissions(self, with_admins=True, with_owner=True,
2712 2847 expand_from_user_groups=False):
2713 2848 """
@@ -4301,9 +4436,9 b' class Gist(Base, BaseModel):'
4301 4436
4302 4437 def scm_instance(self, **kwargs):
4303 4438 """
4304 Get explicit Mercurial repository used
4439 Get an instance of VCS Repository
4440
4305 4441 :param kwargs:
4306 :return:
4307 4442 """
4308 4443 from rhodecode.model.gist import GistModel
4309 4444 full_repo_path = os.path.join(self.base_path(), self.gist_access_id)
@@ -4953,8 +5088,8 b' class FileStore(Base, BaseModel):'
4953 5088
4954 5089 @classmethod
4955 5090 def create(cls, file_uid, filename, file_hash, file_size, file_display_name='',
4956 file_description='', enabled=True, check_acl=True,
4957 user_id=None, scope_repo_id=None, scope_repo_group_id=None):
5091 file_description='', enabled=True, check_acl=True, user_id=None,
5092 scope_user_id=None, scope_repo_id=None, scope_repo_group_id=None):
4958 5093
4959 5094 store_entry = FileStore()
4960 5095 store_entry.file_uid = file_uid
@@ -4968,6 +5103,7 b' class FileStore(Base, BaseModel):'
4968 5103 store_entry.enabled = enabled
4969 5104
4970 5105 store_entry.user_id = user_id
5106 store_entry.scope_user_id = scope_user_id
4971 5107 store_entry.scope_repo_id = scope_repo_id
4972 5108 store_entry.scope_repo_group_id = scope_repo_group_id
4973 5109 return store_entry
@@ -683,6 +683,7 b' class PullRequestModel(BaseModel):'
683 683
684 684 # source repo
685 685 source_repo = pull_request.source_repo.scm_instance()
686
686 687 try:
687 688 source_commit = source_repo.get_commit(commit_id=source_ref_name)
688 689 except CommitDoesNotExistError:
@@ -696,6 +697,7 b' class PullRequestModel(BaseModel):'
696 697
697 698 # target repo
698 699 target_repo = pull_request.target_repo.scm_instance()
700
699 701 try:
700 702 target_commit = target_repo.get_commit(commit_id=target_ref_name)
701 703 except CommitDoesNotExistError:
@@ -752,8 +754,8 b' class PullRequestModel(BaseModel):'
752 754 target_commit.raw_id, source_commit.raw_id, source_repo, merge=True,
753 755 pre_load=pre_load)
754 756
755 ancestor = target_repo.get_common_ancestor(
756 target_commit.raw_id, source_commit.raw_id, source_repo)
757 ancestor = source_repo.get_common_ancestor(
758 source_commit.raw_id, target_commit.raw_id, target_repo)
757 759
758 760 pull_request.source_ref = '%s:%s:%s' % (
759 761 source_ref_type, source_ref_name, source_commit.raw_id)
@@ -1337,6 +1339,7 b' class PullRequestModel(BaseModel):'
1337 1339 name_or_id = reference.name
1338 1340 else:
1339 1341 name_or_id = reference.commit_id
1342
1340 1343 refreshed_commit = vcs_repository.get_commit(name_or_id)
1341 1344 refreshed_reference = Reference(
1342 1345 reference.type, reference.name, refreshed_commit.raw_id)
@@ -192,14 +192,14 b' class RepoModel(BaseModel):'
192 192 return repo_log
193 193
194 194 @classmethod
195 def update_repoinfo(cls, repositories=None):
195 def update_commit_cache(cls, repositories=None):
196 196 if not repositories:
197 197 repositories = Repository.getAll()
198 198 for repo in repositories:
199 199 repo.update_commit_cache()
200 200
201 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 203 _render = get_current_request().get_partial_renderer(
204 204 'rhodecode:templates/data_table/_dt_elements.mako')
205 205 c = _render.get_call_context()
@@ -208,8 +208,12 b' class RepoModel(BaseModel):'
208 208 return _render('quick_menu', repo_name)
209 209
210 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 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 218 def last_change(last_change):
215 219 if admin and isinstance(last_change, datetime.datetime) and not last_change.tzinfo:
@@ -250,8 +254,8 b' class RepoModel(BaseModel):'
250 254 repo.private, repo.archived, repo.fork),
251 255 "name_raw": repo.repo_name.lower(),
252 256
253 "last_change": last_change(repo.last_db_change),
254 "last_change_raw": datetime_to_time(repo.last_db_change),
257 "last_change": last_change(repo.last_commit_change),
258 "last_change_raw": datetime_to_time(repo.last_commit_change),
255 259
256 260 "last_changeset": last_rev(repo.repo_name, cs_cache),
257 261 "last_changeset_raw": cs_cache.get('revision'),
@@ -309,6 +309,10 b' class RepoGroupModel(BaseModel):'
309 309 # trigger the post hook
310 310 from rhodecode.lib.hooks_base import log_create_repository_group
311 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
312 316 log_create_repository_group(
313 317 created_by=user.username, **repo_group.get_dict())
314 318
@@ -686,6 +690,13 b' class RepoGroupModel(BaseModel):'
686 690 'revoked permission from usergroup: {} on repogroup: {}'.format(
687 691 group_name, repo_group), namespace='security.repogroup')
688 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
689 700 def get_repo_groups_as_dict(self, repo_group_list=None, admin=False,
690 701 super_user_actions=False):
691 702
@@ -707,6 +718,11 b' class RepoGroupModel(BaseModel):'
707 718 (datetime.datetime.now() - datetime.datetime.utcnow()).seconds)
708 719 return _render("last_change", last_change)
709 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
710 726 def desc(desc, personal):
711 727 return _render(
712 728 'repo_group_desc', desc, personal, c.visual.stylify_metatags)
@@ -723,13 +739,15 b' class RepoGroupModel(BaseModel):'
723 739
724 740 repo_group_data = []
725 741 for group in repo_group_list:
742 cs_cache = group.changeset_cache
743 last_repo_name = cs_cache.get('source_repo_name')
726 744
727 745 row = {
728 746 "menu": quick_menu(group.group_name),
729 747 "name": repo_group_lnk(group.group_name),
730 748 "name_raw": group.group_name,
731 "last_change": last_change(group.last_db_change),
732 "last_change_raw": datetime_to_time(group.last_db_change),
749 "last_change": last_change(group.last_commit_change),
750 "last_change_raw": datetime_to_time(group.last_commit_change),
733 751
734 752 "last_changeset": "",
735 753 "last_changeset_raw": "",
@@ -818,6 +818,8 b' class ScmModel(BaseModel):'
818 818 repo_name=repo.repo_name, repo_alias=scm_instance.alias,
819 819 commit_ids=[tip.raw_id])
820 820
821 return tip
822
821 823 def delete_nodes(self, user, repo, message, nodes, parent_commit=None,
822 824 author=None, trigger_push_hook=True):
823 825 """
@@ -14,11 +14,11 b' input[type="button"] {'
14 14 font-family: @text-light;
15 15 text-decoration: none;
16 16 text-shadow: none;
17 color: @grey4;
17 color: @grey2;
18 18 background-color: white;
19 19 background-image: none;
20 20 border: none;
21 .border ( @border-thickness-buttons, @grey4 );
21 .border ( @border-thickness-buttons, @grey5 );
22 22 .border-radius (@border-radius);
23 23 cursor: pointer;
24 24 white-space: nowrap;
@@ -26,6 +26,10 b' input[type="button"] {'
26 26 -moz-transition: background .3s,color .3s;
27 27 -o-transition: background .3s,color .3s;
28 28 transition: background .3s,color .3s;
29 box-shadow: @button-shadow;
30 -webkit-box-shadow: @button-shadow;
31
32
29 33
30 34 a {
31 35 display: block;
@@ -44,8 +48,9 b' input[type="button"] {'
44 48 outline:none;
45 49 }
46 50 &:hover {
47 color: white;
48 background-color: @grey4;
51 color: @rcdarkblue;
52 background-color: @white;
53 .border ( @border-thickness, @grey4 );
49 54 }
50 55
51 56 .icon-remove-sign {
@@ -70,26 +75,26 b' input[type="button"] {'
70 75
71 76
72 77 .btn-default {
73 .border ( @border-thickness-buttons, @rcblue );
78 border: @border-thickness solid @grey5;
74 79 background-image: none;
75 color: @rcblue;
80 color: @grey2;
76 81
77 82 a {
78 color: @rcblue;
83 color: @grey2;
79 84 }
80 85
81 86 &:hover,
82 87 &.active {
83 color: white;
84 background-color: @rcdarkblue;
85 .border ( @border-thickness, @rcdarkblue );
88 color: @rcdarkblue;
89 background-color: @white;
90 .border ( @border-thickness, @grey4 );
86 91
87 92 a {
88 color: white;
93 color: @grey2;
89 94 }
90 95 }
91 96 &:disabled {
92 .border ( @border-thickness-buttons, @grey4 );
97 .border ( @border-thickness-buttons, @grey5 );
93 98 background-color: transparent;
94 99 }
95 100 }
@@ -326,6 +331,7 b' input[type="submit"] {'
326 331 .border ( @border-thickness-buttons, @rcblue );
327 332 background-color: @rcblue;
328 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 405 // TODO: johbo: Added interim to get rid of the margin around
406 406 // Select2 widgets. This needs further cleanup.
407 margin-top: @padding;
408
409 407 overflow: auto;
410 408 padding: 0px;
411 border: @border-thickness solid @grey5;
412 background: @grey6;
409 border: @border-thickness solid @grey6;
413 410 .border-radius(@border-radius);
414 411
415 412 #remove_gist {
@@ -479,7 +476,7 b' div.codeblock {'
479 476 }
480 477
481 478 .code-body {
482 padding: @padding;
479 padding: 0.8em 1em;
483 480 background-color: #ffffff;
484 481 min-width: 100%;
485 482 box-sizing: border-box;
@@ -492,6 +489,21 b' div.codeblock {'
492 489 height: auto;
493 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 28 .CodeMirror-gutters {
29 29 border-right: 1px solid #ddd;
30 background-color: @grey6;
30 background-color: white;
31 31 white-space: nowrap;
32 32 }
33 33 .CodeMirror-linenumbers {}
@@ -14,7 +14,7 b' tr.inline-comments div {'
14 14 max-width: 100%;
15 15
16 16 p {
17 white-space: normal;
17 white-space: normal;
18 18 }
19 19
20 20 code, pre, .code, dd {
@@ -227,7 +227,7 b' tr.inline-comments div {'
227 227 .delete-comment {
228 228 display: inline-block;
229 229 color: @rcblue;
230
230
231 231 &:hover {
232 232 cursor: pointer;
233 233 }
@@ -377,13 +377,13 b' form.comment-form {'
377 377 position: relative;
378 378 width: 100%;
379 379 min-height: 42px;
380
380
381 381 .status_box,
382 382 .cancel-button {
383 383 float: left;
384 384 display: inline-block;
385 385 }
386
386
387 387 .action-buttons {
388 388 float: right;
389 389 display: inline-block;
@@ -426,10 +426,10 b' form.comment-form {'
426 426
427 427 .comment-form-login {
428 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 {
433 433 clear: both;
434 434 width: 100%;
435 435 display: block;
@@ -38,7 +38,7 b''
38 38
39 39 .form-control {
40 40 width: 100%;
41 padding: 0.9em;
41 padding: 0.7em;
42 42 border: 1px solid #979797;
43 43 border-radius: 2px;
44 44 }
@@ -60,13 +60,13 b' form.rcform {'
60 60 max-width: 500px;
61 61 margin: 0 0 @padding -@legend-width;
62 62 padding: 0 0 0 @legend-width;
63
63
64 64 .btn {
65 65 display: inline-block;
66 66 margin: 0 1em @padding 0;
67 67 }
68 68 }
69
69
70 70 input,
71 71 textarea {
72 72 float: left;
@@ -113,7 +113,7 b' form.rcform {'
113 113 opacity: 0.5;
114 114 }
115 115 }
116
116
117 117 input[type="radio"]:not(#ie),
118 118 input[type="checkbox"]:not(#ie) {
119 119 // Hide the input, but have it still be clickable
@@ -187,13 +187,13 b' form.rcform {'
187 187 filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476); /* IE6,IE7 */
188 188
189 189 -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476)"; /* IE8 */ }
190
190
191 191 & + .label {
192 192 float: left;
193 193 margin-top: 5px
194 194 }
195 195 }
196
196
197 197 input[type=checkbox]:not(#ie) {
198 198 visibility: hidden;
199 199 &:checked + label:after {
@@ -231,6 +231,11 b' form.rcform {'
231 231
232 232 .drop-menu {
233 233 float: left;
234
235 & + .last-item {
236 margin: 0;
237 }
238
234 239 margin: 0 @input-padding 0 0;
235 240 }
236 241
@@ -244,7 +249,7 b' form.rcform {'
244 249 .error-message {
245 250 margin-top: 5px;
246 251 }
247
252
248 253 input[type=submit] {
249 254 &:extend(.btn-primary);
250 255
@@ -271,14 +276,15 b' form.rcform {'
271 276 .badged-field {
272 277 .user-badge {
273 278 line-height: 25px;
274 padding: 10px 5px;
279 padding: .4em;
275 280 border-radius: @border-radius;
276 border-top: 1px solid @rclightblue;
277 border-left: 1px solid @rclightblue;
278 border-bottom: 1px solid @rclightblue;
281 border-top: 1px solid @grey4;
282 border-left: 1px solid @grey4;
283 border-bottom: 1px solid @grey4;
279 284 font-size: 14px;
280 285 font-style: normal;
281 286 color: @text-light;
287 background: @grey7;
282 288 display: inline-block;
283 289 vertical-align: top;
284 290 cursor: default;
@@ -212,6 +212,13 b' div.markdown-block strong {'
212 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 222 div.markdown-block ul,
216 223 div.markdown-block ol {
217 224 padding-left: 30px !important;
@@ -219,6 +226,13 b' div.markdown-block ol {'
219 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 236 div.markdown-block ul li,
223 237 div.markdown-block ol li {
224 238 list-style: disc !important;
@@ -95,7 +95,7 b''
95 95 margin: 0 1em @padding 0;
96 96 }
97 97 }
98
98
99 99 .checkbox {
100 100 display: inline;
101 101 width: auto;
@@ -198,15 +198,16 b''
198 198 }
199 199
200 200 .user-menu.submenu {
201 right: 0;
202 left: auto;
201 right: 0!important;
202 left: auto!important;
203 203 min-width: 290px;
204 204 }
205 205
206
207 206 .user-menu {
208 207 .bookmark-items {
209 padding: 4px 2px;
208 border-top: @border-thickness solid @grey6;
209 margin-top: 1em;
210 padding: 1em .5em;
210 211 color: @grey3;
211 212 border-bottom: @grey3;
212 213
@@ -227,8 +228,10 b''
227 228 padding: @menupadding;
228 229 z-index: 999;
229 230 overflow: hidden;
230 background-color: @grey6;
231 background-color: @white;
232 border: 1px solid @grey5;
231 233 color: @grey2;
234 box-shadow: @dropdown-shadow;
232 235
233 236 h4 {
234 237 margin-bottom: 12px;
@@ -261,7 +264,7 b''
261 264 .buttons .register {
262 265 a {
263 266 color: @rcblue;
264
267
265 268 &:hover {
266 269 color: @rcdarkblue;
267 270 }
@@ -289,15 +292,16 b''
289 292 .big_gravatar {
290 293 float: left;
291 294 display: block;
292 margin-top: .5em;
295 padding: .5em;
293 296 }
294 297
295 .full_name,
296 .email {
297 margin: 0 0 0 65px;
298 .full_name {
299 margin: 0 0 0 70px;
300 padding-top: 1em;
298 301 }
299 302
300 303 .email {
304 margin: 0 0 0 70px;
301 305 font-family: @text-light;
302 306 }
303 307
@@ -307,8 +311,6 b''
307 311 padding: @padding 0 0 0;
308 312
309 313 li {
310 border-top: @border-thickness solid @grey5;
311
312 314 input {
313 315 margin: @padding 0 0 0;
314 316 }
@@ -107,6 +107,12 b' input + .action-link, .action-link.first'
107 107
108 108 .clipboard-action {
109 109 cursor: pointer;
110 color: @grey4;
111 margin-left: 5px;
112
113 &:hover {
114 color: @grey2;
115 }
110 116 }
111 117
112 118 ul.simple-list{
@@ -237,7 +243,7 b' input.inline[type="file"] {'
237 243 position: relative;
238 244 vertical-align: bottom;
239 245 padding: 0 @header-padding;
240 background-color: @grey2;
246 background-color: @grey1;
241 247 color: @grey5;
242 248
243 249 .title {
@@ -271,7 +277,9 b' input.inline[type="file"] {'
271 277 // Gists
272 278 #files_data {
273 279 clear: both; //for firefox
280 padding-top: 10px;
274 281 }
282
275 283 #gistid {
276 284 margin-right: @padding;
277 285 }
@@ -516,7 +524,7 b' ul.auth_plugins {'
516 524 text-align: center;
517 525 vertical-align: middle;
518 526 color: @grey2;
519 background-color: @grey6;
527 font-size: 11px;
520 528
521 529 p {
522 530 margin: 0;
@@ -605,10 +613,20 b' button.close {'
605 613 }
606 614
607 615
608 input {
616 input, textarea {
609 617 &.disabled {
610 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 632 // remove extra padding in firefox
@@ -643,16 +661,20 b' select {'
643 661 padding: 0 18px 0 8px;
644 662 line-height:1em;
645 663 font-size: @basefontsize;
646 border: @border-thickness solid @rcblue;
664 border: @border-thickness solid @grey5;
665 border-radius: @border-radius;
647 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 670 &:after {
651 671 content: "\00A0\25BE";
652 672 }
653 673
654 &:focus {
674 &:focus, &:hover {
655 675 outline: none;
676 border-color: @grey4;
677 color: @rcdarkblue;
656 678 }
657 679 }
658 680
@@ -712,8 +734,8 b' label {'
712 734 margin: -5px 0;
713 735 padding: 0;
714 736 line-height: 1em;
715 border: 1px solid @grey4;
716 737 box-sizing: content-box;
738 border-radius: 50%;
717 739
718 740 &.gravatar-large {
719 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 964 #graph_content{
946 965
@@ -973,13 +992,12 b' label {'
973 992 }
974 993
975 994 .graph-col-wrapper {
976 padding-left: 110px;
977 995
978 996 #graph_nodes {
979 997 width: 100px;
980 margin-left: -110px;
981 float: left;
982 clear: left;
998 position: absolute;
999 left: 70px;
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 1027 #filter_changelog {
1000 1028 float: left;
1001 1029 }
@@ -1051,7 +1079,7 b' label {'
1051 1079 }
1052 1080
1053 1081 .flag_status {
1054 margin: 2px 8px 6px 2px;
1082 margin: 2px;
1055 1083 &.under_review {
1056 1084 .circle(5px, @alert3);
1057 1085 }
@@ -1222,24 +1250,37 b' table.integrations {'
1222 1250
1223 1251 .autocomplete-suggestions {
1224 1252 width: auto !important; // overrides autocomplete.js
1253 min-width: 278px;
1225 1254 margin: 0;
1226 border: @border-thickness solid @rcblue;
1255 border: @border-thickness solid @grey5;
1227 1256 border-radius: @border-radius;
1228 color: @rcblue;
1257 color: @grey2;
1229 1258 background-color: white;
1230 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
1231 1271 .autocomplete-selected {
1232 1272 background: #F0F0F0;
1233 1273 }
1274
1234 1275 .ac-container-wrap {
1235 1276 margin: 0;
1236 1277 padding: 8px;
1237 border-bottom: @border-thickness solid @rclightblue;
1278 border-bottom: @border-thickness solid @grey5;
1238 1279 list-style-type: none;
1239 1280 cursor: pointer;
1240 1281
1241 1282 &:hover {
1242 background-color: @rclightblue;
1283 background-color: @grey7;
1243 1284 }
1244 1285
1245 1286 img {
@@ -1294,9 +1335,9 b' table.integrations {'
1294 1335 }
1295 1336 }
1296 1337
1297 #editor_container{
1298 position: relative;
1299 margin: @padding;
1338 #editor_container {
1339 position: relative;
1340 margin: @padding 10px;
1300 1341 }
1301 1342 }
1302 1343
@@ -1800,7 +1841,6 b' BIN_FILENODE = 7'
1800 1841 }
1801 1842
1802 1843 #changeset_compare_view_content {
1803 margin-bottom: @space;
1804 1844 clear: both;
1805 1845 width: 100%;
1806 1846 box-sizing: border-box;
@@ -2031,15 +2071,15 b' BIN_FILENODE = 7'
2031 2071
2032 2072 // Files
2033 2073 .edit-file-title {
2034 border-bottom: @border-thickness solid @border-default-color;
2035
2036 .breadcrumbs {
2037 margin-bottom: 0;
2074 font-size: 16px;
2075
2076 .title-heading {
2077 padding: 2px;
2038 2078 }
2039 2079 }
2040 2080
2041 2081 .edit-file-fieldset {
2042 margin-top: @sidebarpadding;
2082 margin: @sidebarpadding 0;
2043 2083
2044 2084 .fieldset {
2045 2085 .left-label {
@@ -2084,8 +2124,29 b' BIN_FILENODE = 7'
2084 2124 .new-file,
2085 2125 #filter_activate,
2086 2126 #filter_deactivate {
2087 float: left;
2088 margin: 0 0 0 15px;
2127 float: right;
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
2089 2150 }
2090 2151
2091 2152 h3.files_location{
@@ -2093,11 +2154,12 b' h3.files_location{'
2093 2154 }
2094 2155
2095 2156 .browser-nav {
2157 width: 100%;
2096 2158 display: table;
2097 margin-bottom: @space;
2098
2159 margin-bottom: 20px;
2099 2160
2100 2161 .info_box {
2162 float: left;
2101 2163 display: inline-table;
2102 2164 height: 2.5em;
2103 2165
@@ -2106,36 +2168,58 b' h3.files_location{'
2106 2168 vertical-align: middle;
2107 2169 }
2108 2170
2171 .drop-menu {
2172 margin: 0 10px;
2173 }
2174
2109 2175 .info_box_elem {
2110 border-top: @border-thickness solid @rcblue;
2111 border-bottom: @border-thickness solid @rcblue;
2176 border-top: @border-thickness solid @grey5;
2177 border-bottom: @border-thickness solid @grey5;
2178 box-shadow: @button-shadow;
2112 2179
2113 2180 #at_rev, a {
2114 padding: 0.6em 0.9em;
2181 padding: 0.6em 0.4em;
2115 2182 margin: 0;
2116 2183 .box-shadow(none);
2117 2184 border: 0;
2118 2185 height: 12px;
2186 color: @grey2;
2119 2187 }
2120 2188
2121 2189 input#at_rev {
2122 2190 max-width: 50px;
2123 text-align: right;
2191 text-align: center;
2124 2192 }
2125 2193
2126 2194 &.previous {
2127 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
2128 2203 .disabled {
2129 color: @grey4;
2204 color: @grey5;
2130 2205 cursor: not-allowed;
2206 opacity: 0.5;
2131 2207 }
2132 2208 }
2133 2209
2134 2210 &.next {
2135 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
2136 2219 .disabled {
2137 color: @grey4;
2220 color: @grey5;
2138 2221 cursor: not-allowed;
2222 opacity: 0.5;
2139 2223 }
2140 2224 }
2141 2225 }
@@ -2152,8 +2236,14 b' h3.files_location{'
2152 2236 margin-right: @padding;
2153 2237 }
2154 2238 }
2239
2155 2240 }
2156 2241
2242 .select-index-number {
2243 margin: 0 0 0 20px;
2244 color: @grey3;
2245 }
2246
2157 2247 .search_activate {
2158 2248 display: table-cell;
2159 2249 vertical-align: middle;
@@ -2182,26 +2272,54 b' h3.files_location{'
2182 2272 margin: -25px 0px 5px 0px;
2183 2273 }
2184 2274
2185 .node-filter {
2186 font-size: @repo-title-fontsize;
2187 padding: 4px 0px 0px 0px;
2188
2189 .node-filter-path {
2190 float: left;
2191 color: @grey4;
2275 .files-quick-filter {
2276 float: right;
2277 width: 180px;
2278 position: relative;
2279 }
2280
2281 .files-filter-box {
2282 display: flex;
2283 padding: 0px;
2284 border-radius: 3px;
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
2308 input {
2309 border: 1px solid @white;
2310 padding-left: 25px;
2311 width: 145px;
2312
2313 &:hover {
2314 border-color: @grey6;
2192 2315 }
2193 .node-filter-input {
2194 float: left;
2195 margin: -2px 0px 0px 2px;
2196 input {
2197 padding: 2px;
2198 border: none;
2199 font-size: @repo-title-fontsize;
2200 }
2316
2317 &:focus {
2318 border-color: @grey5;
2201 2319 }
2320 }
2202 2321 }
2203 2322
2204
2205 2323 .browser-result{
2206 2324 td a{
2207 2325 margin-left: 0.5em;
@@ -2219,6 +2337,142 b' h3.files_location{'
2219 2337 }
2220 2338
2221 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
2222 2476 // Search
2223 2477
2224 2478 .search-form{
@@ -2281,7 +2535,7 b' div.search-code-body {'
2281 2535 }
2282 2536
2283 2537 .code-body {
2284 border: @border-thickness solid @border-default-color;
2538 border: @border-thickness solid @grey6;
2285 2539 .border-radius(@border-radius);
2286 2540 }
2287 2541
@@ -2301,6 +2555,11 b' div.search-code-body {'
2301 2555 .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; }
2302 2556 }
2303 2557
2558 .path {
2559 border-bottom: none !important;
2560 border-left: 1px solid @grey6 !important;
2561 border-right: 1px solid @grey6 !important;
2562 }
2304 2563 }
2305 2564
2306 2565 table.rctable td.td-search-results div {
@@ -2476,3 +2735,56 b' form.markup-form {'
2476 2735 padding: 20px;
2477 2736 background-color: white;
2478 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 2 // For use in RhodeCode applications;
3 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 17 // HEADER NAVIGATION
6 18
7 19 .horizontal-list {
8 float: right;
9 20 display: block;
10 21 margin: 0;
11 22 padding: 0;
@@ -18,6 +29,7 b''
18 29 li {
19 30 line-height: 1em;
20 31 list-style-type: none;
32 margin: 0 20px 0 0;
21 33
22 34 a {
23 35 padding: 0 .5em;
@@ -55,12 +67,6 b''
55 67 .user {
56 68 padding-bottom: 10px;
57 69 }
58
59 &.open {
60 .user {
61 border-bottom: 5px solid @rcblue;
62 }
63 }
64 70 }
65 71
66 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 89 &.open {
88 90
89 91 a {
@@ -118,14 +120,12 b''
118 120 > a,
119 121 &.has_select2 a {
120 122 display: block;
121 padding: 10px 0 2px;
123 padding: 10px 0;
122 124 }
123 125
124 126 .menulabel {
125 padding: 0 .5em;
126 127 line-height: 1em;
127 128 // for this specifically we do not use a variable
128 border-right: 1px solid @grey4;
129 129 }
130 130
131 131 .pr_notifications {
@@ -141,7 +141,7 b''
141 141 &.open,
142 142 &.active {
143 143 a {
144 color: @grey1;
144 color: @rcblue;
145 145 }
146 146 }
147 147 }
@@ -156,6 +156,14 b''
156 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 167 #quick_login {
160 168
161 169 li a {
@@ -281,16 +289,19 b''
281 289 }
282 290
283 291 .navigation li:last-child .submenu {
284 right: -20px;
285 left: auto;
292 right: auto;
293 left: 0;
294 border: 1px solid @grey5;
295 background: @white;
296 box-shadow: @dropdown-shadow;
286 297 }
287 298
288 299 .submenu {
289 300 position: absolute;
290 301 top: 100%;
291 302 left: 0;
292 min-width: 150px;
293 margin: 6px 0 0;
303 min-width: 180px;
304 margin: 2px 0 0;
294 305 padding: 0;
295 306 text-align: left;
296 307 font-family: @text-light;
@@ -303,7 +314,7 b''
303 314 padding: 0 .5em;
304 315 line-height: 1em;
305 316 color: @grey3;
306 background-color: @grey6;
317 background-color: @white;
307 318 list-style-type: none;
308 319
309 320 a {
@@ -324,7 +335,7 b''
324 335 z-index: 30;
325 336 }
326 337 &:hover {
327 background-color: @grey5;
338 background-color: @grey7;
328 339 -webkit-transition: background .3s;
329 340 -moz-transition: background .3s;
330 341 -o-transition: background .3s;
@@ -501,10 +512,10 b''
501 512
502 513 #context-bar {
503 514 display: block;
504 margin: 0 auto;
515 margin: 0 auto 20px 0;
505 516 padding: 0 @header-padding;
506 background-color: @grey6;
507 border-bottom: @border-thickness solid @grey5;
517 background-color: @grey7;
518 border-bottom: 1px solid @grey5;
508 519
509 520 .clear {
510 521 clear: both;
@@ -513,19 +524,22 b''
513 524
514 525 ul#context-pages {
515 526 li {
516 line-height: 1em;
517 527 list-style-type: none;
518 528
519 529 a {
520 color: @grey3;
530 color: @grey2;
531
532 &:hover {
533 color: @grey1;
534 }
521 535 }
522 536
523 537 &.active {
524 538 // special case, non-variable color
525 border-bottom: 4px solid @nav-grey;
539 border-bottom: 2px solid @rcblue;
526 540
527 541 a {
528 color: @grey1;
542 color: @rcblue;
529 543 }
530 544 }
531 545 }
@@ -534,8 +548,9 b' ul#context-pages {'
534 548 // PAGINATION
535 549
536 550 .pagination {
537 border: @border-thickness solid @rcblue;
538 color: @rcblue;
551 border: @border-thickness solid @grey5;
552 color: @grey2;
553 box-shadow: @button-shadow;
539 554
540 555 .current {
541 556 color: @grey4;
@@ -552,33 +567,44 b' ul#context-pages {'
552 567 .dataTables_paginate, .pagination-wh {
553 568 text-align: left;
554 569 display: inline-block;
555 border-left: 1px solid @rcblue;
570 border-left: 1px solid @grey5;
556 571 float: none;
557 572 overflow: hidden;
573 box-shadow: @button-shadow;
558 574
559 575 .paginate_button, .pager_curpage,
560 576 .pager_link, .pg-previous, .pg-next, .pager_dotdot {
561 577 display: inline-block;
562 578 padding: @menupadding/4 @menupadding;
563 border: 1px solid @rcblue;
579 border: 1px solid @grey5;
564 580 border-left: 0;
565 color: @rcblue;
581 color: @grey2;
566 582 cursor: pointer;
567 583 float: left;
584
585 &:hover {
586 color: @rcdarkblue;
587 }
568 588 }
569 589
570 .pager_curpage, .pager_dotdot,
571 .paginate_button.current, .paginate_button.disabled,
590 .paginate_button.disabled,
572 591 .disabled {
573 592 color: @grey3;
574 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 603 .ellipsis {
578 604 display: inline-block;
579 605 text-align: left;
580 606 padding: @menupadding/4 @menupadding;
581 border: 1px solid @rcblue;
607 border: 1px solid @grey5;
582 608 border-left: 0;
583 609 float: left;
584 610 }
@@ -595,14 +621,6 b' ul#context-pages {'
595 621 font-family: @text-regular;
596 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 624 .nav-pills {
607 625 margin: 0;
608 626 }
@@ -631,14 +649,11 b' ul#context-pages {'
631 649
632 650 .main_filter_help_box {
633 651 padding: 7px 7px;
634 border-top: 1px solid @grey4;
635 border-right: 1px solid @grey4;
636 border-bottom: 1px solid @grey4;
637 652 display: inline-block;
638 653 vertical-align: top;
639 654 background: inherit;
640 655 position: absolute;
641 right: 8px;
656 right: 0;
642 657 top: 9px;
643 658 }
644 659
@@ -647,8 +662,10 b' ul#context-pages {'
647 662
648 663 .searchItems {
649 664 display:flex;
650 background: #666666;
665 background: @black;
651 666 padding: 0px;
667 border-radius: 3px;
668 border: 1px solid @black;
652 669
653 670 a {
654 671 border: none !important;
@@ -657,26 +674,30 b' ul#context-pages {'
657 674
658 675 .searchTag {
659 676 line-height: 28px;
660 padding: 0px 4px;
677 padding: 0 5px;
661 678
662 679 .tag {
663 color: @nav-grey;
664 border-color: @nav-grey;
680 color: @grey5;
681 border-color: @grey2;
682 background: @grey1;
665 683 }
666 684 }
667 685
668 686 .searchTagFilter {
669 background-color: @grey3 !important;
687 background-color: @black !important;
688 margin-right: 0;
670 689 }
671 690
672 691 .searchTagHelp {
673 background-color: @grey2 !important;
692 background-color: @grey1 !important;
693 margin: 0;
674 694 }
675 695 .searchTagHelp:hover {
676 background-color: @grey2 !important;
696 background-color: @grey1 !important;
677 697 }
678 698 .searchTagInput {
679 background-color: @grey3 !important;
699 background-color: @grey1 !important;
700 margin-right: 0;
680 701 }
681 702 }
682 703
@@ -685,32 +706,33 b' ul#context-pages {'
685 706 }
686 707
687 708 #main_filter_help {
688 background: @grey3;
709 background: @grey1;
689 710 border: 1px solid black;
690 711 position: absolute;
691 712 white-space: pre;
692 713 z-index: 9999;
693 714 color: @nav-grey;
694 margin: 1px 7px;
695 715 padding: 0 10px;
696 716 }
697 717
698 .main_filter_input {
699 padding: 5px;
700 min-width: 260px;
701 color: @nav-grey;
702 background: @grey3;
703 min-height: 18px;
704 border:none;
705 border-radius: 0;
718 input {
706 719
707 &:active {
708 color: @grey2 !important;
709 background: white !important;
710 }
711 &:focus {
712 color: @grey2 !important;
713 background: white !important;
720 &.main_filter_input {
721 padding: 5px 10px;
722 min-width: 340px;
723 color: @grey7;
724 background: @black;
725 min-height: 18px;
726 border: 0;
727
728 &:active {
729 color: @grey2 !important;
730 background: white !important;
731 }
732 &:focus {
733 color: @grey2 !important;
734 background: white !important;
735 }
714 736 }
715 737 }
716 738
@@ -47,7 +47,7 b''
47 47 min-height: 150px
48 48 }
49 49 }
50
50
51 51 .panel-footer {
52 52 background-color: white;
53 53 padding: .65em @panel-padding .5em;
@@ -63,10 +63,6 b''
63 63 &.user-profile {
64 64 float: left;
65 65
66 .panel-heading {
67 margin-bottom: @padding;
68 }
69
70 66 .panel-body {
71 67 &:extend(.clearfix);
72 68 }
@@ -1,11 +1,13 b''
1 1 @font-face {
2 2 font-family: 'rcicons';
3 src: url('../fonts/RCIcons/rcicons.eot?74666722');
4 src: url('../fonts/RCIcons/rcicons.eot?74666722#iefix') format('embedded-opentype'),
5 url('../fonts/RCIcons/rcicons.woff2?74666722') format('woff2'),
6 url('../fonts/RCIcons/rcicons.woff?74666722') format('woff'),
7 url('../fonts/RCIcons/rcicons.ttf?74666722') format('truetype'),
8 url('../fonts/RCIcons/rcicons.svg?74666722#rcicons') format('svg');
3
4 src: url('../fonts/RCIcons/rcicons.eot?92789106');
5 src: url('../fonts/RCIcons/rcicons.eot?92789106#iefix') format('embedded-opentype'),
6 url('../fonts/RCIcons/rcicons.woff2?92789106') format('woff2'),
7 url('../fonts/RCIcons/rcicons.woff?92789106') format('woff'),
8 url('../fonts/RCIcons/rcicons.ttf?92789106') format('truetype'),
9 url('../fonts/RCIcons/rcicons.svg?92789106#rcicons') format('svg');
10
9 11 font-weight: normal;
10 12 font-style: normal;
11 13 }
@@ -55,78 +57,164 b''
55 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 145 .icon-no-margin::before {
59 146 margin: 0;
60 147
61 148 }
62 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 155 .icon-bookmark:before { content: '\e803'; } /* '' */
65 156 .icon-branch:before { content: '\e804'; } /* '' */
157 .icon-tag:before { content: '\e805'; } /* '' */
66 158 .icon-lock:before { content: '\e806'; } /* '' */
67 159 .icon-unlock:before { content: '\e807'; } /* '' */
68 .icon-delete:before { content: '\e808'; } /* '' */
69 .icon-false:before { content: '\e808'; } /* '' */
70
71 .icon-ok:before { content: '\e809'; } /* '' */
72 .icon-true:before { content: '\e809'; } /* '' */
73
74 .icon-comment:before { content: '\e80a'; } /* '' */
75 .icon-comment-add:before { content: '\e816'; } /* '' */
76 .icon-comment_toggle:before { content: '\e818'; } /* '' */
77
78 .icon-feed:before { content: '\e80b'; } /* '' */
79
80 .icon-right:before { content: '\e80c'; } /* '' */
81 .icon-left:before { content: '\e80d'; } /* '' */
82
83 .icon-arrow_down:before { content: '\e80e'; } /* '' */
84 .icon-arrow_up:before { content: '\e80e'; } /* '' */
85
86 .icon-group:before { content: '\e812'; } /* '' */
87
88 .icon-fork:before { content: '\e814'; } /* '' */
89 .icon-merge:before { content: '\e814'; } /* '' */
90
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'; } /* '' */
160 .icon-feed:before { content: '\e808'; } /* '' */
161 .icon-left:before { content: '\e809'; } /* '' */
162 .icon-right:before { content: '\e80a'; } /* '' */
163 .icon-down:before { content: '\e80b'; } /* '' */
164 .icon-folder:before { content: '\e80c'; } /* '' */
165 .icon-folder-open:before { content: '\e80d'; } /* '' */
166 .icon-folder-empty:before { content: '\f114'; } /* '' */
167 .icon-folder-open-empty:before { content: '\f115'; } /* '' */
168 .icon-trash-empty:before { content: '\e80e'; } /* '' */
169 .icon-group:before { content: '\e80f'; } /* '' */
170 .icon-remove:before { content: '\e810'; } /* '' */
171 .icon-fork:before { content: '\e811'; } /* '' */
172 .icon-more:before { content: '\e812'; } /* '' */
173 .icon-search:before { content: '\e813'; } /* '' */
174 .icon-scissors:before { content: '\e814'; } /* '' */
175 .icon-download:before { content: '\e815'; } /* '' */
176 .icon-doc:before { content: '\e816'; } /* '' */
177 .icon-cog:before { content: '\e817'; } /* '' */
178 .icon-cog-alt:before { content: '\e818'; } /* '' */
179 .icon-eye:before { content: '\e819'; } /* '' */
180 .icon-eye-off:before { content: '\e81a'; } /* '' */
181 .icon-cancel-circled2:before { content: '\e81b'; } /* '' */
182 .icon-cancel-circled:before { content: '\e81c'; } /* '' */
108 183 .icon-plus:before { content: '\e81d'; } /* '' */
109 .icon-remove:before { content: '\e81e'; } /* '' */
110 .icon-remove-sign:before { content: '\e81e'; } /* '' */
111
112 .icon-rhodecode:before { content: '\e81f'; } /* '' */
113
114 .icon-tag:before { content: '\e821'; } /* '' */
115 .icon-copy:before { content: '\f0c5'; } /* '' */
116 .icon-clipboard:before { content: '\f0c5'; } /* '' */
184 .icon-plus-circled:before { content: '\e81e'; } /* '' */
185 .icon-minus-circled:before { content: '\e81f'; } /* '' */
186 .icon-minus:before { content: '\e820'; } /* '' */
187 .icon-info-circled:before { content: '\e821'; } /* '' */
188 .icon-upload:before { content: '\e822'; } /* '' */
189 .icon-home:before { content: '\e823'; } /* '' */
190 .icon-git:before { content: '\e82a'; } /* '' */
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'; } /* '' */
120 .icon-folder-close:before { content: '\e813'; } /* '' */
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
216 // MERGED ICONS BASED ON CURRENT ONES
217 .icon-repo-group:before { &:extend(.icon-folder-open:before); }
130 218 .icon-repo-private:before { &:extend(.icon-lock:before); }
131 219 .icon-repo-lock:before { &:extend(.icon-lock:before); }
132 220 .icon-unlock-alt:before { &:extend(.icon-unlock:before); }
@@ -134,9 +222,20 b''
134 222 .icon-repo-public:before { &:extend(.icon-unlock:before); }
135 223 .icon-rss-sign:before { &:extend(.icon-feed:before); }
136 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 237 // TRANSFORM
139 .icon-arrow_up:before {transform: rotate(180deg);}
238
140 239 .icon-merge:before {transform: rotate(180deg);}
141 240
142 241 // -- END ICON CLASSES -- //
@@ -152,6 +251,9 b''
152 251 .icon-svn-inv { color: @color1 !important; }
153 252 .icon-repo-lock { color: #FF0000; }
154 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 258 .repo-switcher-dropdown .select2-result-label {
157 259 .icon-git:before {
@@ -88,7 +88,6 b' div.readme_box pre {'
88 88 font-size: 13px !important;
89 89 overflow: visible !important;
90 90 line-height: 140% !important;
91 background-color: @grey7;
92 91 }
93 92
94 93 div.readme_box img {
@@ -156,10 +155,10 b' div.readme_box code {'
156 155 }
157 156
158 157 div.readme_box pre {
159 border: @border-thickness solid @grey5;
158 border: @border-thickness solid #CBDBEB;
160 159 overflow: auto;
161 160 padding: .5em;
162 background-color: @grey7;
161 background-color: #FCFEFF;
163 162 }
164 163
165 164 div.readme_box pre > code {
@@ -17,7 +17,7 b''
17 17 .select2-search,
18 18 .select2-search input {.box-sizing(border-box);}
19 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 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 22 .select2-container.select2-allowclear .select2-choice abbr {display: inline-block;}
23 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 92 min-width: 160px;
93 93 margin: 0 @padding 0 0;
94 94 padding: 0;
95 border: @border-thickness solid @rcblue;
95 border: @border-thickness solid @grey5;
96 96 border-radius: @border-radius;
97 color: @rcblue;
97 color: @grey2;
98 98 background-color: white;
99
100 a {
101 color: @grey2;
102
103 &:hover {
104 color: @rcdarkblue;
105 }
106 }
99 107 }
100 108
101 109 .drop-menu-dropdown {
@@ -120,7 +128,7 b' select.select2{height:28px;visibility:hi'
120 128
121 129 a {
122 130 display:block;
123 padding: .9em;
131 padding: .7em;
124 132 padding-right: 2em;
125 133 position: relative;
126 134
@@ -129,7 +137,7 b' select.select2{height:28px;visibility:hi'
129 137 content: "\00A0\25BE";
130 138 right: .1em;
131 139 line-height: 1em;
132 top: 0.4em;
140 top: 0.2em;
133 141 width: 1em;
134 142 font-size: 20px;
135 143 }
@@ -157,6 +165,12 b' select.select2{height:28px;visibility:hi'
157 165 width: 100%;
158 166 margin: .5em 0;
159 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 176 .select2-no-results {
@@ -176,7 +190,13 b' select.select2{height:28px;visibility:hi'
176 190
177 191 &:hover,
178 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 202 &.select2-result-with-children {
@@ -189,8 +209,7 b' select.select2{height:28px;visibility:hi'
189 209 display:block;
190 210 padding: 8px;
191 211 font-family: @text-regular;
192 border-bottom: @border-thickness solid @rclightblue;
193 color: @rcblue;
212 color: @grey2;
194 213 cursor: pointer;
195 214 }
196 215 &.select2-result-with-children {
@@ -205,7 +224,7 b' select.select2{height:28px;visibility:hi'
205 224 ul.select2-result-sub li .select2-result-label {
206 225 padding-left: 16px;
207 226 font-family: @text-regular;
208 color: @rcblue;
227 color: @grey2;
209 228 cursor: pointer;
210 229 }
211 230 }
@@ -3,30 +3,33 b''
3 3 // Used for headers and file detail summary screens.
4 4
5 5 .summary {
6 float: left;
6 clear: both;
7 float: none;
7 8 position: relative;
8 9 width: 100%;
9 10 margin: 0;
10 11 padding: 0;
12 background: #FCFCFC;
13 border: 1px solid #EAEAEA;
14 border-radius: @border-radius;
15 margin-bottom: 20px;
11 16
12 17 .summary-detail-header {
13 float: left;
14 18 display: block;
15 19 width: 100%;
16 margin-bottom: @textmargin;
20 margin-bottom: 10px;
17 21 padding: 0 0 .5em 0;
18 22 border-bottom: @border-thickness solid @border-default-color;
19 23
20 24 .breadcrumbs {
21 float: left;
22 25 display: inline;
23 26 margin: 0;
24 27 padding: 0;
25 28 }
29
26 30 h4 {
27 float: left;
28 31 margin: 0 1em 0 0;
29 padding: 0;
32 padding: 10px 0 5px 20px;
30 33 line-height: 1.2em;
31 34 font-size: @basefontsize;
32 35 }
@@ -42,11 +45,11 b''
42 45 }
43 46
44 47 .summary-detail {
45 float: left;
48 float: none;
46 49 position: relative;
47 width: 73%;
48 margin: 0 3% @space 0;
49 padding: 0;
50 width: 100%;
51 margin: 0;
52 padding: 0 0 20px 0;
50 53
51 54 .file_diff_buttons {
52 55 margin-top: @space;
@@ -62,18 +65,37 b''
62 65 height: 30px;
63 66 margin: 0;
64 67 padding: 0;
68 width: 130px;
65 69 font-weight: @text-semibold-weight;
66 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 82 .right-clone {
70 float: right;
71 width: 83%;
83 float: left;
84 width: ~"calc(100% - 170px)";
85
86 .clipboard-action {
87 margin-left: -30px;
88 }
72 89 }
73 90
74 91 .clone_url_input {
75 width: ~"calc(100% - 35px)";
76 padding: 5px;
92 width: ~"calc(100% - 90px)";
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 101 &.directory {
@@ -123,18 +145,32 b''
123 145 border: @border-thickness solid @border-default-color;
124 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 164 // this is used outside of just the summary
129 165 .fieldset, // similar to form fieldset
130 166 .summary .sidebar-right-content { // these have to match
131 167 clear: both;
132 float: left;
168 float: none;
133 169 position: relative;
134 170 display:block;
135 171 width: 100%;
136 min-height: 1em;
137 margin-bottom: @textmargin;
172 min-height: 20px;
173 margin-bottom: 10px;
138 174 padding: 0;
139 175 line-height: 1.2em;
140 176
@@ -147,19 +183,28 b''
147 183 }
148 184
149 185 .summary .sidebar-right-content {
150 margin-bottom: @space;
186 margin-bottom: 0;
151 187
152 188 .rc-user {
153 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 204 .fieldset {
158 205
159 206 .left-label { // similar to form legend
160 float: left;
161 207 display: block;
162 width: 25%;
163 208 margin: 0;
164 209 padding: 0;
165 210 font-weight: @text-semibold-weight;
@@ -167,16 +212,78 b''
167 212 }
168 213
169 214 .left-label-summary {
170 .left-label;
171 width: 150px;
215 padding-left: 20px;
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 }
172 234 }
173
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 }
279 }
280
174 281 .right-content { // similar to form fields
175 282 float: left;
176 283 display: block;
177 width: 75%;
178 margin: 0 0 0 -15%;
179 padding: 0 0 0 15%;
284 width: ~"calc(40% - 20px)";
285 text-align: right;
286 margin: 15px 20px 15px 0;
180 287
181 288 .truncate-wrap,
182 289 .truncate {
@@ -187,11 +294,49 b''
187 294 .commit-long {
188 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 327 .commit.truncate-wrap {
192 328 overflow:hidden;
193 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 342 // expand commit message
@@ -214,19 +359,46 b''
214 359
215 360 .comments-show { display: inline; }
216 361 .comments-hide { display: none; }
217
362
218 363 &.comments-visible {
219 364 .comments-show { display: none; }
220 365 .comments-hide { display: inline; }
221 366 }
222 367 }
223
368
224 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 395 .quick_start {
226 float: left;
227 396 display: block;
228 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 403 // adds some space to make copy and paste easier
232 404 .left-label,
@@ -235,6 +407,7 b''
235 407 }
236 408 }
237 409
410
238 411 .submodule {
239 412 .summary-detail {
240 413 width: 100%;
@@ -250,23 +423,32 b''
250 423 display: block;
251 424 width: 100%;
252 425 margin: 0;
253 padding: @space 0 10px 0;
254 border-top: @border-thickness solid @border-default-color;
426
427 .file-filename {
428 float:left;
429 padding: 10px;
430 }
255 431
256 .stats {
257 float: left;
432 .file-stats {
433 padding: 10px;
434 float:right;
258 435 }
259 .stats-filename {
260 font-size: 120%;
261 }
436
437
262 438 .stats-first-item {
263 439 padding: 0px 0px 0px 3px;
264 440 }
265 441
442 .stats-info {
443 font-size: 11px;
444 color: @grey4;
445 }
446
266 447 .buttons {
267 448 float: right;
268 449 text-align: right;
269 450 color: @grey4;
451 padding: 10px;
270 452 }
271 453
272 454 .file-container {
@@ -286,6 +468,25 b''
286 468 .repo-size {
287 469 margin-bottom: .5em;
288 470 }
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 33 td {
34 34 height: auto;
35 35 max-width: 20%;
36 padding: .65em 1em .65em 0;
36 padding: .65em 0 .65em 1em;
37 37 vertical-align: middle;
38 38 border-bottom: @border-thickness solid @grey5;
39 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 111 &.td-hash {
107 112 min-width: 80px;
108 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 127 &.td-time {
117 128 width: 160px;
118 129 white-space: nowrap;
@@ -408,29 +419,11 b' table.trending_language_tbl {'
408 419
409 420 .trending_language {
410 421 position: relative;
411 width: 100%;
412 height: 19px;
413 422 overflow: hidden;
414 background-color: @grey6;
423 color: @text-color;
424 width: 400px;
415 425
416 span, b{
417 position: absolute;
418 display: block;
419 height: 12px;
420 margin-bottom: 0px;
421 white-space: pre;
422 padding: floor(@basefontsize/4);
423 top: 0;
424 left: 0;
425 }
426
427 span{
428 color: @text-color;
429 z-index: 0;
430 min-width: 20px;
431 }
432
433 b {
426 .lang-bar {
434 427 z-index: 1;
435 428 overflow: hidden;
436 429 background-color: @rcblue;
@@ -442,6 +435,9 b' table.trending_language_tbl {'
442 435
443 436 // Changesets
444 437 #changesets.rctable {
438 th {
439 padding: 0 1em 0.65em 0;
440 }
445 441
446 442 // td must be fixed height for graph
447 443 td {
@@ -13,15 +13,19 b''
13 13 font-size: (-1 + @basefontsize); //fit in tables
14 14 line-height: .9em;
15 15 border: none;
16 box-shadow: @button-shadow;
16 17 .border-radius(@border-radius);
17 18 font-family: @text-regular;
18 19 background-image: none;
19 20 color: @grey4;
20 .border ( @border-thickness-tags, @grey4 );
21 .border ( @border-thickness-tags, @grey5 );
21 22 white-space: nowrap;
22 23 a {
23 24 color: inherit;
24 text-decoration: underline;
25
26 &:hover {
27 color: @grey2;
28 }
25 29
26 30 i,
27 31 [class^="icon-"]:before,
@@ -29,6 +33,10 b''
29 33 text-decoration: none;
30 34 }
31 35 }
36
37 &:hover {
38 border-color: @grey4;
39 }
32 40 }
33 41
34 42 .tag0 { .border ( @border-thickness-tags, @grey4 ); color:@grey4; }
@@ -46,6 +46,13 b' h6, .h6 { font-size: 1em; font-weight'
46 46 .breadcrumbs {
47 47 font-size: @repo-title-fontsize;
48 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 58 .breadcrumbs_light {
@@ -156,6 +163,19 b' pre {'
156 163
157 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 180 small,
161 181 .small {
@@ -231,7 +251,8 b' mark,'
231 251 clear: both;
232 252 float: left;
233 253 width: 100%;
234 margin: @pagepadding/2 0 @pagepadding;
254 margin: @pagepadding/2 0 @pagepadding/4;
255 min-height: 25px;
235 256
236 257 .breadcrumbs {
237 258 float: left;
@@ -285,6 +306,11 b' mark,'
285 306 }
286 307
287 308 .title-content {
309
310 &.repo-title {
311 float: none
312 }
313
288 314 float: left;
289 315 margin: 0;
290 316 padding: 0;
@@ -8,13 +8,15 b''
8 8 @rchighlightblue: lighten(@rcblue, 35%);
9 9
10 10 // Secondary Colors (greyscale)
11 @grey1: #202020; //midnight
12 @grey2: #323232; //charcoal
13 @grey3: #666666; //tungsten
14 @grey4: #979797; //light grey
11 @black: #000;
12 @white: #fff;
13 @grey1: #2B2B2D; //midnight
14 @grey2: #5C5C5C; //charcoal
15 @grey3: #7E7F7F; //tungsten
16 @grey4: #949494; //light grey
15 17 @grey5: #dbd9da; //greyish
16 18 @grey6: #eeeeee; //silver
17 @grey7: #f9f9f9; //light silver
19 @grey7: #F5F5F5; //light silver
18 20
19 21 // special for navigation
20 22 @nav-grey: #CDCCCD;
@@ -102,7 +104,7 b''
102 104
103 105 // FORMS (new)
104 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 108 // TODO: johbo: Needed for working computation of paddings around labels etc.
107 109 // Expected to be replaced once we are done with the form refactoring.
108 110 @input-padding-px: 12px;
@@ -128,10 +130,14 b''
128 130 @fields-input-l: 720px;
129 131
130 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 139 // DEFAULT WIDTHS
134 @wrapper-maxwidth: 1200px;
140 @wrapper-maxwidth: 1600px;
135 141 @sidebar-width: 145px;
136 142 @sidebar-all-width: @sidebar-width + 2 * @sidebarpadding;
137 143 @sidebar-small-width: 100px;
1 NO CONTENT: modified file, binary diff hidden
@@ -1,78 +1,134 b''
1 1 <?xml version="1.0" standalone="no"?>
2 2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3 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 5 <defs>
6 6 <font id="rcicons" horiz-adv-x="1000" >
7 7 <font-face font-family="rcicons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
8 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 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 132 </font>
77 133 </defs>
78 134 </svg> No newline at end of file
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -98,7 +98,7 b' function setRCMouseBindings(repoName, re'
98 98 });
99 99 Mousetrap.bind(['g c'], function(e) {
100 100 window.location = pyroutes.url(
101 'repo_changelog', {'repo_name': repoName});
101 'repo_commits', {'repo_name': repoName});
102 102 });
103 103 Mousetrap.bind(['g F'], function(e) {
104 104 window.location = pyroutes.url(
@@ -131,6 +131,7 b' function registerRCRoutes() {'
131 131 pyroutes.register('repo_new', '/_admin/repos/new', []);
132 132 pyroutes.register('repo_create', '/_admin/repos/create', []);
133 133 pyroutes.register('repo_groups', '/_admin/repo_groups', []);
134 pyroutes.register('repo_groups_data', '/_admin/repo_groups_data', []);
134 135 pyroutes.register('repo_group_new', '/_admin/repo_group/new', []);
135 136 pyroutes.register('repo_group_create', '/_admin/repo_group/create', []);
136 137 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
@@ -148,6 +149,7 b' function registerRCRoutes() {'
148 149 pyroutes.register('repo_group_list_data', '/_repo_groups', []);
149 150 pyroutes.register('goto_switcher_data', '/_goto_data', []);
150 151 pyroutes.register('markup_preview', '/_markup_preview', []);
152 pyroutes.register('file_preview', '/_file_preview', []);
151 153 pyroutes.register('store_user_session_value', '/_store_session_attr', []);
152 154 pyroutes.register('journal', '/_admin/journal', []);
153 155 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
@@ -195,14 +197,17 b' function registerRCRoutes() {'
195 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 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 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 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 202 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
200 203 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
201 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 209 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
203 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 211 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
207 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 213 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
@@ -356,6 +361,12 b' function registerRCRoutes() {'
356 361 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
357 362 pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
358 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 370 pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']);
360 371 pyroutes.register('repo_automation_update', '/%(repo_name)s/settings/automation/%(entry_id)s/update', ['repo_name', 'entry_id']);
361 372 pyroutes.register('edit_repo_remote_push', '/%(repo_name)s/settings/remote/push', ['repo_name']);
@@ -102,7 +102,7 b' var showRepoStats = function(target, dat'
102 102 var total = 0;
103 103 var no_data = true;
104 104 var tbl = document.createElement('table');
105 tbl.setAttribute('class', 'trending_language_tbl');
105 tbl.setAttribute('class', 'trending_language_tbl rctable');
106 106
107 107 $.each(data, function(key, val){
108 108 total += val.count;
@@ -120,54 +120,47 b' var showRepoStats = function(target, dat'
120 120 cnt += 1;
121 121 no_data = false;
122 122
123 var hide = cnt > 2;
124 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 125 var key = val[0];
131 126 var obj = {"desc": val[1].desc, "count": val[1].count};
132 127
133 var percentage = Math.round((obj.count / total * 100), 2);
134
128 // meta language names
135 129 var td1 = document.createElement('td');
136 td1.width = 300;
137 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 132 td1.appendChild(trending_language_label);
140 133
134 // extensions
141 135 var td2 = document.createElement('td');
142 var trending_language = document.createElement('div');
143 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
144
145 trending_language.title = key + " " + nr_files;
136 var extension = document.createElement('div');
137 extension.innerHTML = ".{0}".format(key)
138 td2.appendChild(extension);
146 139
147 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
148 + "</span><b>" + percentage + "% " + nr_files + "</b>";
140 // number of files
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');
151 $('b', trending_language)[0].style.width = percentage + "%";
152 td2.appendChild(trending_language);
148 // percentage
149 var td4 = document.createElement('td');
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 158 tr.appendChild(td1);
155 159 tr.appendChild(td2);
160 tr.appendChild(td3);
161 tr.appendChild(td4);
156 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 166 $(container).html(tbl);
@@ -46,6 +46,8 b' var CommitsController = function () {'
46 46 self.$graphCanvas.html('');
47 47
48 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 52 // Determine max number of edges per row in graph
51 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 71 var x_step = Math.min(10, Math.floor(86 / edgeCount));
72 var height = $('#changesets').find('.commits-range').height() + graph_padding;
61 73 var graph_options = {
62 74 width: 100,
63 height: $('#changesets').find('.commits-range').height(),
75 height: height,
64 76 x_step: x_step,
65 77 y_step: 42,
66 78 dotRadius: 3.5,
@@ -85,11 +97,11 b' var CommitsController = function () {'
85 97 this.$graphCanvas.commits(graph_options);
86 98
87 99 this.setLabelText(edgeData);
88 if ($('.load-more-commits').find('.prev-commits').get(0)) {
89 var padding = 75;
90 100
91 } else {
92 var padding = 43;
101 var padding = 90;
102 if (prev_link) {
103 padding += 34;
104
93 105 }
94 106 $('#graph_nodes').css({'padding-top': padding});
95 107 };
@@ -112,10 +124,10 b' var CommitsController = function () {'
112 124 }
113 125
114 126 if (urlData['commit_id'] && urlData['f_path']) {
115 return pyroutes.url('repo_changelog_elements_file', urlData);
127 return pyroutes.url('repo_commits_elements_file', urlData);
116 128 }
117 129 else {
118 return pyroutes.url('repo_changelog_elements', urlData);
130 return pyroutes.url('repo_commits_elements', urlData);
119 131 }
120 132
121 133 };
@@ -204,7 +204,12 b' var CodeMirrorCompleteAfter = function(c'
204 204 };
205 205
206 206 var initCodeMirror = function(textAreadId, resetUrl, focus, options) {
207 var ta = $('#' + textAreadId).get(0);
207 if (textAreadId.substr(0,1) === "#"){
208 var ta = $(textAreadId).get(0);
209 }else {
210 var ta = $('#' + textAreadId).get(0);
211 }
212
208 213 if (focus === undefined) {
209 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 653 /* markup form */
661 654 (function(mod) {
@@ -587,12 +587,14 b' var CommentsController = function() {'
587 587 $('#content').removeClass("wrapper");
588 588 $('#content').addClass("wide-mode-wrapper");
589 589 $(node).addClass('btn-success');
590 return true
590 591 } else {
591 592 $('#content').removeClass("wide-mode-wrapper");
592 593 $('#content').addClass("wrapper");
593 594 $(node).removeClass('btn-success');
595 return false
594 596 }
595 return false;
597
596 598 };
597 599
598 600 this.toggleComments = function(node, show) {
This diff has been collapsed as it changes many lines, (627 lines changed) Show them Hide them
@@ -19,234 +19,254 b''
19 19 /**
20 20 * Search file list
21 21 */
22 // global reference to file-node filter
23 var _NODEFILTER = {};
22
23 var NodeFilter = {};
24 24
25 var fileBrowserListeners = function(node_list_url, url_base){
26 var n_filter = $('#node_filter').get(0);
27
28 _NODEFILTER.filterTimeout = null;
29 var nodes = null;
25 var fileBrowserListeners = function (node_list_url, url_base) {
26 var $filterInput = $('#node_filter');
27 var n_filter = $filterInput.get(0);
30 28
31 _NODEFILTER.fetchNodes = function(callback) {
32 $.ajax({url: node_list_url, headers: {'X-PARTIAL-XHR': true}})
33 .done(function(data){
34 nodes = data.nodes;
35 if (callback) {
36 callback();
37 }
38 })
39 .fail(function(data){
40 console.log('failed to load');
41 });
42 };
29 NodeFilter.filterTimeout = null;
30 var nodes = null;
43 31
44 _NODEFILTER.fetchNodesCallback = function() {
45 $('#node_filter_box_loading').hide();
46 $('#node_filter_box').removeClass('hidden').show();
47 n_filter.focus();
48 if ($('#node_filter').hasClass('init')){
49 n_filter.value = '';
50 $('#node_filter').removeClass('init');
51 }
52 };
32 NodeFilter.focus = function () {
33 $filterInput.focus()
34 };
53 35
54 _NODEFILTER.initFilter = function(){
55 $('#node_filter_box_loading').removeClass('hidden').show();
56 $('#search_activate_id').hide();
57 $('#search_deactivate_id').removeClass('hidden').show();
58 $('#add_node_id').hide();
59 _NODEFILTER.fetchNodes(_NODEFILTER.fetchNodesCallback);
60 };
36 NodeFilter.fetchNodes = function (callback) {
37 $.ajax(
38 {url: node_list_url, headers: {'X-PARTIAL-XHR': true}})
39 .done(function (data) {
40 nodes = data.nodes;
41 if (callback) {
42 callback();
43 }
44 })
45 .fail(function (data) {
46 console.log('failed to load');
47 });
48 };
61 49
62 _NODEFILTER.resetFilter = function(){
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 = [];
75 var order = 0;
76 for (var i = 0; i < query.length; i++) {
77 var match_position = filepath.indexOf(query[i]);
78 if (match_position !== -1) {
79 var prev_match_position = highlight[highlight.length-1];
80 if (prev_match_position === undefined) {
81 highlight.push(match_position);
82 } else {
83 var current_match_position = prev_match_position + match_position + 1;
84 highlight.push(current_match_position);
85 order = order + current_match_position - prev_match_position;
50 NodeFilter.initFilter = function (e) {
51 if ($filterInput.hasClass('loading')) {
52 return
86 53 }
87 filepath = filepath.substring(match_position+1);
88 } else {
89 return false;
90 }
91 }
92 return {'order': order,
93 'highlight': highlight};
94 };
95 54
96 _NODEFILTER.sortPredicate = function(a, b) {
97 if (a.order < b.order) return -1;
98 if (a.order > b.order) return 1;
99 if (a.filepath < b.filepath) return -1;
100 if (a.filepath > b.filepath) return 1;
101 return 0;
102 };
103
104 _NODEFILTER.updateFilter = function(elem, e) {
105 return function(){
106 // Reset timeout
107 _NODEFILTER.filterTimeout = null;
108 var query = elem.value.toLowerCase();
109 var match = [];
110 var matches_max = 20;
111 if (query !== ""){
112 var results = [];
113 for(var k=0;k<nodes.length;k++){
114 var result = _NODEFILTER.fuzzy_match(
115 nodes[k].name.toLowerCase(), query);
116 if (result) {
117 result.type = nodes[k].type;
118 result.filepath = nodes[k].name;
119 results.push(result);
120 }
121 }
122 results = results.sort(_NODEFILTER.sortPredicate);
123 var limit = matches_max;
124 if (results.length < matches_max) {
125 limit = results.length;
55 // in case we are already loaded, do nothing
56 if (!$filterInput.hasClass('init')) {
57 return NodeFilter.handleKey(e);
126 58 }
127 for (var i=0; i<limit; i++){
128 if(query && results.length > 0){
129 var n = results[i].filepath;
130 var t = results[i].type;
131 var n_hl = n.split("");
132 var pos = results[i].highlight;
133 for (var j = 0; j < pos.length; j++) {
134 n_hl[pos[j]] = "<em>" + n_hl[pos[j]] + "</em>";
135 }
136 n_hl = n_hl.join("");
137 var new_url = url_base.replace('__FPATH__',n);
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');
138 63
139 var typeObj = {
140 dir: 'icon-directory browser-dir',
141 file: 'icon-file-text browser-file'
142 };
64 var callback = function (org) {
65 return function () {
66 if ($filterInput.hasClass('init')) {
67 $filterInput.removeClass('init');
68 $filterInput.removeClass('loading');
69 }
70 $('.files-filter-box-path i').removeClass(iconLoading).addClass(iconSearch);
143 71
144 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));
146 }
147 }
148 if(results.length > limit){
149 var truncated_count = results.length - matches_max;
150 if (truncated_count === 1) {
151 match.push('<tr><td>{0} {1}</td><td colspan="5"></td></tr>'.format(truncated_count, _gettext('truncated result')));
152 } else {
153 match.push('<tr><td>{0} {1}</td><td colspan="5"></td></tr>'.format(truncated_count, _gettext('truncated results')));
154 }
155 }
156 }
157 if (query !== ""){
158 $('#tbody').hide();
159 $('#tbody_filtered').show();
72 // auto re-filter if we filled in the input
73 if (n_filter.value !== "") {
74 NodeFilter.updateFilter(n_filter, e)()
75 }
160 76
161 if (match.length === 0){
162 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_gettext('No matching files')));
163 }
164 $('#tbody_filtered').html(match.join(""));
165 }
166 else{
77 }
78 };
79 // load node data
80 NodeFilter.fetchNodes(callback());
81
82 };
83
84 NodeFilter.resetFilter = function () {
167 85 $('#tbody').show();
168 86 $('#tbody_filtered').hide();
169 }
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;
100 };
101
102 var scrollUp = function (element) {
103 if (element.offset().top < $(window).scrollTop()) {
104 $('html,body').scrollTop(element.offset().top);
105 return false;
106 }
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 }
170 165
171 166 };
172 };
173
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 167
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 };
168 NodeFilter.fuzzy_match = function (filepath, query) {
169 var highlight = [];
170 var order = 0;
171 for (var i = 0; i < query.length; i++) {
172 var match_position = filepath.indexOf(query[i]);
173 if (match_position !== -1) {
174 var prev_match_position = highlight[highlight.length - 1];
175 if (prev_match_position === undefined) {
176 highlight.push(match_position);
177 } else {
178 var current_match_position = prev_match_position + match_position + 1;
179 highlight.push(current_match_position);
180 order = order + current_match_position - prev_match_position;
181 }
182 filepath = filepath.substring(match_position + 1);
183 } else {
184 return false;
185 }
186 }
187 return {
188 'order': order,
189 'highlight': highlight
190 };
191 };
192 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 });
193 NodeFilter.sortPredicate = function (a, b) {
194 if (a.order < b.order) return -1;
195 if (a.order > b.order) return 1;
196 if (a.filepath < b.filepath) return -1;
197 if (a.filepath > b.filepath) return 1;
198 return 0;
199 };
207 200
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 });
201 NodeFilter.updateFilter = function (elem, e) {
202 return function () {
203 // Reset timeout
204 NodeFilter.filterTimeout = null;
205 var query = elem.value.toLowerCase();
206 var match = [];
207 var matches_max = 20;
208 if (query !== "") {
209 var results = [];
210 for (var k = 0; k < nodes.length; k++) {
211 var result = NodeFilter.fuzzy_match(
212 nodes[k].name.toLowerCase(), query);
213 if (result) {
214 result.type = nodes[k].type;
215 result.filepath = nodes[k].name;
216 results.push(result);
217 }
218 }
219 results = results.sort(NodeFilter.sortPredicate);
220 var limit = matches_max;
221 if (results.length < matches_max) {
222 limit = results.length;
223 }
224 for (var i = 0; i < limit; i++) {
225 if (query && results.length > 0) {
226 var n = results[i].filepath;
227 var t = results[i].type;
228 var n_hl = n.split("");
229 var pos = results[i].highlight;
230 for (var j = 0; j < pos.length; j++) {
231 n_hl[pos[j]] = "<em>" + n_hl[pos[j]] + "</em>";
232 }
233 n_hl = n_hl.join("");
234 var new_url = url_base.replace('__FPATH__', n);
235
236 var typeObj = {
237 dir: 'icon-directory browser-dir',
238 file: 'icon-file-text browser-file'
239 };
240
241 var typeIcon = '<i class="{0}"></i>'.format(typeObj[t]);
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));
243 }
244 }
245 if (results.length > limit) {
246 var truncated_count = results.length - matches_max;
247 if (truncated_count === 1) {
248 match.push('<tr><td>{0} {1}</td><td colspan="5"></td></tr>'.format(truncated_count, _gettext('truncated result')));
249 } else {
250 match.push('<tr><td>{0} {1}</td><td colspan="5"></td></tr>'.format(truncated_count, _gettext('truncated results')));
251 }
252 }
253 }
254 if (query !== "") {
255 $('#tbody').hide();
256 $('#tbody_filtered').show();
257
258 if (match.length === 0) {
259 match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format(_gettext('No matching files')));
260 }
261 $('#tbody_filtered').html(match.join(""));
262 } else {
263 $('#tbody').show();
264 $('#tbody_filtered').hide();
265 }
266
267 };
268 };
269
250 270 };
251 271
252 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
@@ -16,58 +16,44 b''
16 16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 var onSuccessFollow = function(target){
20 var f = $(target);
21 var f_cnt = $('#current_followers_count');
19 var onSuccessFollow = function (target) {
20 var targetEl = $(target);
22 21
23 if(f.hasClass('follow')){
24 f.removeClass('follow');
25 f.addClass('following');
26 f.attr('title', _gettext('Stop following this repository'));
27 $(f).html(_gettext('Unfollow'));
28 if(f_cnt.length){
29 var cnt = Number(f_cnt.html())+1;
30 f_cnt.html(cnt);
22 var callback = function () {
23 targetEl.animate({'opacity': 1.00}, 200);
24 if (targetEl.hasClass('watching')) {
25 targetEl.removeClass('watching');
26 targetEl.attr('title', _gettext('Stopped watching this repository'));
27 $(targetEl).html('<i class="icon-eye"></i>'+_gettext('Watch'));
28 } else {
29 targetEl.addClass('watching');
30 targetEl.attr('title', _gettext('Started watching this repository'));
31 $(targetEl).html('<i class="icon-eye-off"></i>'+_gettext('Unwatch'));
31 32 }
32 }
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 }
33 };
34 targetEl.animate({'opacity': 0.15}, 200, callback);
43 35 };
44 36
45 // TODO:: check if the function is needed. 0 usage found
46 var toggleFollowingUser = function(target,follows_user_id,token,user_id){
37
38 var toggleFollowingUser = function (target, follows_user_id) {
47 39 var args = {
48 40 'follows_user_id': follows_user_id,
49 'auth_token': token,
50 41 'csrf_token': CSRF_TOKEN
51 42 };
52 if(user_id != undefined){
53 args.user_id = user_id
54 }
55 ajaxPOST(pyroutes.url('toggle_following'), args, function(){
43
44 ajaxPOST(pyroutes.url('toggle_following'), args, function () {
56 45 onSuccessFollow(target);
57 46 });
58 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 51 var args = {
63 52 'follows_repo_id': follows_repo_id,
64 'auth_token': token,
65 53 'csrf_token': CSRF_TOKEN
66 54 };
67 if(user_id != undefined){
68 args.user_id = user_id
69 }
70 ajaxPOST(pyroutes.url('toggle_following'), args, function(){
55
56 ajaxPOST(pyroutes.url('toggle_following'), args, function () {
71 57 onSuccessFollow(target);
72 58 });
73 59 return false;
@@ -73,10 +73,3 b' var select2RefSwitcher = function(target'
73 73 {'repo_name': templateContext.repo_name});
74 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 9 %endif
10 10 </%def>
11 11
12 <%def name="breadcrumbs_links()">
13 ${_('Audit long entry')} ${c.audit_log_entry.entry_id}
14 </%def>
12 <%def name="breadcrumbs_links()"></%def>
15 13
16 14 <%def name="menu_bar_nav()">
17 15 ${self.menu_items(active='admin')}
18 16 </%def>
17
18 <%def name="menu_bar_subnav()">
19 ${self.admin_menu(active='audit_logs')}
20 </%def>
21
19 22 <%def name="main()">
20 23 <div class="box">
21 <!-- box / title -->
24
22 25 <div class="title">
23 ${self.breadcrumbs()}
26 ${_('Audit long entry')} ${c.audit_log_entry.entry_id}
24 27 </div>
25 <!-- end box / title -->
28
26 29 <div class="table">
27 30 <div id="user_log">
28 31 <table class="rctable audit-log">
@@ -8,27 +8,28 b''
8 8 %endif
9 9 </%def>
10 10
11 <%def name="breadcrumbs_links()">
12 ${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...')}"/>
14 <input type='submit' value="${_('filter')}" class="btn" />
15 ${_('Audit logs')} - ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
16 ${h.end_form()}
17 <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>
19 </%def>
11 <%def name="breadcrumbs_links()"></%def>
20 12
21 13 <%def name="menu_bar_nav()">
22 14 ${self.menu_items(active='admin')}
23 15 </%def>
24 16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='audit_logs')}
19 </%def>
20
25 21 <%def name="main()">
26 22 <div class="box">
27 <!-- box / title -->
28 23 <div class="title">
29 ${self.breadcrumbs()}
24 ${h.form(None, id_="filter_form", method="get")}
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...')}"/>
26 <input type='submit' value="${_('filter')}" class="btn" />
27 ${_('Audit logs')} - ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
28 ${h.end_form()}
29 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
30 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
30 31 </div>
31 <!-- end box / title -->
32
32 33 <div class="table">
33 34 <div id="user_log">
34 35 <%include file="/admin/admin_log_base.mako" />
@@ -8,29 +8,26 b''
8 8 %endif
9 9 </%def>
10 10
11 <%def name="breadcrumbs_links()">
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 &raquo;
14 ${_('Authentication Plugins')}
15 </%def>
11 <%def name="breadcrumbs_links()"></%def>
16 12
17 13 <%def name="menu_bar_nav()">
18 14 ${self.menu_items(active='admin')}
19 15 </%def>
20 16
17 <%def name="menu_bar_subnav()">
18 ${self.admin_menu(active='authentication')}
19 </%def>
20
21 21 <%def name="main()">
22 22
23 23 <div class="box">
24 <div class="title">
25 ${self.breadcrumbs()}
26 </div>
27 24
28 25 <div class='sidebar-col-wrapper'>
29 26
30 27 <div class="sidebar">
31 28 <ul class="nav nav-pills nav-stacked">
32 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 31 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
35 32 </li>
36 33 % endfor
@@ -66,10 +63,10 b''
66 63 <th>${_('Plugin ID')}</th>
67 64 <th>${_('Enabled')}</th>
68 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 67 <td>
71 <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')}
68 <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${('btn-success' if plugin.get_id() in enabled_plugins else '')}">
69 ${(_('activated') if plugin.get_id() in enabled_plugins else _('not active'))}
73 70 </span>
74 71 </td>
75 72 <td>${plugin.get_display_name()}</td>
@@ -2,10 +2,10 b''
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 ${_('Authentication Settings')}
6 %if c.rhodecode_name:
5 ${_('Authentication Settings')}
6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}}
8 %endif
8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
@@ -17,22 +17,23 b''
17 17 </%def>
18 18
19 19 <%def name="menu_bar_nav()">
20 ${self.menu_items(active='admin')}
20 ${self.menu_items(active='admin')}
21 </%def>
22
23 <%def name="menu_bar_subnav()">
24 ${self.admin_menu(active='authentication')}
21 25 </%def>
22 26
23 27 <%def name="main()">
28
24 29 <div class="box">
25 <div class="title">
26 ${self.breadcrumbs()}
27 </div>
30
28 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 33 <div class="sidebar">
33 34 <ul class="nav nav-pills nav-stacked">
34 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 37 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
37 38 </li>
38 39 % endfor
@@ -18,11 +18,12 b''
18 18 ${self.menu_items(active='admin')}
19 19 </%def>
20 20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='defaults')}
23 </%def>
24
21 25 <%def name="main()">
22 26 <div class="box">
23 <div class="title">
24 ${self.breadcrumbs()}
25 </div>
26 27
27 28 ##main
28 29 <div class="sidebar-col-wrapper">
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changelog/changelog.mako to rhodecode/templates/commits/changelog.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_elements.mako to rhodecode/templates/commits/changelog_elements.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_file_history.mako to rhodecode/templates/commits/changelog_file_history.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files_detail.mako to rhodecode/templates/files/files_source_header.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/file_tree_detail.mako to rhodecode/templates/files/files_tree_header.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now