##// END OF EJS Templates
implements #285: Implemented non changeable urls for clone url, and web views
marcink -
r1813:a8c66e87 beta
parent child Browse files
Show More
@@ -1,54 +1,79 b''
1 1 .. _general:
2 2
3 3 General RhodeCode usage
4 4 =======================
5 5
6 6
7 7 Repository deleting
8 8 -------------------
9 9
10 10 Currently when admin/owner deletes a repository, RhodeCode does not physically
11 11 delete a repository from filesystem, it renames it in a special way so it's
12 12 not possible to push,clone or access repository. It's worth a notice that,
13 13 even if someone will be given administrative access to RhodeCode and will
14 14 delete a repository You can easy restore such action by restoring `rm__<date>`
15 15 from the repository name, and internal repository storage (.hg/.git)
16 16
17 17 Follow current branch in file view
18 18 ----------------------------------
19 19
20 20 In file view when this checkbox is checked the << and >> arrows will jump
21 21 to changesets within the same branch currently viewing. So for example
22 22 if someone is viewing files at 'beta' branch and marks `follow current branch`
23 23 checkbox the << and >> buttons will only show him revisions for 'beta' branch
24 24
25 25
26 26 Compare view from changelog
27 27 ---------------------------
28 28
29 29 Checkboxes in compare view allow users to view combined compare view. You can
30 30 only show the range between the first and last checkbox (no cherry pick).
31 31 Clicking more than one checkbox will activate a link in top saying
32 32 `Show selected changes <from-rev> -> <to-rev>` clicking this will bring
33 33 compare view
34 34
35 35 Compare view is also available from the journal on pushes having more than
36 36 one changeset
37 37
38 38
39 Non changeable repository urls
40 ------------------------------
41
42 Due to complicated nature of repository grouping, often urls of repositories
43 can change.
44
45 example::
46
47 #before
48 http://server.com/repo_name
49 # after insertion to test_group group the url will be
50 http://server.com/test_group/repo_name
51
52 This can be an issue for build systems and any other hardcoded scripts, moving
53 repository to a group leads to a need for changing external systems. To
54 overcome this RhodeCode introduces a non changable replacement url. It's
55 simply an repository ID prefixed with `_` above urls are also accessible as::
56
57 http://server.com/_<ID>
58
59 Since ID are always the same moving the repository will not affect such url.
60 the _<ID> syntax can be used anywhere in the system so urls with repo_name
61 for changelogs, files and other can be exchanged with _<ID> syntax.
62
63
39 64
40 65 Mailing
41 66 -------
42 67
43 68 When administrator will fill up the mailing settings in .ini files
44 69 RhodeCode will send mails on user registration, or when RhodeCode errors occur
45 70 on errors the mails will have a detailed traceback of error.
46 71
47 72
48 73 Trending source files
49 74 ---------------------
50 75
51 76 Trending source files are calculated based on pre defined dict of known
52 77 types and extensions. If You miss some extension or Would like to scan some
53 78 custom files it's possible to add new types in `LANGUAGES_EXTENSIONS_MAP` dict
54 79 located in `/rhodecode/lib/celerylib/tasks.py` No newline at end of file
@@ -1,489 +1,497 b''
1 1 """
2 2 Routes configuration
3 3
4 4 The more specific and detailed routes should be defined first so they
5 5 may take precedent over the more generic routes. For more information
6 6 refer to the routes manual at http://routes.groovie.org/docs/
7 7 """
8 8 from __future__ import with_statement
9 9 from routes import Mapper
10 10
11
12 11 # prefix for non repository related links needs to be prefixed with `/`
13 12 ADMIN_PREFIX = '/_admin'
14 13
15 14
16 15 def make_map(config):
17 16 """Create, configure and return the routes Mapper"""
18 17 rmap = Mapper(directory=config['pylons.paths']['controllers'],
19 18 always_scan=config['debug'])
20 19 rmap.minimization = False
21 20 rmap.explicit = False
22 21
23 22 from rhodecode.lib.utils import is_valid_repo
24 23 from rhodecode.lib.utils import is_valid_repos_group
25 24
26 25 def check_repo(environ, match_dict):
27 26 """
28 27 check for valid repository for proper 404 handling
29 28
30 29 :param environ:
31 30 :param match_dict:
32 31 """
32 from rhodecode.model.db import Repository
33 repo_name = match_dict.get('repo_name')
33 34
34 repo_name = match_dict.get('repo_name')
35 try:
36 by_id = repo_name.split('_')
37 if len(by_id) == 2 and by_id[1].isdigit():
38 repo_name = Repository.get(by_id[1]).repo_name
39 match_dict['repo_name'] = repo_name
40 except:
41 pass
42
35 43 return is_valid_repo(repo_name, config['base_path'])
36 44
37 45 def check_group(environ, match_dict):
38 46 """
39 47 check for valid repositories group for proper 404 handling
40 48
41 49 :param environ:
42 50 :param match_dict:
43 51 """
44 52 repos_group_name = match_dict.get('group_name')
45 53
46 54 return is_valid_repos_group(repos_group_name, config['base_path'])
47 55
48 56 def check_int(environ, match_dict):
49 57 return match_dict.get('id').isdigit()
50 58
51 59 # The ErrorController route (handles 404/500 error pages); it should
52 60 # likely stay at the top, ensuring it can always be resolved
53 61 rmap.connect('/error/{action}', controller='error')
54 62 rmap.connect('/error/{action}/{id}', controller='error')
55 63
56 64 #==========================================================================
57 65 # CUSTOM ROUTES HERE
58 66 #==========================================================================
59 67
60 68 #MAIN PAGE
61 69 rmap.connect('home', '/', controller='home', action='index')
62 70 rmap.connect('repo_switcher', '/repos', controller='home',
63 71 action='repo_switcher')
64 72 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*}',
65 73 controller='home', action='branch_tag_switcher')
66 74 rmap.connect('bugtracker',
67 75 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
68 76 _static=True)
69 77 rmap.connect('rst_help',
70 78 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
71 79 _static=True)
72 80 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
73 81
74 82 #ADMIN REPOSITORY REST ROUTES
75 83 with rmap.submapper(path_prefix=ADMIN_PREFIX,
76 84 controller='admin/repos') as m:
77 85 m.connect("repos", "/repos",
78 86 action="create", conditions=dict(method=["POST"]))
79 87 m.connect("repos", "/repos",
80 88 action="index", conditions=dict(method=["GET"]))
81 89 m.connect("formatted_repos", "/repos.{format}",
82 90 action="index",
83 91 conditions=dict(method=["GET"]))
84 92 m.connect("new_repo", "/repos/new",
85 93 action="new", conditions=dict(method=["GET"]))
86 94 m.connect("formatted_new_repo", "/repos/new.{format}",
87 95 action="new", conditions=dict(method=["GET"]))
88 96 m.connect("/repos/{repo_name:.*}",
89 97 action="update", conditions=dict(method=["PUT"],
90 98 function=check_repo))
91 99 m.connect("/repos/{repo_name:.*}",
92 100 action="delete", conditions=dict(method=["DELETE"],
93 101 function=check_repo))
94 102 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
95 103 action="edit", conditions=dict(method=["GET"],
96 104 function=check_repo))
97 105 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
98 106 action="edit", conditions=dict(method=["GET"],
99 107 function=check_repo))
100 108 m.connect("repo", "/repos/{repo_name:.*}",
101 109 action="show", conditions=dict(method=["GET"],
102 110 function=check_repo))
103 111 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
104 112 action="show", conditions=dict(method=["GET"],
105 113 function=check_repo))
106 114 #ajax delete repo perm user
107 115 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
108 116 action="delete_perm_user", conditions=dict(method=["DELETE"],
109 117 function=check_repo))
110 118 #ajax delete repo perm users_group
111 119 m.connect('delete_repo_users_group',
112 120 "/repos_delete_users_group/{repo_name:.*}",
113 121 action="delete_perm_users_group",
114 122 conditions=dict(method=["DELETE"], function=check_repo))
115 123
116 124 #settings actions
117 125 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
118 126 action="repo_stats", conditions=dict(method=["DELETE"],
119 127 function=check_repo))
120 128 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
121 129 action="repo_cache", conditions=dict(method=["DELETE"],
122 130 function=check_repo))
123 131 m.connect('repo_public_journal',"/repos_public_journal/{repo_name:.*}",
124 132 action="repo_public_journal", conditions=dict(method=["PUT"],
125 133 function=check_repo))
126 134 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
127 135 action="repo_pull", conditions=dict(method=["PUT"],
128 136 function=check_repo))
129 137 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*}",
130 138 action="repo_as_fork", conditions=dict(method=["PUT"],
131 139 function=check_repo))
132 140
133 141 with rmap.submapper(path_prefix=ADMIN_PREFIX,
134 142 controller='admin/repos_groups') as m:
135 143 m.connect("repos_groups", "/repos_groups",
136 144 action="create", conditions=dict(method=["POST"]))
137 145 m.connect("repos_groups", "/repos_groups",
138 146 action="index", conditions=dict(method=["GET"]))
139 147 m.connect("formatted_repos_groups", "/repos_groups.{format}",
140 148 action="index", conditions=dict(method=["GET"]))
141 149 m.connect("new_repos_group", "/repos_groups/new",
142 150 action="new", conditions=dict(method=["GET"]))
143 151 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
144 152 action="new", conditions=dict(method=["GET"]))
145 153 m.connect("update_repos_group", "/repos_groups/{id}",
146 154 action="update", conditions=dict(method=["PUT"],
147 155 function=check_int))
148 156 m.connect("delete_repos_group", "/repos_groups/{id}",
149 157 action="delete", conditions=dict(method=["DELETE"],
150 158 function=check_int))
151 159 m.connect("edit_repos_group", "/repos_groups/{id}/edit",
152 160 action="edit", conditions=dict(method=["GET"],
153 161 function=check_int))
154 162 m.connect("formatted_edit_repos_group",
155 163 "/repos_groups/{id}.{format}/edit",
156 164 action="edit", conditions=dict(method=["GET"],
157 165 function=check_int))
158 166 m.connect("repos_group", "/repos_groups/{id}",
159 167 action="show", conditions=dict(method=["GET"],
160 168 function=check_int))
161 169 m.connect("formatted_repos_group", "/repos_groups/{id}.{format}",
162 170 action="show", conditions=dict(method=["GET"],
163 171 function=check_int))
164 172
165 173 #ADMIN USER REST ROUTES
166 174 with rmap.submapper(path_prefix=ADMIN_PREFIX,
167 175 controller='admin/users') as m:
168 176 m.connect("users", "/users",
169 177 action="create", conditions=dict(method=["POST"]))
170 178 m.connect("users", "/users",
171 179 action="index", conditions=dict(method=["GET"]))
172 180 m.connect("formatted_users", "/users.{format}",
173 181 action="index", conditions=dict(method=["GET"]))
174 182 m.connect("new_user", "/users/new",
175 183 action="new", conditions=dict(method=["GET"]))
176 184 m.connect("formatted_new_user", "/users/new.{format}",
177 185 action="new", conditions=dict(method=["GET"]))
178 186 m.connect("update_user", "/users/{id}",
179 187 action="update", conditions=dict(method=["PUT"]))
180 188 m.connect("delete_user", "/users/{id}",
181 189 action="delete", conditions=dict(method=["DELETE"]))
182 190 m.connect("edit_user", "/users/{id}/edit",
183 191 action="edit", conditions=dict(method=["GET"]))
184 192 m.connect("formatted_edit_user",
185 193 "/users/{id}.{format}/edit",
186 194 action="edit", conditions=dict(method=["GET"]))
187 195 m.connect("user", "/users/{id}",
188 196 action="show", conditions=dict(method=["GET"]))
189 197 m.connect("formatted_user", "/users/{id}.{format}",
190 198 action="show", conditions=dict(method=["GET"]))
191 199
192 200 #EXTRAS USER ROUTES
193 201 m.connect("user_perm", "/users_perm/{id}",
194 202 action="update_perm", conditions=dict(method=["PUT"]))
195 203
196 204 #ADMIN USERS REST ROUTES
197 205 with rmap.submapper(path_prefix=ADMIN_PREFIX,
198 206 controller='admin/users_groups') as m:
199 207 m.connect("users_groups", "/users_groups",
200 208 action="create", conditions=dict(method=["POST"]))
201 209 m.connect("users_groups", "/users_groups",
202 210 action="index", conditions=dict(method=["GET"]))
203 211 m.connect("formatted_users_groups", "/users_groups.{format}",
204 212 action="index", conditions=dict(method=["GET"]))
205 213 m.connect("new_users_group", "/users_groups/new",
206 214 action="new", conditions=dict(method=["GET"]))
207 215 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
208 216 action="new", conditions=dict(method=["GET"]))
209 217 m.connect("update_users_group", "/users_groups/{id}",
210 218 action="update", conditions=dict(method=["PUT"]))
211 219 m.connect("delete_users_group", "/users_groups/{id}",
212 220 action="delete", conditions=dict(method=["DELETE"]))
213 221 m.connect("edit_users_group", "/users_groups/{id}/edit",
214 222 action="edit", conditions=dict(method=["GET"]))
215 223 m.connect("formatted_edit_users_group",
216 224 "/users_groups/{id}.{format}/edit",
217 225 action="edit", conditions=dict(method=["GET"]))
218 226 m.connect("users_group", "/users_groups/{id}",
219 227 action="show", conditions=dict(method=["GET"]))
220 228 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
221 229 action="show", conditions=dict(method=["GET"]))
222 230
223 231 #EXTRAS USER ROUTES
224 232 m.connect("users_group_perm", "/users_groups_perm/{id}",
225 233 action="update_perm", conditions=dict(method=["PUT"]))
226 234
227 235 #ADMIN GROUP REST ROUTES
228 236 rmap.resource('group', 'groups',
229 237 controller='admin/groups', path_prefix=ADMIN_PREFIX)
230 238
231 239 #ADMIN PERMISSIONS REST ROUTES
232 240 rmap.resource('permission', 'permissions',
233 241 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
234 242
235 243 ##ADMIN LDAP SETTINGS
236 244 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
237 245 controller='admin/ldap_settings', action='ldap_settings',
238 246 conditions=dict(method=["POST"]))
239 247
240 248 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
241 249 controller='admin/ldap_settings')
242 250
243 251 #ADMIN SETTINGS REST ROUTES
244 252 with rmap.submapper(path_prefix=ADMIN_PREFIX,
245 253 controller='admin/settings') as m:
246 254 m.connect("admin_settings", "/settings",
247 255 action="create", conditions=dict(method=["POST"]))
248 256 m.connect("admin_settings", "/settings",
249 257 action="index", conditions=dict(method=["GET"]))
250 258 m.connect("formatted_admin_settings", "/settings.{format}",
251 259 action="index", conditions=dict(method=["GET"]))
252 260 m.connect("admin_new_setting", "/settings/new",
253 261 action="new", conditions=dict(method=["GET"]))
254 262 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
255 263 action="new", conditions=dict(method=["GET"]))
256 264 m.connect("/settings/{setting_id}",
257 265 action="update", conditions=dict(method=["PUT"]))
258 266 m.connect("/settings/{setting_id}",
259 267 action="delete", conditions=dict(method=["DELETE"]))
260 268 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
261 269 action="edit", conditions=dict(method=["GET"]))
262 270 m.connect("formatted_admin_edit_setting",
263 271 "/settings/{setting_id}.{format}/edit",
264 272 action="edit", conditions=dict(method=["GET"]))
265 273 m.connect("admin_setting", "/settings/{setting_id}",
266 274 action="show", conditions=dict(method=["GET"]))
267 275 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
268 276 action="show", conditions=dict(method=["GET"]))
269 277 m.connect("admin_settings_my_account", "/my_account",
270 278 action="my_account", conditions=dict(method=["GET"]))
271 279 m.connect("admin_settings_my_account_update", "/my_account_update",
272 280 action="my_account_update", conditions=dict(method=["PUT"]))
273 281 m.connect("admin_settings_create_repository", "/create_repository",
274 282 action="create_repository", conditions=dict(method=["GET"]))
275 283
276 284 #NOTIFICATION REST ROUTES
277 285 with rmap.submapper(path_prefix=ADMIN_PREFIX,
278 286 controller='admin/notifications') as m:
279 287 m.connect("notifications", "/notifications",
280 288 action="create", conditions=dict(method=["POST"]))
281 289 m.connect("notifications", "/notifications",
282 290 action="index", conditions=dict(method=["GET"]))
283 291 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
284 292 action="mark_all_read", conditions=dict(method=["GET"]))
285 293 m.connect("formatted_notifications", "/notifications.{format}",
286 294 action="index", conditions=dict(method=["GET"]))
287 295 m.connect("new_notification", "/notifications/new",
288 296 action="new", conditions=dict(method=["GET"]))
289 297 m.connect("formatted_new_notification", "/notifications/new.{format}",
290 298 action="new", conditions=dict(method=["GET"]))
291 299 m.connect("/notification/{notification_id}",
292 300 action="update", conditions=dict(method=["PUT"]))
293 301 m.connect("/notification/{notification_id}",
294 302 action="delete", conditions=dict(method=["DELETE"]))
295 303 m.connect("edit_notification", "/notification/{notification_id}/edit",
296 304 action="edit", conditions=dict(method=["GET"]))
297 305 m.connect("formatted_edit_notification",
298 306 "/notification/{notification_id}.{format}/edit",
299 307 action="edit", conditions=dict(method=["GET"]))
300 308 m.connect("notification", "/notification/{notification_id}",
301 309 action="show", conditions=dict(method=["GET"]))
302 310 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
303 311 action="show", conditions=dict(method=["GET"]))
304 312
305 313
306 314
307 315 #ADMIN MAIN PAGES
308 316 with rmap.submapper(path_prefix=ADMIN_PREFIX,
309 317 controller='admin/admin') as m:
310 318 m.connect('admin_home', '', action='index')
311 319 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
312 320 action='add_repo')
313 321
314 322 #==========================================================================
315 323 # API V1
316 324 #==========================================================================
317 325 with rmap.submapper(path_prefix=ADMIN_PREFIX,
318 326 controller='api/api') as m:
319 327 m.connect('api', '/api')
320 328
321 329
322 330 #USER JOURNAL
323 331 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX, controller='journal')
324 332
325 333 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
326 334 controller='journal', action="public_journal")
327 335
328 336 rmap.connect('public_journal_rss', '%s/public_journal_rss' % ADMIN_PREFIX,
329 337 controller='journal', action="public_journal_rss")
330 338
331 339 rmap.connect('public_journal_atom',
332 340 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
333 341 action="public_journal_atom")
334 342
335 343 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
336 344 controller='journal', action='toggle_following',
337 345 conditions=dict(method=["POST"]))
338 346
339 347 #SEARCH
340 348 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
341 349 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
342 350 controller='search')
343 351
344 352 #LOGIN/LOGOUT/REGISTER/SIGN IN
345 353 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
346 354 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
347 355 action='logout')
348 356
349 357 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
350 358 action='register')
351 359
352 360 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
353 361 controller='login', action='password_reset')
354 362
355 363 rmap.connect('reset_password_confirmation',
356 364 '%s/password_reset_confirmation' % ADMIN_PREFIX,
357 365 controller='login', action='password_reset_confirmation')
358 366
359 367 #FEEDS
360 368 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
361 369 controller='feed', action='rss',
362 370 conditions=dict(function=check_repo))
363 371
364 372 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
365 373 controller='feed', action='atom',
366 374 conditions=dict(function=check_repo))
367 375
368 376 #==========================================================================
369 377 # REPOSITORY ROUTES
370 378 #==========================================================================
371 379 rmap.connect('summary_home', '/{repo_name:.*}',
372 380 controller='summary',
373 381 conditions=dict(function=check_repo))
374 382
375 383 rmap.connect('repos_group_home', '/{group_name:.*}',
376 384 controller='admin/repos_groups', action="show_by_name",
377 385 conditions=dict(function=check_group))
378 386
379 387 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
380 388 controller='changeset', revision='tip',
381 389 conditions=dict(function=check_repo))
382 390
383 391 rmap.connect('changeset_comment', '/{repo_name:.*}/changeset/{revision}/comment',
384 392 controller='changeset', revision='tip', action='comment',
385 393 conditions=dict(function=check_repo))
386 394
387 395 rmap.connect('changeset_comment_delete', '/{repo_name:.*}/changeset/comment/{comment_id}/delete',
388 396 controller='changeset', action='delete_comment',
389 397 conditions=dict(function=check_repo, method=["DELETE"]))
390 398
391 399 rmap.connect('raw_changeset_home',
392 400 '/{repo_name:.*}/raw-changeset/{revision}',
393 401 controller='changeset', action='raw_changeset',
394 402 revision='tip', conditions=dict(function=check_repo))
395 403
396 404 rmap.connect('summary_home', '/{repo_name:.*}/summary',
397 405 controller='summary', conditions=dict(function=check_repo))
398 406
399 407 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
400 408 controller='shortlog', conditions=dict(function=check_repo))
401 409
402 410 rmap.connect('branches_home', '/{repo_name:.*}/branches',
403 411 controller='branches', conditions=dict(function=check_repo))
404 412
405 413 rmap.connect('tags_home', '/{repo_name:.*}/tags',
406 414 controller='tags', conditions=dict(function=check_repo))
407 415
408 416 rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks',
409 417 controller='bookmarks', conditions=dict(function=check_repo))
410 418
411 419 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
412 420 controller='changelog', conditions=dict(function=check_repo))
413 421
414 422 rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}',
415 423 controller='changelog', action='changelog_details',
416 424 conditions=dict(function=check_repo))
417 425
418 426 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
419 427 controller='files', revision='tip', f_path='',
420 428 conditions=dict(function=check_repo))
421 429
422 430 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
423 431 controller='files', action='diff', revision='tip', f_path='',
424 432 conditions=dict(function=check_repo))
425 433
426 434 rmap.connect('files_rawfile_home',
427 435 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
428 436 controller='files', action='rawfile', revision='tip',
429 437 f_path='', conditions=dict(function=check_repo))
430 438
431 439 rmap.connect('files_raw_home',
432 440 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
433 441 controller='files', action='raw', revision='tip', f_path='',
434 442 conditions=dict(function=check_repo))
435 443
436 444 rmap.connect('files_annotate_home',
437 445 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
438 446 controller='files', action='annotate', revision='tip',
439 447 f_path='', conditions=dict(function=check_repo))
440 448
441 449 rmap.connect('files_edit_home',
442 450 '/{repo_name:.*}/edit/{revision}/{f_path:.*}',
443 451 controller='files', action='edit', revision='tip',
444 452 f_path='', conditions=dict(function=check_repo))
445 453
446 454 rmap.connect('files_add_home',
447 455 '/{repo_name:.*}/add/{revision}/{f_path:.*}',
448 456 controller='files', action='add', revision='tip',
449 457 f_path='', conditions=dict(function=check_repo))
450 458
451 459 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
452 460 controller='files', action='archivefile',
453 461 conditions=dict(function=check_repo))
454 462
455 463 rmap.connect('files_nodelist_home',
456 464 '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}',
457 465 controller='files', action='nodelist',
458 466 conditions=dict(function=check_repo))
459 467
460 468 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
461 469 controller='settings', action="delete",
462 470 conditions=dict(method=["DELETE"], function=check_repo))
463 471
464 472 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
465 473 controller='settings', action="update",
466 474 conditions=dict(method=["PUT"], function=check_repo))
467 475
468 476 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
469 477 controller='settings', action='index',
470 478 conditions=dict(function=check_repo))
471 479
472 480 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
473 481 controller='forks', action='fork_create',
474 482 conditions=dict(function=check_repo, method=["POST"]))
475 483
476 484 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
477 485 controller='forks', action='fork',
478 486 conditions=dict(function=check_repo))
479 487
480 488 rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
481 489 controller='forks', action='forks',
482 490 conditions=dict(function=check_repo))
483 491
484 492 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
485 493 controller='followers', action='followers',
486 494 conditions=dict(function=check_repo))
487 495
488 496
489 497 return rmap
@@ -1,229 +1,236 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.summary
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Summary controller for Rhodecode
7 7
8 8 :created_on: Apr 18, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import traceback
27 27 import calendar
28 28 import logging
29 29 from time import mktime
30 30 from datetime import timedelta, date
31 31 from itertools import product
32 32 from urlparse import urlparse
33 33
34 34 from vcs.exceptions import ChangesetError, EmptyRepositoryError, \
35 35 NodeDoesNotExistError
36 36
37 37 from pylons import tmpl_context as c, request, url, config
38 38 from pylons.i18n.translation import _
39 39
40 40 from beaker.cache import cache_region, region_invalidate
41 41
42 42 from rhodecode.model.db import Statistics, CacheInvalidation
43 43 from rhodecode.lib import ALL_READMES, ALL_EXTS
44 44 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
45 45 from rhodecode.lib.base import BaseRepoController, render
46 46 from rhodecode.lib.utils import EmptyChangeset
47 47 from rhodecode.lib.markup_renderer import MarkupRenderer
48 48 from rhodecode.lib.celerylib import run_task
49 49 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
50 50 LANGUAGES_EXTENSIONS_MAP
51 51 from rhodecode.lib.helpers import RepoPage
52 52 from rhodecode.lib.compat import json, OrderedDict
53 53
54 54 log = logging.getLogger(__name__)
55 55
56 56 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
57 57 sorted(list(product(ALL_READMES, ALL_EXTS)),
58 58 key=lambda y:y[0][1] + y[1][1])]
59 59
60 60
61 61 class SummaryController(BaseRepoController):
62 62
63 63 @LoginRequired()
64 64 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
65 65 'repository.admin')
66 66 def __before__(self):
67 67 super(SummaryController, self).__before__()
68 68
69 69 def index(self, repo_name):
70 70 c.dbrepo = dbrepo = c.rhodecode_db_repo
71 71 c.following = self.scm_model.is_following_repo(repo_name,
72 72 self.rhodecode_user.user_id)
73 73
74 74 def url_generator(**kw):
75 75 return url('shortlog_home', repo_name=repo_name, size=10, **kw)
76 76
77 77 c.repo_changesets = RepoPage(c.rhodecode_repo, page=1,
78 78 items_per_page=10, url=url_generator)
79 79
80 80 if self.rhodecode_user.username == 'default':
81 81 # for default(anonymous) user we don't need to pass credentials
82 82 username = ''
83 83 password = ''
84 84 else:
85 85 username = str(self.rhodecode_user.username)
86 86 password = '@'
87 87
88 88 parsed_url = urlparse(url.current(qualified=True))
89 89
90 90 default_clone_uri = '{scheme}://{user}{pass}{netloc}{path}'
91 91
92 92 uri_tmpl = config.get('clone_uri', default_clone_uri)
93 93 uri_tmpl = uri_tmpl.replace('{', '%(').replace('}', ')s')
94 94
95 uri = uri_tmpl % {'user': username,
96 'pass': password,
97 'scheme': parsed_url.scheme,
98 'netloc': parsed_url.netloc,
99 'path':parsed_url.path}
95 uri_dict = {
96 'user': username,
97 'pass': password,
98 'scheme': parsed_url.scheme,
99 'netloc': parsed_url.netloc,
100 'path': parsed_url.path
101 }
102 uri = uri_tmpl % uri_dict
103 # generate another clone url by id
104 uri_dict.update({'path': '/_%s' % c.dbrepo.repo_id})
105 uri_id = uri_tmpl % uri_dict
100 106
101 107 c.clone_repo_url = uri
108 c.clone_repo_url_id = uri_id
102 109 c.repo_tags = OrderedDict()
103 110 for name, hash in c.rhodecode_repo.tags.items()[:10]:
104 111 try:
105 112 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash)
106 113 except ChangesetError:
107 114 c.repo_tags[name] = EmptyChangeset(hash)
108 115
109 116 c.repo_branches = OrderedDict()
110 117 for name, hash in c.rhodecode_repo.branches.items()[:10]:
111 118 try:
112 119 c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash)
113 120 except ChangesetError:
114 121 c.repo_branches[name] = EmptyChangeset(hash)
115 122
116 123 td = date.today() + timedelta(days=1)
117 124 td_1m = td - timedelta(days=calendar.mdays[td.month])
118 125 td_1y = td - timedelta(days=365)
119 126
120 127 ts_min_m = mktime(td_1m.timetuple())
121 128 ts_min_y = mktime(td_1y.timetuple())
122 129 ts_max_y = mktime(td.timetuple())
123 130
124 131 if dbrepo.enable_statistics:
125 132 c.show_stats = True
126 133 c.no_data_msg = _('No data loaded yet')
127 134 run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
128 135 else:
129 136 c.show_stats = False
130 137 c.no_data_msg = _('Statistics are disabled for this repository')
131 138 c.ts_min = ts_min_m
132 139 c.ts_max = ts_max_y
133 140
134 141 stats = self.sa.query(Statistics)\
135 142 .filter(Statistics.repository == dbrepo)\
136 143 .scalar()
137 144
138 145 c.stats_percentage = 0
139 146
140 147 if stats and stats.languages:
141 148 c.no_data = False is dbrepo.enable_statistics
142 149 lang_stats_d = json.loads(stats.languages)
143 150 c.commit_data = stats.commit_activity
144 151 c.overview_data = stats.commit_activity_combined
145 152
146 153 lang_stats = ((x, {"count": y,
147 154 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
148 155 for x, y in lang_stats_d.items())
149 156
150 157 c.trending_languages = json.dumps(OrderedDict(
151 158 sorted(lang_stats, reverse=True,
152 159 key=lambda k: k[1])[:10]
153 160 )
154 161 )
155 162 last_rev = stats.stat_on_revision + 1
156 163 c.repo_last_rev = c.rhodecode_repo.count()\
157 164 if c.rhodecode_repo.revisions else 0
158 165 if last_rev == 0 or c.repo_last_rev == 0:
159 166 pass
160 167 else:
161 168 c.stats_percentage = '%.2f' % ((float((last_rev)) /
162 169 c.repo_last_rev) * 100)
163 170 else:
164 171 c.commit_data = json.dumps({})
165 172 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
166 173 c.trending_languages = json.dumps({})
167 174 c.no_data = True
168 175
169 176 c.enable_downloads = dbrepo.enable_downloads
170 177 if c.enable_downloads:
171 178 c.download_options = self._get_download_links(c.rhodecode_repo)
172 179
173 180 c.readme_data, c.readme_file = self.__get_readme_data(c.rhodecode_repo)
174 181 return render('summary/summary.html')
175 182
176 183 def __get_readme_data(self, repo):
177 184
178 185 @cache_region('long_term')
179 186 def _get_readme_from_cache(key):
180 187 readme_data = None
181 188 readme_file = None
182 189 log.debug('Fetching readme file')
183 190 try:
184 191 cs = repo.get_changeset('tip')
185 192 renderer = MarkupRenderer()
186 193 for f in README_FILES:
187 194 try:
188 195 readme = cs.get_node(f)
189 196 readme_file = f
190 197 readme_data = renderer.render(readme.content, f)
191 198 log.debug('Found readme %s' % readme_file)
192 199 break
193 200 except NodeDoesNotExistError:
194 201 continue
195 202 except ChangesetError:
196 203 pass
197 204 except EmptyRepositoryError:
198 205 pass
199 206 except Exception:
200 207 log.error(traceback.format_exc())
201 208
202 209 return readme_data, readme_file
203 210
204 211 key = repo.name + '_README'
205 212 inv = CacheInvalidation.invalidate(key)
206 213 if inv is not None:
207 214 region_invalidate(_get_readme_from_cache, None, key)
208 215 CacheInvalidation.set_valid(inv.cache_key)
209 216 return _get_readme_from_cache(key)
210 217
211 218 def _get_download_links(self, repo):
212 219
213 220 download_l = []
214 221
215 222 branches_group = ([], _("Branches"))
216 223 tags_group = ([], _("Tags"))
217 224
218 225 for name, chs in c.rhodecode_repo.branches.items():
219 226 #chs = chs.split(':')[-1]
220 227 branches_group[0].append((chs, name),)
221 228 download_l.append(branches_group)
222 229
223 230 for name, chs in c.rhodecode_repo.tags.items():
224 231 #chs = chs.split(':')[-1]
225 232 tags_group[0].append((chs, name),)
226 233 download_l.append(tags_group)
227 234
228 235 return download_l
229 236
@@ -1,154 +1,178 b''
1 1 """The base Controller API
2 2
3 3 Provides the BaseController class for subclassing.
4 4 """
5 5 import logging
6 6 import time
7 import traceback
7 8
8 9 from paste.auth.basic import AuthBasicAuthenticator
9 10
10 11 from pylons import config, tmpl_context as c, request, session, url
11 12 from pylons.controllers import WSGIController
12 13 from pylons.controllers.util import redirect
13 14 from pylons.templating import render_mako as render
14 15
15 16 from rhodecode import __version__, BACKENDS
16 17
17 18 from rhodecode.lib import str2bool
18 19 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
19 20 HasPermissionAnyMiddleware
20 21 from rhodecode.lib.utils import get_repo_slug, invalidate_cache
21 22 from rhodecode.model import meta
22 23
23 24 from rhodecode.model.db import Repository
24 25 from rhodecode.model.notification import NotificationModel
25 26 from rhodecode.model.scm import ScmModel
26 27
27 28 log = logging.getLogger(__name__)
28 29
30
29 31 class BaseVCSController(object):
30
32
31 33 def __init__(self, application, config):
32 34 self.application = application
33 35 self.config = config
34 36 # base path of repo locations
35 37 self.basepath = self.config['base_path']
36 38 #authenticate this mercurial request using authfunc
37 39 self.authenticate = AuthBasicAuthenticator('', authfunc)
38 40 self.ipaddr = '0.0.0.0'
39
41
42 def _get_by_id(self, repo_name):
43 """
44 Get's a special pattern _<ID> from clone url and tries to replace it
45 with a repository_name for support of _<ID> non changable urls
46
47 :param repo_name:
48 """
49 try:
50 data = repo_name.split('/')
51 if len(data) >= 2:
52 by_id = data[1].split('_')
53 if len(by_id) == 2 and by_id[1].isdigit():
54 _repo_name = Repository.get(by_id[1]).repo_name
55 data[1] = _repo_name
56 except:
57 log.debug('Failed to extract repo_name from id %s' % (
58 traceback.format_exc()
59 )
60 )
61
62 return '/'.join(data)
63
40 64 def _invalidate_cache(self, repo_name):
41 65 """
42 66 Set's cache for this repository for invalidation on next access
43
67
44 68 :param repo_name: full repo name, also a cache key
45 69 """
46 70 invalidate_cache('get_repo_cached_%s' % repo_name)
47
71
48 72 def _check_permission(self, action, user, repo_name):
49 73 """
50 74 Checks permissions using action (push/pull) user and repository
51 75 name
52 76
53 77 :param action: push or pull action
54 78 :param user: user instance
55 79 :param repo_name: repository name
56 80 """
57 81 if action == 'push':
58 82 if not HasPermissionAnyMiddleware('repository.write',
59 83 'repository.admin')(user,
60 84 repo_name):
61 85 return False
62 86
63 87 else:
64 88 #any other action need at least read permission
65 89 if not HasPermissionAnyMiddleware('repository.read',
66 90 'repository.write',
67 91 'repository.admin')(user,
68 92 repo_name):
69 93 return False
70 94
71 return True
72
95 return True
96
73 97 def __call__(self, environ, start_response):
74 98 start = time.time()
75 99 try:
76 100 return self._handle_request(environ, start_response)
77 101 finally:
78 102 log = logging.getLogger('rhodecode.' + self.__class__.__name__)
79 103 log.debug('Request time: %.3fs' % (time.time() - start))
80 104 meta.Session.remove()
81 105
82 106
83 107 class BaseController(WSGIController):
84 108
85 109 def __before__(self):
86 110 c.rhodecode_version = __version__
87 111 c.rhodecode_name = config.get('rhodecode_title')
88 112 c.use_gravatar = str2bool(config.get('use_gravatar'))
89 113 c.ga_code = config.get('rhodecode_ga_code')
90 114 c.repo_name = get_repo_slug(request)
91 115 c.backends = BACKENDS.keys()
92 116 c.unread_notifications = NotificationModel()\
93 117 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
94 118 self.cut_off_limit = int(config.get('cut_off_limit'))
95 119
96 120 self.sa = meta.Session
97 121 self.scm_model = ScmModel(self.sa)
98 122
99 123 def __call__(self, environ, start_response):
100 124 """Invoke the Controller"""
101 125 # WSGIController.__call__ dispatches to the Controller method
102 126 # the request is routed to. This routing information is
103 127 # available in environ['pylons.routes_dict']
104 128 start = time.time()
105 129 try:
106 130 # make sure that we update permissions each time we call controller
107 131 api_key = request.GET.get('api_key')
108 132 cookie_store = session.get('rhodecode_user') or {}
109 133 user_id = cookie_store.get('user_id', None)
110 134 username = get_container_username(environ, config)
111 135
112 136 auth_user = AuthUser(user_id, api_key, username)
113 137 request.user = auth_user
114 138 self.rhodecode_user = c.rhodecode_user = auth_user
115 139 if not self.rhodecode_user.is_authenticated and \
116 140 self.rhodecode_user.user_id is not None:
117 141 self.rhodecode_user\
118 142 .set_authenticated(cookie_store.get('is_authenticated'))
119 143
120 144 session['rhodecode_user'] = self.rhodecode_user.get_cookie_store()
121 145 session.save()
122 146 return WSGIController.__call__(self, environ, start_response)
123 147 finally:
124 148 log.debug('Request time: %.3fs' % (time.time() - start))
125 149 meta.Session.remove()
126 150
127 151
128 152 class BaseRepoController(BaseController):
129 153 """
130 154 Base class for controllers responsible for loading all needed data for
131 155 repository loaded items are
132 156
133 157 c.rhodecode_repo: instance of scm repository
134 158 c.rhodecode_db_repo: instance of db
135 159 c.repository_followers: number of followers
136 160 c.repository_forks: number of forks
137 161 """
138 162
139 163 def __before__(self):
140 164 super(BaseRepoController, self).__before__()
141 165 if c.repo_name:
142 166
143 167 c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
144 168 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
145 169
146 170 if c.rhodecode_repo is None:
147 171 log.error('%s this repository is present in database but it '
148 172 'cannot be created as an scm instance', c.repo_name)
149 173
150 174 redirect(url('home'))
151 175
152 176 c.repository_followers = self.scm_model.get_followers(c.repo_name)
153 177 c.repository_forks = self.scm_model.get_forks(c.repo_name)
154 178
@@ -1,247 +1,248 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.lib.middleware.simplegit
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 SimpleGit middleware for handling git protocol request (push/clone etc.)
7 7 It's implemented with basic auth function
8 8
9 9 :created_on: Apr 28, 2010
10 10 :author: marcink
11 11 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
12 12 :license: GPLv3, see COPYING for more details.
13 13 """
14 14 # This program is free software: you can redistribute it and/or modify
15 15 # it under the terms of the GNU General Public License as published by
16 16 # the Free Software Foundation, either version 3 of the License, or
17 17 # (at your option) any later version.
18 18 #
19 19 # This program is distributed in the hope that it will be useful,
20 20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 22 # GNU General Public License for more details.
23 23 #
24 24 # You should have received a copy of the GNU General Public License
25 25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26
27 27 import os
28 28 import logging
29 29 import traceback
30 30
31 31 from dulwich import server as dulserver
32 32
33 33 class SimpleGitUploadPackHandler(dulserver.UploadPackHandler):
34 34
35 35 def handle(self):
36 36 write = lambda x: self.proto.write_sideband(1, x)
37 37
38 38 graph_walker = dulserver.ProtocolGraphWalker(self,
39 39 self.repo.object_store,
40 40 self.repo.get_peeled)
41 41 objects_iter = self.repo.fetch_objects(
42 42 graph_walker.determine_wants, graph_walker, self.progress,
43 43 get_tagged=self.get_tagged)
44 44
45 45 # Do they want any objects?
46 46 if objects_iter is None or len(objects_iter) == 0:
47 47 return
48 48
49 49 self.progress("counting objects: %d, done.\n" % len(objects_iter))
50 50 dulserver.write_pack_objects(dulserver.ProtocolFile(None, write),
51 51 objects_iter, len(objects_iter))
52 52 messages = []
53 53 messages.append('thank you for using rhodecode')
54 54
55 55 for msg in messages:
56 56 self.progress(msg + "\n")
57 57 # we are done
58 58 self.proto.write("0000")
59 59
60 60 dulserver.DEFAULT_HANDLERS = {
61 61 'git-upload-pack': SimpleGitUploadPackHandler,
62 62 'git-receive-pack': dulserver.ReceivePackHandler,
63 63 }
64 64
65 65 from dulwich.repo import Repo
66 66 from dulwich.web import HTTPGitApplication
67 67
68 68 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
69 69
70 70 from rhodecode.lib import safe_str
71 71 from rhodecode.lib.base import BaseVCSController
72 72 from rhodecode.lib.auth import get_container_username
73 73 from rhodecode.lib.utils import is_valid_repo
74 74 from rhodecode.model.db import User
75 75
76 76 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
77 77
78 78 log = logging.getLogger(__name__)
79 79
80 80
81 81 def is_git(environ):
82 82 """Returns True if request's target is git server.
83 83 ``HTTP_USER_AGENT`` would then have git client version given.
84 84
85 85 :param environ:
86 86 """
87 87 http_user_agent = environ.get('HTTP_USER_AGENT')
88 88 if http_user_agent and http_user_agent.startswith('git'):
89 89 return True
90 90 return False
91 91
92 92
93 93 class SimpleGit(BaseVCSController):
94 94
95 95 def _handle_request(self, environ, start_response):
96 96 if not is_git(environ):
97 97 return self.application(environ, start_response)
98 98
99 99 proxy_key = 'HTTP_X_REAL_IP'
100 100 def_key = 'REMOTE_ADDR'
101 101 ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
102 102 username = None
103 103 # skip passing error to error controller
104 104 environ['pylons.status_code_redirect'] = True
105 105
106 106 #======================================================================
107 107 # EXTRACT REPOSITORY NAME FROM ENV
108 108 #======================================================================
109 109 try:
110 110 repo_name = self.__get_repository(environ)
111 111 log.debug('Extracted repo name is %s' % repo_name)
112 112 except:
113 113 return HTTPInternalServerError()(environ, start_response)
114 114
115 115 #======================================================================
116 116 # GET ACTION PULL or PUSH
117 117 #======================================================================
118 118 action = self.__get_action(environ)
119 119
120 120 #======================================================================
121 121 # CHECK ANONYMOUS PERMISSION
122 122 #======================================================================
123 123 if action in ['pull', 'push']:
124 124 anonymous_user = self.__get_user('default')
125 125 username = anonymous_user.username
126 126 anonymous_perm = self._check_permission(action,anonymous_user,
127 127 repo_name)
128 128
129 129 if anonymous_perm is not True or anonymous_user.active is False:
130 130 if anonymous_perm is not True:
131 131 log.debug('Not enough credentials to access this '
132 132 'repository as anonymous user')
133 133 if anonymous_user.active is False:
134 134 log.debug('Anonymous access is disabled, running '
135 135 'authentication')
136 136 #==============================================================
137 137 # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
138 138 # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
139 139 #==============================================================
140 140
141 141 # Attempting to retrieve username from the container
142 142 username = get_container_username(environ, self.config)
143 143
144 144 # If not authenticated by the container, running basic auth
145 145 if not username:
146 146 self.authenticate.realm = \
147 147 safe_str(self.config['rhodecode_realm'])
148 148 result = self.authenticate(environ)
149 149 if isinstance(result, str):
150 150 AUTH_TYPE.update(environ, 'basic')
151 151 REMOTE_USER.update(environ, result)
152 152 username = result
153 153 else:
154 154 return result.wsgi_application(environ, start_response)
155 155
156 156 #==============================================================
157 157 # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME
158 158 #==============================================================
159 159
160 160 if action in ['pull', 'push']:
161 161 try:
162 162 user = self.__get_user(username)
163 163 if user is None or not user.active:
164 164 return HTTPForbidden()(environ, start_response)
165 165 username = user.username
166 166 except:
167 167 log.error(traceback.format_exc())
168 168 return HTTPInternalServerError()(environ,
169 169 start_response)
170 170
171 171 #check permissions for this repository
172 172 perm = self._check_permission(action, user,
173 173 repo_name)
174 174 if perm is not True:
175 175 return HTTPForbidden()(environ, start_response)
176 176
177 177 #===================================================================
178 178 # GIT REQUEST HANDLING
179 179 #===================================================================
180 180
181 181 repo_path = safe_str(os.path.join(self.basepath, repo_name))
182 182 log.debug('Repository path is %s' % repo_path)
183 183
184 184 # quick check if that dir exists...
185 185 if is_valid_repo(repo_name, self.basepath) is False:
186 186 return HTTPNotFound()(environ, start_response)
187 187
188 188 try:
189 189 #invalidate cache on push
190 190 if action == 'push':
191 191 self._invalidate_cache(repo_name)
192 192
193 193 app = self.__make_app(repo_name, repo_path)
194 194 return app(environ, start_response)
195 195 except Exception:
196 196 log.error(traceback.format_exc())
197 197 return HTTPInternalServerError()(environ, start_response)
198 198
199 199 def __make_app(self, repo_name, repo_path):
200 200 """
201 201 Make an wsgi application using dulserver
202 202
203 203 :param repo_name: name of the repository
204 204 :param repo_path: full path to the repository
205 205 """
206 206
207 207 _d = {'/' + repo_name: Repo(repo_path)}
208 208 backend = dulserver.DictBackend(_d)
209 209 gitserve = HTTPGitApplication(backend)
210 210
211 211 return gitserve
212 212
213 213 def __get_repository(self, environ):
214 214 """
215 215 Get's repository name out of PATH_INFO header
216 216
217 217 :param environ: environ where PATH_INFO is stored
218 218 """
219 219 try:
220 environ['PATH_INFO'] = self._get_by_id(environ['PATH_INFO'])
220 221 repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:])
221 222 if repo_name.endswith('/'):
222 223 repo_name = repo_name.rstrip('/')
223 224 except:
224 225 log.error(traceback.format_exc())
225 226 raise
226 227 repo_name = repo_name.split('/')[0]
227 228 return repo_name
228 229
229 230 def __get_user(self, username):
230 231 return User.get_by_username(username)
231 232
232 233 def __get_action(self, environ):
233 234 """Maps git request commands into a pull or push command.
234 235
235 236 :param environ:
236 237 """
237 238 service = environ['QUERY_STRING'].split('=')
238 239 if len(service) > 1:
239 240 service_cmd = service[1]
240 241 mapping = {'git-receive-pack': 'push',
241 242 'git-upload-pack': 'pull',
242 243 }
243 244
244 245 return mapping.get(service_cmd,
245 246 service_cmd if service_cmd else 'other')
246 247 else:
247 248 return 'other'
@@ -1,252 +1,252 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.lib.middleware.simplehg
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 SimpleHG middleware for handling mercurial protocol request
7 7 (push/clone etc.). It's implemented with basic auth function
8 8
9 9 :created_on: Apr 28, 2010
10 10 :author: marcink
11 11 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
12 12 :license: GPLv3, see COPYING for more details.
13 13 """
14 14 # This program is free software: you can redistribute it and/or modify
15 15 # it under the terms of the GNU General Public License as published by
16 16 # the Free Software Foundation, either version 3 of the License, or
17 17 # (at your option) any later version.
18 18 #
19 19 # This program is distributed in the hope that it will be useful,
20 20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 22 # GNU General Public License for more details.
23 23 #
24 24 # You should have received a copy of the GNU General Public License
25 25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26
27 27 import os
28 28 import logging
29 29 import traceback
30 30
31 31 from mercurial.error import RepoError
32 32 from mercurial.hgweb import hgweb_mod
33 33
34 34 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
35 35
36 36 from rhodecode.lib import safe_str
37 37 from rhodecode.lib.base import BaseVCSController
38 38 from rhodecode.lib.auth import get_container_username
39 39 from rhodecode.lib.utils import make_ui, is_valid_repo, ui_sections
40 40 from rhodecode.model.db import User
41 41
42 42 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
43 43
44 44 log = logging.getLogger(__name__)
45 45
46 46
47 47 def is_mercurial(environ):
48 48 """Returns True if request's target is mercurial server - header
49 49 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
50 50 """
51 51 http_accept = environ.get('HTTP_ACCEPT')
52 52 if http_accept and http_accept.startswith('application/mercurial'):
53 53 return True
54 54 return False
55 55
56 56
57 57 class SimpleHg(BaseVCSController):
58 58
59 59 def _handle_request(self, environ, start_response):
60 60 if not is_mercurial(environ):
61 61 return self.application(environ, start_response)
62 62
63 63 proxy_key = 'HTTP_X_REAL_IP'
64 64 def_key = 'REMOTE_ADDR'
65 65 ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
66 66
67 67 # skip passing error to error controller
68 68 environ['pylons.status_code_redirect'] = True
69 69
70 70 #======================================================================
71 71 # EXTRACT REPOSITORY NAME FROM ENV
72 72 #======================================================================
73 73 try:
74 74 repo_name = environ['REPO_NAME'] = self.__get_repository(environ)
75 75 log.debug('Extracted repo name is %s' % repo_name)
76 76 except:
77 77 return HTTPInternalServerError()(environ, start_response)
78 78
79 79 #======================================================================
80 80 # GET ACTION PULL or PUSH
81 81 #======================================================================
82 82 action = self.__get_action(environ)
83 83
84 84 #======================================================================
85 85 # CHECK ANONYMOUS PERMISSION
86 86 #======================================================================
87 87 if action in ['pull', 'push']:
88 88 anonymous_user = self.__get_user('default')
89 89
90 90 username = anonymous_user.username
91 91 anonymous_perm = self._check_permission(action,anonymous_user,
92 92 repo_name)
93 93
94 94 if anonymous_perm is not True or anonymous_user.active is False:
95 95 if anonymous_perm is not True:
96 96 log.debug('Not enough credentials to access this '
97 97 'repository as anonymous user')
98 98 if anonymous_user.active is False:
99 99 log.debug('Anonymous access is disabled, running '
100 100 'authentication')
101 101 #==============================================================
102 102 # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
103 103 # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
104 104 #==============================================================
105 105
106 106 # Attempting to retrieve username from the container
107 107 username = get_container_username(environ, self.config)
108 108
109 109 # If not authenticated by the container, running basic auth
110 110 if not username:
111 111 self.authenticate.realm = \
112 112 safe_str(self.config['rhodecode_realm'])
113 113 result = self.authenticate(environ)
114 114 if isinstance(result, str):
115 115 AUTH_TYPE.update(environ, 'basic')
116 116 REMOTE_USER.update(environ, result)
117 117 username = result
118 118 else:
119 119 return result.wsgi_application(environ, start_response)
120 120
121 121 #==============================================================
122 122 # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME
123 123 #==============================================================
124 124
125 125 if action in ['pull', 'push']:
126 126 try:
127 127 user = self.__get_user(username)
128 128 if user is None or not user.active:
129 129 return HTTPForbidden()(environ, start_response)
130 130 username = user.username
131 131 except:
132 132 log.error(traceback.format_exc())
133 133 return HTTPInternalServerError()(environ,
134 134 start_response)
135 135
136 136 #check permissions for this repository
137 137 perm = self._check_permission(action, user,
138 138 repo_name)
139 139 if perm is not True:
140 140 return HTTPForbidden()(environ, start_response)
141 141
142 142 extras = {'ip': ipaddr,
143 143 'username': username,
144 144 'action': action,
145 145 'repository': repo_name}
146 146
147 147 #======================================================================
148 148 # MERCURIAL REQUEST HANDLING
149 149 #======================================================================
150 150
151 151 repo_path = safe_str(os.path.join(self.basepath, repo_name))
152 152 log.debug('Repository path is %s' % repo_path)
153 153
154 154 baseui = make_ui('db')
155 155 self.__inject_extras(repo_path, baseui, extras)
156 156
157 157
158 158 # quick check if that dir exists...
159 159 if is_valid_repo(repo_name, self.basepath) is False:
160 160 return HTTPNotFound()(environ, start_response)
161 161
162 162 try:
163 163 # invalidate cache on push
164 164 if action == 'push':
165 165 self._invalidate_cache(repo_name)
166 166
167 167 app = self.__make_app(repo_path, baseui, extras)
168 168 return app(environ, start_response)
169 169 except RepoError, e:
170 170 if str(e).find('not found') != -1:
171 171 return HTTPNotFound()(environ, start_response)
172 172 except Exception:
173 173 log.error(traceback.format_exc())
174 174 return HTTPInternalServerError()(environ, start_response)
175 175
176 176 def __make_app(self, repo_name, baseui, extras):
177 177 """
178 178 Make an wsgi application using hgweb, and inject generated baseui
179 179 instance, additionally inject some extras into ui object
180 180 """
181 181 return hgweb_mod.hgweb(repo_name, name=repo_name, baseui=baseui)
182 182
183
184 183 def __get_repository(self, environ):
185 184 """
186 185 Get's repository name out of PATH_INFO header
187 186
188 187 :param environ: environ where PATH_INFO is stored
189 188 """
190 189 try:
190 environ['PATH_INFO'] = self._get_by_id(environ['PATH_INFO'])
191 191 repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:])
192 192 if repo_name.endswith('/'):
193 193 repo_name = repo_name.rstrip('/')
194 194 except:
195 195 log.error(traceback.format_exc())
196 196 raise
197 197
198 198 return repo_name
199 199
200 200 def __get_user(self, username):
201 201 return User.get_by_username(username)
202 202
203 203 def __get_action(self, environ):
204 204 """
205 205 Maps mercurial request commands into a clone,pull or push command.
206 206 This should always return a valid command string
207 207
208 208 :param environ:
209 209 """
210 210 mapping = {'changegroup': 'pull',
211 211 'changegroupsubset': 'pull',
212 212 'stream_out': 'pull',
213 213 'listkeys': 'pull',
214 214 'unbundle': 'push',
215 215 'pushkey': 'push', }
216 216 for qry in environ['QUERY_STRING'].split('&'):
217 217 if qry.startswith('cmd'):
218 218 cmd = qry.split('=')[-1]
219 219 if cmd in mapping:
220 220 return mapping[cmd]
221 221 else:
222 222 return 'pull'
223 223
224 224
225 225 def __inject_extras(self, repo_path, baseui, extras={}):
226 226 """
227 227 Injects some extra params into baseui instance
228 228
229 229 also overwrites global settings with those takes from local hgrc file
230 230
231 231 :param baseui: baseui instance
232 232 :param extras: dict with extra params to put into baseui
233 233 """
234 234
235 235 hgrc = os.path.join(repo_path, '.hg', 'hgrc')
236 236
237 237 # make our hgweb quiet so it doesn't print output
238 238 baseui.setconfig('ui', 'quiet', 'true')
239 239
240 240 #inject some additional parameters that will be available in ui
241 241 #for hooks
242 242 for k, v in extras.items():
243 243 baseui.setconfig('rhodecode_extras', k, v)
244 244
245 245 repoui = make_ui('file', hgrc, False)
246 246
247 247 if repoui:
248 248 #overwrite our ui instance with the section from hgrc file
249 249 for section in ui_sections:
250 250 for k, v in repoui.configitems(section):
251 251 baseui.setconfig(section, k, v)
252 252
@@ -1,4080 +1,4094 b''
1 1 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td
2 2 {
3 3 border: 0;
4 4 outline: 0;
5 5 font-size: 100%;
6 6 vertical-align: baseline;
7 7 background: transparent;
8 8 margin: 0;
9 9 padding: 0;
10 10 }
11 11
12 12 body {
13 13 line-height: 1;
14 14 height: 100%;
15 15 background: url("../images/background.png") repeat scroll 0 0 #B0B0B0;
16 16 font-family: Lucida Grande, Verdana, Lucida Sans Regular,
17 17 Lucida Sans Unicode, Arial, sans-serif; font-size : 12px;
18 18 color: #000;
19 19 margin: 0;
20 20 padding: 0;
21 21 font-size: 12px;
22 22 }
23 23
24 24 ol,ul {
25 25 list-style: none;
26 26 }
27 27
28 28 blockquote,q {
29 29 quotes: none;
30 30 }
31 31
32 32 blockquote:before,blockquote:after,q:before,q:after {
33 33 content: none;
34 34 }
35 35
36 36 :focus {
37 37 outline: 0;
38 38 }
39 39
40 40 del {
41 41 text-decoration: line-through;
42 42 }
43 43
44 44 table {
45 45 border-collapse: collapse;
46 46 border-spacing: 0;
47 47 }
48 48
49 49 html {
50 50 height: 100%;
51 51 }
52 52
53 53 a {
54 54 color: #003367;
55 55 text-decoration: none;
56 56 cursor: pointer;
57 57 }
58 58
59 59 a:hover {
60 60 color: #316293;
61 61 text-decoration: underline;
62 62 }
63 63
64 64 h1,h2,h3,h4,h5,h6 {
65 65 color: #292929;
66 66 font-weight: 700;
67 67 }
68 68
69 69 h1 {
70 70 font-size: 22px;
71 71 }
72 72
73 73 h2 {
74 74 font-size: 20px;
75 75 }
76 76
77 77 h3 {
78 78 font-size: 18px;
79 79 }
80 80
81 81 h4 {
82 82 font-size: 16px;
83 83 }
84 84
85 85 h5 {
86 86 font-size: 14px;
87 87 }
88 88
89 89 h6 {
90 90 font-size: 11px;
91 91 }
92 92
93 93 ul.circle {
94 94 list-style-type: circle;
95 95 }
96 96
97 97 ul.disc {
98 98 list-style-type: disc;
99 99 }
100 100
101 101 ul.square {
102 102 list-style-type: square;
103 103 }
104 104
105 105 ol.lower-roman {
106 106 list-style-type: lower-roman;
107 107 }
108 108
109 109 ol.upper-roman {
110 110 list-style-type: upper-roman;
111 111 }
112 112
113 113 ol.lower-alpha {
114 114 list-style-type: lower-alpha;
115 115 }
116 116
117 117 ol.upper-alpha {
118 118 list-style-type: upper-alpha;
119 119 }
120 120
121 121 ol.decimal {
122 122 list-style-type: decimal;
123 123 }
124 124
125 125 div.color {
126 126 clear: both;
127 127 overflow: hidden;
128 128 position: absolute;
129 129 background: #FFF;
130 130 margin: 7px 0 0 60px;
131 131 padding: 1px 1px 1px 0;
132 132 }
133 133
134 134 div.color a {
135 135 width: 15px;
136 136 height: 15px;
137 137 display: block;
138 138 float: left;
139 139 margin: 0 0 0 1px;
140 140 padding: 0;
141 141 }
142 142
143 143 div.options {
144 144 clear: both;
145 145 overflow: hidden;
146 146 position: absolute;
147 147 background: #FFF;
148 148 margin: 7px 0 0 162px;
149 149 padding: 0;
150 150 }
151 151
152 152 div.options a {
153 153 height: 1%;
154 154 display: block;
155 155 text-decoration: none;
156 156 margin: 0;
157 157 padding: 3px 8px;
158 158 }
159 159
160 160 .top-left-rounded-corner {
161 161 -webkit-border-top-left-radius: 8px;
162 162 -khtml-border-radius-topleft: 8px;
163 163 -moz-border-radius-topleft: 8px;
164 164 border-top-left-radius: 8px;
165 165 }
166 166
167 167 .top-right-rounded-corner {
168 168 -webkit-border-top-right-radius: 8px;
169 169 -khtml-border-radius-topright: 8px;
170 170 -moz-border-radius-topright: 8px;
171 171 border-top-right-radius: 8px;
172 172 }
173 173
174 174 .bottom-left-rounded-corner {
175 175 -webkit-border-bottom-left-radius: 8px;
176 176 -khtml-border-radius-bottomleft: 8px;
177 177 -moz-border-radius-bottomleft: 8px;
178 178 border-bottom-left-radius: 8px;
179 179 }
180 180
181 181 .bottom-right-rounded-corner {
182 182 -webkit-border-bottom-right-radius: 8px;
183 183 -khtml-border-radius-bottomright: 8px;
184 184 -moz-border-radius-bottomright: 8px;
185 185 border-bottom-right-radius: 8px;
186 186 }
187 187
188 188 #header {
189 189 margin: 0;
190 190 padding: 0 10px;
191 191 }
192 192
193 193 #header ul#logged-user {
194 194 margin-bottom: 5px !important;
195 195 -webkit-border-radius: 0px 0px 8px 8px;
196 196 -khtml-border-radius: 0px 0px 8px 8px;
197 197 -moz-border-radius: 0px 0px 8px 8px;
198 198 border-radius: 0px 0px 8px 8px;
199 199 height: 37px;
200 200 background-color: #eedc94;
201 201 background-repeat: repeat-x;
202 202 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1),
203 203 to(#eedc94) );
204 204 background-image: -moz-linear-gradient(top, #003b76, #00376e);
205 205 background-image: -ms-linear-gradient(top, #003b76, #00376e);
206 206 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),
207 207 color-stop(100%, #00376e) );
208 208 background-image: -webkit-linear-gradient(top, #003b76, #00376e) );
209 209 background-image: -o-linear-gradient(top, #003b76, #00376e) );
210 210 background-image: linear-gradient(top, #003b76, #00376e);
211 211 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
212 212 endColorstr='#00376e', GradientType=0 );
213 213 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
214 214 }
215 215
216 216 #header ul#logged-user li {
217 217 list-style: none;
218 218 float: left;
219 219 margin: 8px 0 0;
220 220 padding: 4px 12px;
221 221 border-left: 1px solid #316293;
222 222 }
223 223
224 224 #header ul#logged-user li.first {
225 225 border-left: none;
226 226 margin: 4px;
227 227 }
228 228
229 229 #header ul#logged-user li.first div.gravatar {
230 230 margin-top: -2px;
231 231 }
232 232
233 233 #header ul#logged-user li.first div.account {
234 234 padding-top: 4px;
235 235 float: left;
236 236 }
237 237
238 238 #header ul#logged-user li.last {
239 239 border-right: none;
240 240 }
241 241
242 242 #header ul#logged-user li a {
243 243 color: #fff;
244 244 font-weight: 700;
245 245 text-decoration: none;
246 246 }
247 247
248 248 #header ul#logged-user li a:hover {
249 249 text-decoration: underline;
250 250 }
251 251
252 252 #header ul#logged-user li.highlight a {
253 253 color: #fff;
254 254 }
255 255
256 256 #header ul#logged-user li.highlight a:hover {
257 257 color: #FFF;
258 258 }
259 259
260 260 #header #header-inner {
261 261 min-height: 40px;
262 262 clear: both;
263 263 position: relative;
264 264 background-color: #eedc94;
265 265 background-repeat: repeat-x;
266 266 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1),
267 267 to(#eedc94) );
268 268 background-image: -moz-linear-gradient(top, #003b76, #00376e);
269 269 background-image: -ms-linear-gradient(top, #003b76, #00376e);
270 270 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),
271 271 color-stop(100%, #00376e) );
272 272 background-image: -webkit-linear-gradient(top, #003b76, #00376e) );
273 273 background-image: -o-linear-gradient(top, #003b76, #00376e) );
274 274 background-image: linear-gradient(top, #003b76, #00376e);
275 275 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
276 276 endColorstr='#00376e', GradientType=0 );
277 277 margin: 0;
278 278 padding: 0;
279 279 display: block;
280 280 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
281 281 -webkit-border-radius: 4px 4px 4px 4px;
282 282 -khtml-border-radius: 4px 4px 4px 4px;
283 283 -moz-border-radius: 4px 4px 4px 4px;
284 284 border-radius: 4px 4px 4px 4px;
285 285 }
286 286 #header #header-inner.hover{
287 287 position: fixed !important;
288 288 width: 100% !important;
289 289 margin-left: -10px !important;
290 290 z-index: 10000;
291 291 border-radius: 0px 0px 4px 4px;
292 292 }
293 293 #header #header-inner #home a {
294 294 height: 40px;
295 295 width: 46px;
296 296 display: block;
297 297 background: url("../images/button_home.png");
298 298 background-position: 0 0;
299 299 margin: 0;
300 300 padding: 0;
301 301 }
302 302
303 303 #header #header-inner #home a:hover {
304 304 background-position: 0 -40px;
305 305 }
306 306
307 307 #header #header-inner #logo {
308 308 float: left;
309 309 position: absolute;
310 310 }
311 311
312 312 #header #header-inner #logo h1 {
313 313 color: #FFF;
314 314 font-size: 18px;
315 315 margin: 10px 0 0 13px;
316 316 padding: 0;
317 317 }
318 318
319 319 #header #header-inner #logo a {
320 320 color: #fff;
321 321 text-decoration: none;
322 322 }
323 323
324 324 #header #header-inner #logo a:hover {
325 325 color: #bfe3ff;
326 326 }
327 327
328 328 #header #header-inner #quick,#header #header-inner #quick ul {
329 329 position: relative;
330 330 float: right;
331 331 list-style-type: none;
332 332 list-style-position: outside;
333 333 margin: 6px 5px 0 0;
334 334 padding: 0;
335 335 }
336 336
337 337 #header #header-inner #quick li {
338 338 position: relative;
339 339 float: left;
340 340 margin: 0 5px 0 0;
341 341 padding: 0;
342 342 }
343 343
344 344 #header #header-inner #quick li a {
345 345 top: 0;
346 346 left: 0;
347 347 height: 1%;
348 348 display: block;
349 349 clear: both;
350 350 overflow: hidden;
351 351 color: #FFF;
352 352 font-weight: 700;
353 353 text-decoration: none;
354 354 background: #369;
355 355 padding: 0;
356 356 -webkit-border-radius: 4px 4px 4px 4px;
357 357 -khtml-border-radius: 4px 4px 4px 4px;
358 358 -moz-border-radius: 4px 4px 4px 4px;
359 359 border-radius: 4px 4px 4px 4px;
360 360 }
361 361
362 362 #header #header-inner #quick li span.short {
363 363 padding: 9px 6px 8px 6px;
364 364 }
365 365
366 366 #header #header-inner #quick li span {
367 367 top: 0;
368 368 right: 0;
369 369 height: 1%;
370 370 display: block;
371 371 float: left;
372 372 border-left: 1px solid #3f6f9f;
373 373 margin: 0;
374 374 padding: 10px 12px 8px 10px;
375 375 }
376 376
377 377 #header #header-inner #quick li span.normal {
378 378 border: none;
379 379 padding: 10px 12px 8px;
380 380 }
381 381
382 382 #header #header-inner #quick li span.icon {
383 383 top: 0;
384 384 left: 0;
385 385 border-left: none;
386 386 border-right: 1px solid #2e5c89;
387 387 padding: 8px 6px 4px;
388 388 }
389 389
390 390 #header #header-inner #quick li span.icon_short {
391 391 top: 0;
392 392 left: 0;
393 393 border-left: none;
394 394 border-right: 1px solid #2e5c89;
395 395 padding: 8px 6px 4px;
396 396 }
397 397
398 398 #header #header-inner #quick li span.icon img,#header #header-inner #quick li span.icon_short img
399 399 {
400 400 margin: 0px -2px 0px 0px;
401 401 }
402 402
403 403 #header #header-inner #quick li a:hover {
404 404 background: #4e4e4e no-repeat top left;
405 405 }
406 406
407 407 #header #header-inner #quick li a:hover span {
408 408 border-left: 1px solid #545454;
409 409 }
410 410
411 411 #header #header-inner #quick li a:hover span.icon,#header #header-inner #quick li a:hover span.icon_short
412 412 {
413 413 border-left: none;
414 414 border-right: 1px solid #464646;
415 415 }
416 416
417 417 #header #header-inner #quick ul {
418 418 top: 29px;
419 419 right: 0;
420 420 min-width: 200px;
421 421 display: none;
422 422 position: absolute;
423 423 background: #FFF;
424 424 border: 1px solid #666;
425 425 border-top: 1px solid #003367;
426 426 z-index: 100;
427 427 margin: 0;
428 428 padding: 0;
429 429 }
430 430
431 431 #header #header-inner #quick ul.repo_switcher {
432 432 max-height: 275px;
433 433 overflow-x: hidden;
434 434 overflow-y: auto;
435 435 }
436 436
437 437 #header #header-inner #quick ul.repo_switcher li.qfilter_rs {
438 438 float: none;
439 439 margin: 0;
440 440 border-bottom: 2px solid #003367;
441 441 }
442 442
443 443 #header #header-inner #quick .repo_switcher_type {
444 444 position: absolute;
445 445 left: 0;
446 446 top: 9px;
447 447 }
448 448
449 449 #header #header-inner #quick li ul li {
450 450 border-bottom: 1px solid #ddd;
451 451 }
452 452
453 453 #header #header-inner #quick li ul li a {
454 454 width: 182px;
455 455 height: auto;
456 456 display: block;
457 457 float: left;
458 458 background: #FFF;
459 459 color: #003367;
460 460 font-weight: 400;
461 461 margin: 0;
462 462 padding: 7px 9px;
463 463 }
464 464
465 465 #header #header-inner #quick li ul li a:hover {
466 466 color: #000;
467 467 background: #FFF;
468 468 }
469 469
470 470 #header #header-inner #quick ul ul {
471 471 top: auto;
472 472 }
473 473
474 474 #header #header-inner #quick li ul ul {
475 475 right: 200px;
476 476 max-height: 275px;
477 477 overflow: auto;
478 478 overflow-x: hidden;
479 479 white-space: normal;
480 480 }
481 481
482 482 #header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover
483 483 {
484 484 background: url("../images/icons/book.png") no-repeat scroll 4px 9px
485 485 #FFF;
486 486 width: 167px;
487 487 margin: 0;
488 488 padding: 12px 9px 7px 24px;
489 489 }
490 490
491 491 #header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover
492 492 {
493 493 background: url("../images/icons/lock.png") no-repeat scroll 4px 9px
494 494 #FFF;
495 495 min-width: 167px;
496 496 margin: 0;
497 497 padding: 12px 9px 7px 24px;
498 498 }
499 499
500 500 #header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover
501 501 {
502 502 background: url("../images/icons/lock_open.png") no-repeat scroll 4px
503 503 9px #FFF;
504 504 min-width: 167px;
505 505 margin: 0;
506 506 padding: 12px 9px 7px 24px;
507 507 }
508 508
509 509 #header #header-inner #quick li ul li a.hg,#header #header-inner #quick li ul li a.hg:hover
510 510 {
511 511 background: url("../images/icons/hgicon.png") no-repeat scroll 4px 9px
512 512 #FFF;
513 513 min-width: 167px;
514 514 margin: 0 0 0 14px;
515 515 padding: 12px 9px 7px 24px;
516 516 }
517 517
518 518 #header #header-inner #quick li ul li a.git,#header #header-inner #quick li ul li a.git:hover
519 519 {
520 520 background: url("../images/icons/giticon.png") no-repeat scroll 4px 9px
521 521 #FFF;
522 522 min-width: 167px;
523 523 margin: 0 0 0 14px;
524 524 padding: 12px 9px 7px 24px;
525 525 }
526 526
527 527 #header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover
528 528 {
529 529 background: url("../images/icons/database_edit.png") no-repeat scroll
530 530 4px 9px #FFF;
531 531 width: 167px;
532 532 margin: 0;
533 533 padding: 12px 9px 7px 24px;
534 534 }
535 535
536 536 #header #header-inner #quick li ul li a.repos_groups,#header #header-inner #quick li ul li a.repos_groups:hover
537 537 {
538 538 background: url("../images/icons/database_link.png") no-repeat scroll
539 539 4px 9px #FFF;
540 540 width: 167px;
541 541 margin: 0;
542 542 padding: 12px 9px 7px 24px;
543 543 }
544 544
545 545 #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover
546 546 {
547 547 background: #FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
548 548 width: 167px;
549 549 margin: 0;
550 550 padding: 12px 9px 7px 24px;
551 551 }
552 552
553 553 #header #header-inner #quick li ul li a.groups,#header #header-inner #quick li ul li a.groups:hover
554 554 {
555 555 background: #FFF url("../images/icons/group_edit.png") no-repeat 4px 9px;
556 556 width: 167px;
557 557 margin: 0;
558 558 padding: 12px 9px 7px 24px;
559 559 }
560 560
561 561 #header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover
562 562 {
563 563 background: #FFF url("../images/icons/cog.png") no-repeat 4px 9px;
564 564 width: 167px;
565 565 margin: 0;
566 566 padding: 12px 9px 7px 24px;
567 567 }
568 568
569 569 #header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover
570 570 {
571 571 background: #FFF url("../images/icons/key.png") no-repeat 4px 9px;
572 572 width: 167px;
573 573 margin: 0;
574 574 padding: 12px 9px 7px 24px;
575 575 }
576 576
577 577 #header #header-inner #quick li ul li a.ldap,#header #header-inner #quick li ul li a.ldap:hover
578 578 {
579 579 background: #FFF url("../images/icons/server_key.png") no-repeat 4px 9px;
580 580 width: 167px;
581 581 margin: 0;
582 582 padding: 12px 9px 7px 24px;
583 583 }
584 584
585 585 #header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover
586 586 {
587 587 background: #FFF url("../images/icons/arrow_divide.png") no-repeat 4px
588 588 9px;
589 589 width: 167px;
590 590 margin: 0;
591 591 padding: 12px 9px 7px 24px;
592 592 }
593 593
594 594 #header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover
595 595 {
596 596 background: #FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
597 597 width: 167px;
598 598 margin: 0;
599 599 padding: 12px 9px 7px 24px;
600 600 }
601 601
602 602 #header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover
603 603 {
604 604 background: #FFF url("../images/icons/delete.png") no-repeat 4px 9px;
605 605 width: 167px;
606 606 margin: 0;
607 607 padding: 12px 9px 7px 24px;
608 608 }
609 609
610 610 #header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover
611 611 {
612 612 background: #FFF url("../images/icons/arrow_branch.png") no-repeat 4px
613 613 9px;
614 614 width: 167px;
615 615 margin: 0;
616 616 padding: 12px 9px 7px 24px;
617 617 }
618 618
619 619 #header #header-inner #quick li ul li a.tags,
620 620 #header #header-inner #quick li ul li a.tags:hover{
621 621 background: #FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
622 622 width: 167px;
623 623 margin: 0;
624 624 padding: 12px 9px 7px 24px;
625 625 }
626 626
627 627 #header #header-inner #quick li ul li a.bookmarks,
628 628 #header #header-inner #quick li ul li a.bookmarks:hover{
629 629 background: #FFF url("../images/icons/tag_green.png") no-repeat 4px 9px;
630 630 width: 167px;
631 631 margin: 0;
632 632 padding: 12px 9px 7px 24px;
633 633 }
634 634
635 635 #header #header-inner #quick li ul li a.admin,
636 636 #header #header-inner #quick li ul li a.admin:hover{
637 637 background: #FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
638 638 width: 167px;
639 639 margin: 0;
640 640 padding: 12px 9px 7px 24px;
641 641 }
642 642
643 643 .groups_breadcrumbs a {
644 644 color: #fff;
645 645 }
646 646
647 647 .groups_breadcrumbs a:hover {
648 648 color: #bfe3ff;
649 649 text-decoration: none;
650 650 }
651 651
652 652 td.quick_repo_menu {
653 653 background: #FFF url("../images/vertical-indicator.png") 8px 50% no-repeat !important;
654 654 cursor: pointer;
655 655 width: 8px;
656 656 border: 1px solid transparent;
657 657 }
658 658
659 659 td.quick_repo_menu.active {
660 660 background: url("../images/dt-arrow-dn.png") no-repeat scroll 5px 50% #FFFFFF !important;
661 661 border: 1px solid #003367;
662 662 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
663 663 cursor: pointer;
664 664 }
665 665
666 666 td.quick_repo_menu .menu_items {
667 667 margin-top: 10px;
668 668 margin-left:-6px;
669 669 width: 150px;
670 670 position: absolute;
671 671 background-color: #FFF;
672 672 background: none repeat scroll 0 0 #FFFFFF;
673 673 border-color: #003367 #666666 #666666;
674 674 border-right: 1px solid #666666;
675 675 border-style: solid;
676 676 border-width: 1px;
677 677 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
678 678 border-top-style: none;
679 679 }
680 680
681 681 td.quick_repo_menu .menu_items li {
682 682 padding: 0 !important;
683 683 }
684 684
685 685 td.quick_repo_menu .menu_items a {
686 686 display: block;
687 687 padding: 4px 12px 4px 8px;
688 688 }
689 689
690 690 td.quick_repo_menu .menu_items a:hover {
691 691 background-color: #EEE;
692 692 text-decoration: none;
693 693 }
694 694
695 695 td.quick_repo_menu .menu_items .icon img {
696 696 margin-bottom: -2px;
697 697 }
698 698
699 699 td.quick_repo_menu .menu_items.hidden {
700 700 display: none;
701 701 }
702 702
703 703 .yui-dt-first th {
704 704 text-align: left;
705 705 }
706 706
707 707 /*
708 708 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
709 709 Code licensed under the BSD License:
710 710 http://developer.yahoo.com/yui/license.html
711 711 version: 2.9.0
712 712 */
713 713 .yui-skin-sam .yui-dt-mask {
714 714 position: absolute;
715 715 z-index: 9500;
716 716 }
717 717 .yui-dt-tmp {
718 718 position: absolute;
719 719 left: -9000px;
720 720 }
721 721 .yui-dt-scrollable .yui-dt-bd { overflow: auto }
722 722 .yui-dt-scrollable .yui-dt-hd {
723 723 overflow: hidden;
724 724 position: relative;
725 725 }
726 726 .yui-dt-scrollable .yui-dt-bd thead tr,
727 727 .yui-dt-scrollable .yui-dt-bd thead th {
728 728 position: absolute;
729 729 left: -1500px;
730 730 }
731 731 .yui-dt-scrollable tbody { -moz-outline: 0 }
732 732 .yui-skin-sam thead .yui-dt-sortable { cursor: pointer }
733 733 .yui-skin-sam thead .yui-dt-draggable { cursor: move }
734 734 .yui-dt-coltarget {
735 735 position: absolute;
736 736 z-index: 999;
737 737 }
738 738 .yui-dt-hd { zoom: 1 }
739 739 th.yui-dt-resizeable .yui-dt-resizerliner { position: relative }
740 740 .yui-dt-resizer {
741 741 position: absolute;
742 742 right: 0;
743 743 bottom: 0;
744 744 height: 100%;
745 745 cursor: e-resize;
746 746 cursor: col-resize;
747 747 background-color: #CCC;
748 748 opacity: 0;
749 749 filter: alpha(opacity=0);
750 750 }
751 751 .yui-dt-resizerproxy {
752 752 visibility: hidden;
753 753 position: absolute;
754 754 z-index: 9000;
755 755 background-color: #CCC;
756 756 opacity: 0;
757 757 filter: alpha(opacity=0);
758 758 }
759 759 th.yui-dt-hidden .yui-dt-liner,
760 760 td.yui-dt-hidden .yui-dt-liner,
761 761 th.yui-dt-hidden .yui-dt-resizer { display: none }
762 762 .yui-dt-editor,
763 763 .yui-dt-editor-shim {
764 764 position: absolute;
765 765 z-index: 9000;
766 766 }
767 767 .yui-skin-sam .yui-dt table {
768 768 margin: 0;
769 769 padding: 0;
770 770 font-family: arial;
771 771 font-size: inherit;
772 772 border-collapse: separate;
773 773 *border-collapse: collapse;
774 774 border-spacing: 0;
775 775 border: 1px solid #7f7f7f;
776 776 }
777 777 .yui-skin-sam .yui-dt thead { border-spacing: 0 }
778 778 .yui-skin-sam .yui-dt caption {
779 779 color: #000;
780 780 font-size: 85%;
781 781 font-weight: normal;
782 782 font-style: italic;
783 783 line-height: 1;
784 784 padding: 1em 0;
785 785 text-align: center;
786 786 }
787 787 .yui-skin-sam .yui-dt th { background: #d8d8da url(../images/sprite.png) repeat-x 0 0 }
788 788 .yui-skin-sam .yui-dt th,
789 789 .yui-skin-sam .yui-dt th a {
790 790 font-weight: normal;
791 791 text-decoration: none;
792 792 color: #000;
793 793 vertical-align: bottom;
794 794 }
795 795 .yui-skin-sam .yui-dt th {
796 796 margin: 0;
797 797 padding: 0;
798 798 border: 0;
799 799 border-right: 1px solid #cbcbcb;
800 800 }
801 801 .yui-skin-sam .yui-dt tr.yui-dt-first td { border-top: 1px solid #7f7f7f }
802 802 .yui-skin-sam .yui-dt th .yui-dt-liner { white-space: nowrap }
803 803 .yui-skin-sam .yui-dt-liner {
804 804 margin: 0;
805 805 padding: 0;
806 806 }
807 807 .yui-skin-sam .yui-dt-coltarget {
808 808 width: 5px;
809 809 background-color: red;
810 810 }
811 811 .yui-skin-sam .yui-dt td {
812 812 margin: 0;
813 813 padding: 0;
814 814 border: 0;
815 815 border-right: 1px solid #cbcbcb;
816 816 text-align: left;
817 817 }
818 818 .yui-skin-sam .yui-dt-list td { border-right: 0 }
819 819 .yui-skin-sam .yui-dt-resizer { width: 6px }
820 820 .yui-skin-sam .yui-dt-mask {
821 821 background-color: #000;
822 822 opacity: .25;
823 823 filter: alpha(opacity=25);
824 824 }
825 825 .yui-skin-sam .yui-dt-message { background-color: #FFF }
826 826 .yui-skin-sam .yui-dt-scrollable table { border: 0 }
827 827 .yui-skin-sam .yui-dt-scrollable .yui-dt-hd {
828 828 border-left: 1px solid #7f7f7f;
829 829 border-top: 1px solid #7f7f7f;
830 830 border-right: 1px solid #7f7f7f;
831 831 }
832 832 .yui-skin-sam .yui-dt-scrollable .yui-dt-bd {
833 833 border-left: 1px solid #7f7f7f;
834 834 border-bottom: 1px solid #7f7f7f;
835 835 border-right: 1px solid #7f7f7f;
836 836 background-color: #FFF;
837 837 }
838 838 .yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td { border-bottom: 1px solid #7f7f7f }
839 839 .yui-skin-sam th.yui-dt-asc,
840 840 .yui-skin-sam th.yui-dt-desc { background: url(../images/sprite.png) repeat-x 0 -100px }
841 841 .yui-skin-sam th.yui-dt-sortable .yui-dt-label { margin-right: 10px }
842 842 .yui-skin-sam th.yui-dt-asc .yui-dt-liner { background: url(../images/dt-arrow-up.png) no-repeat right }
843 843 .yui-skin-sam th.yui-dt-desc .yui-dt-liner { background: url(../images/dt-arrow-dn.png) no-repeat right }
844 844 tbody .yui-dt-editable { cursor: pointer }
845 845 .yui-dt-editor {
846 846 text-align: left;
847 847 background-color: #f2f2f2;
848 848 border: 1px solid #808080;
849 849 padding: 6px;
850 850 }
851 851 .yui-dt-editor label {
852 852 padding-left: 4px;
853 853 padding-right: 6px;
854 854 }
855 855 .yui-dt-editor .yui-dt-button {
856 856 padding-top: 6px;
857 857 text-align: right;
858 858 }
859 859 .yui-dt-editor .yui-dt-button button {
860 860 background: url(../images/sprite.png) repeat-x 0 0;
861 861 border: 1px solid #999;
862 862 width: 4em;
863 863 height: 1.8em;
864 864 margin-left: 6px;
865 865 }
866 866 .yui-dt-editor .yui-dt-button button.yui-dt-default {
867 867 background: url(../images/sprite.png) repeat-x 0 -1400px;
868 868 background-color: #5584e0;
869 869 border: 1px solid #304369;
870 870 color: #FFF;
871 871 }
872 872 .yui-dt-editor .yui-dt-button button:hover {
873 873 background: url(../images/sprite.png) repeat-x 0 -1300px;
874 874 color: #000;
875 875 }
876 876 .yui-dt-editor .yui-dt-button button:active {
877 877 background: url(../images/sprite.png) repeat-x 0 -1700px;
878 878 color: #000;
879 879 }
880 880 .yui-skin-sam tr.yui-dt-even { background-color: #FFF }
881 881 .yui-skin-sam tr.yui-dt-odd { background-color: #edf5ff }
882 882 .yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
883 883 .yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
884 884 .yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
885 885 .yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color: #dbeaff }
886 886 .yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color: #FFF }
887 887 .yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color: #FFF }
888 888 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
889 889 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
890 890 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
891 891 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color: #edf5ff }
892 892 .yui-skin-sam th.yui-dt-highlighted,
893 893 .yui-skin-sam th.yui-dt-highlighted a { background-color: #b2d2ff }
894 894 .yui-skin-sam tr.yui-dt-highlighted,
895 895 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
896 896 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
897 897 .yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
898 898 .yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
899 899 cursor: pointer;
900 900 background-color: #b2d2ff;
901 901 }
902 902 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted,
903 903 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted a { background-color: #b2d2ff }
904 904 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
905 905 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
906 906 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
907 907 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
908 908 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
909 909 cursor: pointer;
910 910 background-color: #b2d2ff;
911 911 }
912 912 .yui-skin-sam th.yui-dt-selected,
913 913 .yui-skin-sam th.yui-dt-selected a { background-color: #446cd7 }
914 914 .yui-skin-sam tr.yui-dt-selected td,
915 915 .yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
916 916 .yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
917 917 background-color: #426fd9;
918 918 color: #FFF;
919 919 }
920 920 .yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
921 921 .yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
922 922 background-color: #446cd7;
923 923 color: #FFF;
924 924 }
925 925 .yui-skin-sam .yui-dt-list th.yui-dt-selected,
926 926 .yui-skin-sam .yui-dt-list th.yui-dt-selected a { background-color: #446cd7 }
927 927 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
928 928 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
929 929 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
930 930 background-color: #426fd9;
931 931 color: #FFF;
932 932 }
933 933 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
934 934 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
935 935 background-color: #446cd7;
936 936 color: #FFF;
937 937 }
938 938 .yui-skin-sam .yui-dt-paginator {
939 939 display: block;
940 940 margin: 6px 0;
941 941 white-space: nowrap;
942 942 }
943 943 .yui-skin-sam .yui-dt-paginator .yui-dt-first,
944 944 .yui-skin-sam .yui-dt-paginator .yui-dt-last,
945 945 .yui-skin-sam .yui-dt-paginator .yui-dt-selected { padding: 2px 6px }
946 946 .yui-skin-sam .yui-dt-paginator a.yui-dt-first,
947 947 .yui-skin-sam .yui-dt-paginator a.yui-dt-last { text-decoration: none }
948 948 .yui-skin-sam .yui-dt-paginator .yui-dt-previous,
949 949 .yui-skin-sam .yui-dt-paginator .yui-dt-next { display: none }
950 950 .yui-skin-sam a.yui-dt-page {
951 951 border: 1px solid #cbcbcb;
952 952 padding: 2px 6px;
953 953 text-decoration: none;
954 954 background-color: #fff;
955 955 }
956 956 .yui-skin-sam .yui-dt-selected {
957 957 border: 1px solid #fff;
958 958 background-color: #fff;
959 959 }
960 960
961 961 #content #left {
962 962 left: 0;
963 963 width: 280px;
964 964 position: absolute;
965 965 }
966 966
967 967 #content #right {
968 968 margin: 0 60px 10px 290px;
969 969 }
970 970
971 971 #content div.box {
972 972 clear: both;
973 973 overflow: hidden;
974 974 background: #fff;
975 975 margin: 0 0 10px;
976 976 padding: 0 0 10px;
977 977 -webkit-border-radius: 4px 4px 4px 4px;
978 978 -khtml-border-radius: 4px 4px 4px 4px;
979 979 -moz-border-radius: 4px 4px 4px 4px;
980 980 border-radius: 4px 4px 4px 4px;
981 981 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
982 982 }
983 983
984 984 #content div.box-left {
985 985 width: 49%;
986 986 clear: none;
987 987 float: left;
988 988 margin: 0 0 10px;
989 989 }
990 990
991 991 #content div.box-right {
992 992 width: 49%;
993 993 clear: none;
994 994 float: right;
995 995 margin: 0 0 10px;
996 996 }
997 997
998 998 #content div.box div.title {
999 999 clear: both;
1000 1000 overflow: hidden;
1001 1001 background-color: #eedc94;
1002 1002 background-repeat: repeat-x;
1003 1003 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1),
1004 1004 to(#eedc94) );
1005 1005 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1006 1006 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1007 1007 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),
1008 1008 color-stop(100%, #00376e) );
1009 1009 background-image: -webkit-linear-gradient(top, #003b76, #00376e) );
1010 1010 background-image: -o-linear-gradient(top, #003b76, #00376e) );
1011 1011 background-image: linear-gradient(top, #003b76, #00376e);
1012 1012 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
1013 1013 endColorstr='#00376e', GradientType=0 );
1014 1014 margin: 0 0 20px;
1015 1015 padding: 0;
1016 1016 }
1017 1017
1018 1018 #content div.box div.title h5 {
1019 1019 float: left;
1020 1020 border: none;
1021 1021 color: #fff;
1022 1022 text-transform: uppercase;
1023 1023 margin: 0;
1024 1024 padding: 11px 0 11px 10px;
1025 1025 }
1026 1026
1027 1027 #content div.box div.title .link-white{
1028 1028 color: #FFFFFF;
1029 1029 }
1030 1030
1031 1031 #content div.box div.title ul.links li {
1032 1032 list-style: none;
1033 1033 float: left;
1034 1034 margin: 0;
1035 1035 padding: 0;
1036 1036 }
1037 1037
1038 1038 #content div.box div.title ul.links li a {
1039 1039 border-left: 1px solid #316293;
1040 1040 color: #FFFFFF;
1041 1041 display: block;
1042 1042 float: left;
1043 1043 font-size: 13px;
1044 1044 font-weight: 700;
1045 1045 height: 1%;
1046 1046 margin: 0;
1047 1047 padding: 11px 22px 12px;
1048 1048 text-decoration: none;
1049 1049 }
1050 1050
1051 1051 #content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6
1052 1052 {
1053 1053 clear: both;
1054 1054 overflow: hidden;
1055 1055 border-bottom: 1px solid #DDD;
1056 1056 margin: 10px 20px;
1057 1057 padding: 0 0 15px;
1058 1058 }
1059 1059
1060 1060 #content div.box p {
1061 1061 color: #5f5f5f;
1062 1062 font-size: 12px;
1063 1063 line-height: 150%;
1064 1064 margin: 0 24px 10px;
1065 1065 padding: 0;
1066 1066 }
1067 1067
1068 1068 #content div.box blockquote {
1069 1069 border-left: 4px solid #DDD;
1070 1070 color: #5f5f5f;
1071 1071 font-size: 11px;
1072 1072 line-height: 150%;
1073 1073 margin: 0 34px;
1074 1074 padding: 0 0 0 14px;
1075 1075 }
1076 1076
1077 1077 #content div.box blockquote p {
1078 1078 margin: 10px 0;
1079 1079 padding: 0;
1080 1080 }
1081 1081
1082 1082 #content div.box dl {
1083 1083 margin: 10px 0px;
1084 1084 }
1085 1085
1086 1086 #content div.box dt {
1087 1087 font-size: 12px;
1088 1088 margin: 0;
1089 1089 }
1090 1090
1091 1091 #content div.box dd {
1092 1092 font-size: 12px;
1093 1093 margin: 0;
1094 1094 padding: 8px 0 8px 15px;
1095 1095 }
1096 1096
1097 1097 #content div.box li {
1098 1098 font-size: 12px;
1099 1099 padding: 4px 0;
1100 1100 }
1101 1101
1102 1102 #content div.box ul.disc,#content div.box ul.circle {
1103 1103 margin: 10px 24px 10px 38px;
1104 1104 }
1105 1105
1106 1106 #content div.box ul.square {
1107 1107 margin: 10px 24px 10px 40px;
1108 1108 }
1109 1109
1110 1110 #content div.box img.left {
1111 1111 border: none;
1112 1112 float: left;
1113 1113 margin: 10px 10px 10px 0;
1114 1114 }
1115 1115
1116 1116 #content div.box img.right {
1117 1117 border: none;
1118 1118 float: right;
1119 1119 margin: 10px 0 10px 10px;
1120 1120 }
1121 1121
1122 1122 #content div.box div.messages {
1123 1123 clear: both;
1124 1124 overflow: hidden;
1125 1125 margin: 0 20px;
1126 1126 padding: 0;
1127 1127 }
1128 1128
1129 1129 #content div.box div.message {
1130 1130 clear: both;
1131 1131 overflow: hidden;
1132 1132 margin: 0;
1133 1133 padding: 10px 0;
1134 1134 }
1135 1135
1136 1136 #content div.box div.message a {
1137 1137 font-weight: 400 !important;
1138 1138 }
1139 1139
1140 1140 #content div.box div.message div.image {
1141 1141 float: left;
1142 1142 margin: 9px 0 0 5px;
1143 1143 padding: 6px;
1144 1144 }
1145 1145
1146 1146 #content div.box div.message div.image img {
1147 1147 vertical-align: middle;
1148 1148 margin: 0;
1149 1149 }
1150 1150
1151 1151 #content div.box div.message div.text {
1152 1152 float: left;
1153 1153 margin: 0;
1154 1154 padding: 9px 6px;
1155 1155 }
1156 1156
1157 1157 #content div.box div.message div.dismiss a {
1158 1158 height: 16px;
1159 1159 width: 16px;
1160 1160 display: block;
1161 1161 background: url("../images/icons/cross.png") no-repeat;
1162 1162 margin: 15px 14px 0 0;
1163 1163 padding: 0;
1164 1164 }
1165 1165
1166 1166 #content div.box div.message div.text h1,#content div.box div.message div.text h2,#content div.box div.message div.text h3,#content div.box div.message div.text h4,#content div.box div.message div.text h5,#content div.box div.message div.text h6
1167 1167 {
1168 1168 border: none;
1169 1169 margin: 0;
1170 1170 padding: 0;
1171 1171 }
1172 1172
1173 1173 #content div.box div.message div.text span {
1174 1174 height: 1%;
1175 1175 display: block;
1176 1176 margin: 0;
1177 1177 padding: 5px 0 0;
1178 1178 }
1179 1179
1180 1180 #content div.box div.message-error {
1181 1181 height: 1%;
1182 1182 clear: both;
1183 1183 overflow: hidden;
1184 1184 background: #FBE3E4;
1185 1185 border: 1px solid #FBC2C4;
1186 1186 color: #860006;
1187 1187 }
1188 1188
1189 1189 #content div.box div.message-error h6 {
1190 1190 color: #860006;
1191 1191 }
1192 1192
1193 1193 #content div.box div.message-warning {
1194 1194 height: 1%;
1195 1195 clear: both;
1196 1196 overflow: hidden;
1197 1197 background: #FFF6BF;
1198 1198 border: 1px solid #FFD324;
1199 1199 color: #5f5200;
1200 1200 }
1201 1201
1202 1202 #content div.box div.message-warning h6 {
1203 1203 color: #5f5200;
1204 1204 }
1205 1205
1206 1206 #content div.box div.message-notice {
1207 1207 height: 1%;
1208 1208 clear: both;
1209 1209 overflow: hidden;
1210 1210 background: #8FBDE0;
1211 1211 border: 1px solid #6BACDE;
1212 1212 color: #003863;
1213 1213 }
1214 1214
1215 1215 #content div.box div.message-notice h6 {
1216 1216 color: #003863;
1217 1217 }
1218 1218
1219 1219 #content div.box div.message-success {
1220 1220 height: 1%;
1221 1221 clear: both;
1222 1222 overflow: hidden;
1223 1223 background: #E6EFC2;
1224 1224 border: 1px solid #C6D880;
1225 1225 color: #4e6100;
1226 1226 }
1227 1227
1228 1228 #content div.box div.message-success h6 {
1229 1229 color: #4e6100;
1230 1230 }
1231 1231
1232 1232 #content div.box div.form div.fields div.field {
1233 1233 height: 1%;
1234 1234 border-bottom: 1px solid #DDD;
1235 1235 clear: both;
1236 1236 margin: 0;
1237 1237 padding: 10px 0;
1238 1238 }
1239 1239
1240 1240 #content div.box div.form div.fields div.field-first {
1241 1241 padding: 0 0 10px;
1242 1242 }
1243 1243
1244 1244 #content div.box div.form div.fields div.field-noborder {
1245 1245 border-bottom: 0 !important;
1246 1246 }
1247 1247
1248 1248 #content div.box div.form div.fields div.field span.error-message {
1249 1249 height: 1%;
1250 1250 display: inline-block;
1251 1251 color: red;
1252 1252 margin: 8px 0 0 4px;
1253 1253 padding: 0;
1254 1254 }
1255 1255
1256 1256 #content div.box div.form div.fields div.field span.success {
1257 1257 height: 1%;
1258 1258 display: block;
1259 1259 color: #316309;
1260 1260 margin: 8px 0 0;
1261 1261 padding: 0;
1262 1262 }
1263 1263
1264 1264 #content div.box div.form div.fields div.field div.label {
1265 1265 left: 70px;
1266 1266 width: 155px;
1267 1267 position: absolute;
1268 1268 margin: 0;
1269 1269 padding: 5px 0 0 0px;
1270 1270 }
1271 1271
1272 1272 #content div.box div.form div.fields div.field div.label-summary {
1273 1273 left: 30px;
1274 1274 width: 155px;
1275 1275 position: absolute;
1276 1276 margin: 0;
1277 1277 padding: 0px 0 0 0px;
1278 1278 }
1279 1279
1280 1280 #content div.box-left div.form div.fields div.field div.label,
1281 1281 #content div.box-right div.form div.fields div.field div.label,
1282 1282 #content div.box-left div.form div.fields div.field div.label,
1283 1283 #content div.box-left div.form div.fields div.field div.label-summary,
1284 1284 #content div.box-right div.form div.fields div.field div.label-summary,
1285 1285 #content div.box-left div.form div.fields div.field div.label-summary
1286 1286 {
1287 1287 clear: both;
1288 1288 overflow: hidden;
1289 1289 left: 0;
1290 1290 width: auto;
1291 1291 position: relative;
1292 1292 margin: 0;
1293 1293 padding: 0 0 8px;
1294 1294 }
1295 1295
1296 1296 #content div.box div.form div.fields div.field div.label-select {
1297 1297 padding: 5px 0 0 5px;
1298 1298 }
1299 1299
1300 1300 #content div.box-left div.form div.fields div.field div.label-select,
1301 1301 #content div.box-right div.form div.fields div.field div.label-select
1302 1302 {
1303 1303 padding: 0 0 8px;
1304 1304 }
1305 1305
1306 1306 #content div.box-left div.form div.fields div.field div.label-textarea,
1307 1307 #content div.box-right div.form div.fields div.field div.label-textarea
1308 1308 {
1309 1309 padding: 0 0 8px !important;
1310 1310 }
1311 1311
1312 1312 #content div.box div.form div.fields div.field div.label label,div.label label
1313 1313 {
1314 1314 color: #393939;
1315 1315 font-weight: 700;
1316 1316 }
1317 1317 #content div.box div.form div.fields div.field div.label label,div.label-summary label
1318 1318 {
1319 1319 color: #393939;
1320 1320 font-weight: 700;
1321 1321 }
1322 1322 #content div.box div.form div.fields div.field div.input {
1323 1323 margin: 0 0 0 200px;
1324 1324 }
1325 1325
1326 1326 #content div.box div.form div.fields div.field div.input.summary {
1327 1327 margin: 0 0 0 110px;
1328 1328 }
1329 1329 #content div.box div.form div.fields div.field div.input.summary-short {
1330 1330 margin: 0 0 0 110px;
1331 1331 }
1332 1332 #content div.box div.form div.fields div.field div.file {
1333 1333 margin: 0 0 0 200px;
1334 1334 }
1335 1335
1336 1336 #content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input
1337 1337 {
1338 1338 margin: 0 0 0 0px;
1339 1339 }
1340 1340
1341 1341 #content div.box div.form div.fields div.field div.input input {
1342 1342 background: #FFF;
1343 1343 border-top: 1px solid #b3b3b3;
1344 1344 border-left: 1px solid #b3b3b3;
1345 1345 border-right: 1px solid #eaeaea;
1346 1346 border-bottom: 1px solid #eaeaea;
1347 1347 color: #000;
1348 1348 font-size: 11px;
1349 1349 margin: 0;
1350 1350 padding: 7px 7px 6px;
1351 1351 }
1352 1352
1353 #content div.box div.form div.fields div.field div.input input#clone_url{
1353 #content div.box div.form div.fields div.field div.input input#clone_url,
1354 #content div.box div.form div.fields div.field div.input input#clone_url_id
1355 {
1354 1356 font-size: 16px;
1355 padding: 2px 7px 2px;
1357 padding: 2px;
1356 1358 }
1357 1359
1358 1360 #content div.box div.form div.fields div.field div.file input {
1359 1361 background: none repeat scroll 0 0 #FFFFFF;
1360 1362 border-color: #B3B3B3 #EAEAEA #EAEAEA #B3B3B3;
1361 1363 border-style: solid;
1362 1364 border-width: 1px;
1363 1365 color: #000000;
1364 1366 font-size: 11px;
1365 1367 margin: 0;
1366 1368 padding: 7px 7px 6px;
1367 1369 }
1368 1370
1369 1371 #content div.box div.form div.fields div.field div.input input.small {
1370 1372 width: 30%;
1371 1373 }
1372 1374
1373 1375 #content div.box div.form div.fields div.field div.input input.medium {
1374 1376 width: 55%;
1375 1377 }
1376 1378
1377 1379 #content div.box div.form div.fields div.field div.input input.large {
1378 1380 width: 85%;
1379 1381 }
1380 1382
1381 1383 #content div.box div.form div.fields div.field div.input input.date {
1382 1384 width: 177px;
1383 1385 }
1384 1386
1385 1387 #content div.box div.form div.fields div.field div.input input.button {
1386 1388 background: #D4D0C8;
1387 1389 border-top: 1px solid #FFF;
1388 1390 border-left: 1px solid #FFF;
1389 1391 border-right: 1px solid #404040;
1390 1392 border-bottom: 1px solid #404040;
1391 1393 color: #000;
1392 1394 margin: 0;
1393 1395 padding: 4px 8px;
1394 1396 }
1395 1397
1396 1398 #content div.box div.form div.fields div.field div.textarea {
1397 1399 border-top: 1px solid #b3b3b3;
1398 1400 border-left: 1px solid #b3b3b3;
1399 1401 border-right: 1px solid #eaeaea;
1400 1402 border-bottom: 1px solid #eaeaea;
1401 1403 margin: 0 0 0 200px;
1402 1404 padding: 10px;
1403 1405 }
1404 1406
1405 1407 #content div.box div.form div.fields div.field div.textarea-editor {
1406 1408 border: 1px solid #ddd;
1407 1409 padding: 0;
1408 1410 }
1409 1411
1410 1412 #content div.box div.form div.fields div.field div.textarea textarea {
1411 1413 width: 100%;
1412 1414 height: 220px;
1413 1415 overflow: hidden;
1414 1416 background: #FFF;
1415 1417 color: #000;
1416 1418 font-size: 11px;
1417 1419 outline: none;
1418 1420 border-width: 0;
1419 1421 margin: 0;
1420 1422 padding: 0;
1421 1423 }
1422 1424
1423 1425 #content div.box-left div.form div.fields div.field div.textarea textarea,#content div.box-right div.form div.fields div.field div.textarea textarea
1424 1426 {
1425 1427 width: 100%;
1426 1428 height: 100px;
1427 1429 }
1428 1430
1429 1431 #content div.box div.form div.fields div.field div.textarea table {
1430 1432 width: 100%;
1431 1433 border: none;
1432 1434 margin: 0;
1433 1435 padding: 0;
1434 1436 }
1435 1437
1436 1438 #content div.box div.form div.fields div.field div.textarea table td {
1437 1439 background: #DDD;
1438 1440 border: none;
1439 1441 padding: 0;
1440 1442 }
1441 1443
1442 1444 #content div.box div.form div.fields div.field div.textarea table td table
1443 1445 {
1444 1446 width: auto;
1445 1447 border: none;
1446 1448 margin: 0;
1447 1449 padding: 0;
1448 1450 }
1449 1451
1450 1452 #content div.box div.form div.fields div.field div.textarea table td table td
1451 1453 {
1452 1454 font-size: 11px;
1453 1455 padding: 5px 5px 5px 0;
1454 1456 }
1455 1457
1456 1458 #content div.box div.form div.fields div.field input[type=text]:focus,#content div.box div.form div.fields div.field input[type=password]:focus,#content div.box div.form div.fields div.field input[type=file]:focus,#content div.box div.form div.fields div.field textarea:focus,#content div.box div.form div.fields div.field select:focus
1457 1459 {
1458 1460 background: #f6f6f6;
1459 1461 border-color: #666;
1460 1462 }
1461 1463
1462 1464 div.form div.fields div.field div.button {
1463 1465 margin: 0;
1464 1466 padding: 0 0 0 8px;
1465 1467 }
1466 1468 #content div.box table.noborder {
1467 1469 border: 1px solid transparent;
1468 1470 }
1469 1471
1470 1472 #content div.box table {
1471 1473 width: 100%;
1472 1474 border-collapse: separate;
1473 1475 margin: 0;
1474 1476 padding: 0;
1475 1477 border: 1px solid #eee;
1476 1478 -webkit-border-radius: 4px;
1477 1479 -moz-border-radius: 4px;
1478 1480 border-radius: 4px;
1479 1481 }
1480 1482
1481 1483 #content div.box table th {
1482 1484 background: #eee;
1483 1485 border-bottom: 1px solid #ddd;
1484 1486 padding: 5px 0px 5px 5px;
1485 1487 }
1486 1488
1487 1489 #content div.box table th.left {
1488 1490 text-align: left;
1489 1491 }
1490 1492
1491 1493 #content div.box table th.right {
1492 1494 text-align: right;
1493 1495 }
1494 1496
1495 1497 #content div.box table th.center {
1496 1498 text-align: center;
1497 1499 }
1498 1500
1499 1501 #content div.box table th.selected {
1500 1502 vertical-align: middle;
1501 1503 padding: 0;
1502 1504 }
1503 1505
1504 1506 #content div.box table td {
1505 1507 background: #fff;
1506 1508 border-bottom: 1px solid #cdcdcd;
1507 1509 vertical-align: middle;
1508 1510 padding: 5px;
1509 1511 }
1510 1512
1511 1513 #content div.box table tr.selected td {
1512 1514 background: #FFC;
1513 1515 }
1514 1516
1515 1517 #content div.box table td.selected {
1516 1518 width: 3%;
1517 1519 text-align: center;
1518 1520 vertical-align: middle;
1519 1521 padding: 0;
1520 1522 }
1521 1523
1522 1524 #content div.box table td.action {
1523 1525 width: 45%;
1524 1526 text-align: left;
1525 1527 }
1526 1528
1527 1529 #content div.box table td.date {
1528 1530 width: 33%;
1529 1531 text-align: center;
1530 1532 }
1531 1533
1532 1534 #content div.box div.action {
1533 1535 float: right;
1534 1536 background: #FFF;
1535 1537 text-align: right;
1536 1538 margin: 10px 0 0;
1537 1539 padding: 0;
1538 1540 }
1539 1541
1540 1542 #content div.box div.action select {
1541 1543 font-size: 11px;
1542 1544 margin: 0;
1543 1545 }
1544 1546
1545 1547 #content div.box div.action .ui-selectmenu {
1546 1548 margin: 0;
1547 1549 padding: 0;
1548 1550 }
1549 1551
1550 1552 #content div.box div.pagination {
1551 1553 height: 1%;
1552 1554 clear: both;
1553 1555 overflow: hidden;
1554 1556 margin: 10px 0 0;
1555 1557 padding: 0;
1556 1558 }
1557 1559
1558 1560 #content div.box div.pagination ul.pager {
1559 1561 float: right;
1560 1562 text-align: right;
1561 1563 margin: 0;
1562 1564 padding: 0;
1563 1565 }
1564 1566
1565 1567 #content div.box div.pagination ul.pager li {
1566 1568 height: 1%;
1567 1569 float: left;
1568 1570 list-style: none;
1569 1571 background: #ebebeb url("../images/pager.png") repeat-x;
1570 1572 border-top: 1px solid #dedede;
1571 1573 border-left: 1px solid #cfcfcf;
1572 1574 border-right: 1px solid #c4c4c4;
1573 1575 border-bottom: 1px solid #c4c4c4;
1574 1576 color: #4A4A4A;
1575 1577 font-weight: 700;
1576 1578 margin: 0 0 0 4px;
1577 1579 padding: 0;
1578 1580 }
1579 1581
1580 1582 #content div.box div.pagination ul.pager li.separator {
1581 1583 padding: 6px;
1582 1584 }
1583 1585
1584 1586 #content div.box div.pagination ul.pager li.current {
1585 1587 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1586 1588 border-top: 1px solid #ccc;
1587 1589 border-left: 1px solid #bebebe;
1588 1590 border-right: 1px solid #b1b1b1;
1589 1591 border-bottom: 1px solid #afafaf;
1590 1592 color: #515151;
1591 1593 padding: 6px;
1592 1594 }
1593 1595
1594 1596 #content div.box div.pagination ul.pager li a {
1595 1597 height: 1%;
1596 1598 display: block;
1597 1599 float: left;
1598 1600 color: #515151;
1599 1601 text-decoration: none;
1600 1602 margin: 0;
1601 1603 padding: 6px;
1602 1604 }
1603 1605
1604 1606 #content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active
1605 1607 {
1606 1608 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1607 1609 border-top: 1px solid #ccc;
1608 1610 border-left: 1px solid #bebebe;
1609 1611 border-right: 1px solid #b1b1b1;
1610 1612 border-bottom: 1px solid #afafaf;
1611 1613 margin: -1px;
1612 1614 }
1613 1615
1614 1616 #content div.box div.pagination-wh {
1615 1617 height: 1%;
1616 1618 clear: both;
1617 1619 overflow: hidden;
1618 1620 text-align: right;
1619 1621 margin: 10px 0 0;
1620 1622 padding: 0;
1621 1623 }
1622 1624
1623 1625 #content div.box div.pagination-right {
1624 1626 float: right;
1625 1627 }
1626 1628
1627 1629 #content div.box div.pagination-wh a,#content div.box div.pagination-wh span.pager_dotdot
1628 1630 {
1629 1631 height: 1%;
1630 1632 float: left;
1631 1633 background: #ebebeb url("../images/pager.png") repeat-x;
1632 1634 border-top: 1px solid #dedede;
1633 1635 border-left: 1px solid #cfcfcf;
1634 1636 border-right: 1px solid #c4c4c4;
1635 1637 border-bottom: 1px solid #c4c4c4;
1636 1638 color: #4A4A4A;
1637 1639 font-weight: 700;
1638 1640 margin: 0 0 0 4px;
1639 1641 padding: 6px;
1640 1642 }
1641 1643
1642 1644 #content div.box div.pagination-wh span.pager_curpage {
1643 1645 height: 1%;
1644 1646 float: left;
1645 1647 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1646 1648 border-top: 1px solid #ccc;
1647 1649 border-left: 1px solid #bebebe;
1648 1650 border-right: 1px solid #b1b1b1;
1649 1651 border-bottom: 1px solid #afafaf;
1650 1652 color: #515151;
1651 1653 font-weight: 700;
1652 1654 margin: 0 0 0 4px;
1653 1655 padding: 6px;
1654 1656 }
1655 1657
1656 1658 #content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active
1657 1659 {
1658 1660 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1659 1661 border-top: 1px solid #ccc;
1660 1662 border-left: 1px solid #bebebe;
1661 1663 border-right: 1px solid #b1b1b1;
1662 1664 border-bottom: 1px solid #afafaf;
1663 1665 text-decoration: none;
1664 1666 }
1665 1667
1666 1668 #content div.box div.traffic div.legend {
1667 1669 clear: both;
1668 1670 overflow: hidden;
1669 1671 border-bottom: 1px solid #ddd;
1670 1672 margin: 0 0 10px;
1671 1673 padding: 0 0 10px;
1672 1674 }
1673 1675
1674 1676 #content div.box div.traffic div.legend h6 {
1675 1677 float: left;
1676 1678 border: none;
1677 1679 margin: 0;
1678 1680 padding: 0;
1679 1681 }
1680 1682
1681 1683 #content div.box div.traffic div.legend li {
1682 1684 list-style: none;
1683 1685 float: left;
1684 1686 font-size: 11px;
1685 1687 margin: 0;
1686 1688 padding: 0 8px 0 4px;
1687 1689 }
1688 1690
1689 1691 #content div.box div.traffic div.legend li.visits {
1690 1692 border-left: 12px solid #edc240;
1691 1693 }
1692 1694
1693 1695 #content div.box div.traffic div.legend li.pageviews {
1694 1696 border-left: 12px solid #afd8f8;
1695 1697 }
1696 1698
1697 1699 #content div.box div.traffic table {
1698 1700 width: auto;
1699 1701 }
1700 1702
1701 1703 #content div.box div.traffic table td {
1702 1704 background: transparent;
1703 1705 border: none;
1704 1706 padding: 2px 3px 3px;
1705 1707 }
1706 1708
1707 1709 #content div.box div.traffic table td.legendLabel {
1708 1710 padding: 0 3px 2px;
1709 1711 }
1710 1712
1711 1713 #summary {
1712 1714
1713 1715 }
1714 1716
1715 1717 #summary .desc {
1716 1718 white-space: pre;
1717 1719 width: 100%;
1718 1720 }
1719 1721
1720 1722 #summary .repo_name {
1721 1723 font-size: 1.6em;
1722 1724 font-weight: bold;
1723 1725 vertical-align: baseline;
1724 1726 clear: right
1725 1727 }
1726 1728
1727 1729 #footer {
1728 1730 clear: both;
1729 1731 overflow: hidden;
1730 1732 text-align: right;
1731 1733 margin: 0;
1732 1734 padding: 0 10px 4px;
1733 1735 margin: -10px 0 0;
1734 1736 }
1735 1737
1736 1738 #footer div#footer-inner {
1737 1739 background-color: #eedc94; background-repeat : repeat-x;
1738 1740 background-image : -khtml-gradient( linear, left top, left bottom,
1739 1741 from( #fceec1), to( #eedc94)); background-image : -moz-linear-gradient(
1740 1742 top, #003b76, #00376e); background-image : -ms-linear-gradient( top,
1741 1743 #003b76, #00376e); background-image : -webkit-gradient( linear, left
1742 1744 top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1743 1745 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
1744 1746 background-image : -o-linear-gradient( top, #003b76, #00376e));
1745 1747 background-image : linear-gradient( top, #003b76, #00376e); filter :
1746 1748 progid : DXImageTransform.Microsoft.gradient ( startColorstr =
1747 1749 '#003b76', endColorstr = '#00376e', GradientType = 0);
1748 1750 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1749 1751 -webkit-border-radius: 4px 4px 4px 4px;
1750 1752 -khtml-border-radius: 4px 4px 4px 4px;
1751 1753 -moz-border-radius: 4px 4px 4px 4px;
1752 1754 border-radius: 4px 4px 4px 4px;
1753 1755 background-repeat: repeat-x;
1754 1756 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1),
1755 1757 to(#eedc94) );
1756 1758 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1757 1759 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1758 1760 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),
1759 1761 color-stop(100%, #00376e) );
1760 1762 background-image: -webkit-linear-gradient(top, #003b76, #00376e) );
1761 1763 background-image: -o-linear-gradient(top, #003b76, #00376e) );
1762 1764 background-image: linear-gradient(top, #003b76, #00376e);
1763 1765 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
1764 1766 endColorstr='#00376e', GradientType=0 );
1765 1767 }
1766 1768
1767 1769 #footer div#footer-inner p {
1768 1770 padding: 15px 25px 15px 0;
1769 1771 color: #FFF;
1770 1772 font-weight: 700;
1771 1773 }
1772 1774
1773 1775 #footer div#footer-inner .footer-link {
1774 1776 float: left;
1775 1777 padding-left: 10px;
1776 1778 }
1777 1779
1778 1780 #footer div#footer-inner .footer-link a,#footer div#footer-inner .footer-link-right a
1779 1781 {
1780 1782 color: #FFF;
1781 1783 }
1782 1784
1783 1785 #login div.title {
1784 1786 width: 420px;
1785 1787 clear: both;
1786 1788 overflow: hidden;
1787 1789 position: relative;
1788 1790 background-color: #eedc94; background-repeat : repeat-x;
1789 1791 background-image : -khtml-gradient( linear, left top, left bottom,
1790 1792 from( #fceec1), to( #eedc94)); background-image : -moz-linear-gradient(
1791 1793 top, #003b76, #00376e); background-image : -ms-linear-gradient( top,
1792 1794 #003b76, #00376e); background-image : -webkit-gradient( linear, left
1793 1795 top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1794 1796 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
1795 1797 background-image : -o-linear-gradient( top, #003b76, #00376e));
1796 1798 background-image : linear-gradient( top, #003b76, #00376e); filter :
1797 1799 progid : DXImageTransform.Microsoft.gradient ( startColorstr =
1798 1800 '#003b76', endColorstr = '#00376e', GradientType = 0);
1799 1801 margin: 0 auto;
1800 1802 padding: 0;
1801 1803 background-repeat: repeat-x;
1802 1804 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1),
1803 1805 to(#eedc94) );
1804 1806 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1805 1807 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1806 1808 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),
1807 1809 color-stop(100%, #00376e) );
1808 1810 background-image: -webkit-linear-gradient(top, #003b76, #00376e) );
1809 1811 background-image: -o-linear-gradient(top, #003b76, #00376e) );
1810 1812 background-image: linear-gradient(top, #003b76, #00376e);
1811 1813 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
1812 1814 endColorstr='#00376e', GradientType=0 );
1813 1815 }
1814 1816
1815 1817 #login div.inner {
1816 1818 width: 380px;
1817 1819 background: #FFF url("../images/login.png") no-repeat top left;
1818 1820 border-top: none;
1819 1821 border-bottom: none;
1820 1822 margin: 0 auto;
1821 1823 padding: 20px;
1822 1824 }
1823 1825
1824 1826 #login div.form div.fields div.field div.label {
1825 1827 width: 173px;
1826 1828 float: left;
1827 1829 text-align: right;
1828 1830 margin: 2px 10px 0 0;
1829 1831 padding: 5px 0 0 5px;
1830 1832 }
1831 1833
1832 1834 #login div.form div.fields div.field div.input input {
1833 1835 width: 176px;
1834 1836 background: #FFF;
1835 1837 border-top: 1px solid #b3b3b3;
1836 1838 border-left: 1px solid #b3b3b3;
1837 1839 border-right: 1px solid #eaeaea;
1838 1840 border-bottom: 1px solid #eaeaea;
1839 1841 color: #000;
1840 1842 font-size: 11px;
1841 1843 margin: 0;
1842 1844 padding: 7px 7px 6px;
1843 1845 }
1844 1846
1845 1847 #login div.form div.fields div.buttons {
1846 1848 clear: both;
1847 1849 overflow: hidden;
1848 1850 border-top: 1px solid #DDD;
1849 1851 text-align: right;
1850 1852 margin: 0;
1851 1853 padding: 10px 0 0;
1852 1854 }
1853 1855
1854 1856 #login div.form div.links {
1855 1857 clear: both;
1856 1858 overflow: hidden;
1857 1859 margin: 10px 0 0;
1858 1860 padding: 0 0 2px;
1859 1861 }
1860 1862
1861 1863 #quick_login {
1862 1864 top: 31px;
1863 1865 background-color: rgb(0, 51, 103);
1864 1866 z-index: 999;
1865 1867 height: 150px;
1866 1868 position: absolute;
1867 1869 margin-left: -16px;
1868 1870 width: 281px;
1869 1871 -webkit-border-radius: 0px 0px 4px 4px;
1870 1872 -khtml-border-radius: 0px 0px 4px 4px;
1871 1873 -moz-border-radius: 0px 0px 4px 4px;
1872 1874 border-radius: 0px 0px 4px 4px;
1873 1875 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1874 1876 }
1875 1877
1876 1878 #quick_login .password_forgoten {
1877 1879 padding-right: 10px;
1878 1880 padding-top: 0px;
1879 1881 float: left;
1880 1882 }
1881 1883
1882 1884 #quick_login .password_forgoten a {
1883 1885 font-size: 10px
1884 1886 }
1885 1887
1886 1888 #quick_login .register {
1887 1889 padding-right: 10px;
1888 1890 padding-top: 5px;
1889 1891 float: left;
1890 1892 }
1891 1893
1892 1894 #quick_login .register a {
1893 1895 font-size: 10px
1894 1896 }
1895 1897
1896 1898 #quick_login div.form div.fields {
1897 1899 padding-top: 2px;
1898 1900 padding-left: 10px;
1899 1901 }
1900 1902
1901 1903 #quick_login div.form div.fields div.field {
1902 1904 padding: 5px;
1903 1905 }
1904 1906
1905 1907 #quick_login div.form div.fields div.field div.label label {
1906 1908 color: #fff;
1907 1909 padding-bottom: 3px;
1908 1910 }
1909 1911
1910 1912 #quick_login div.form div.fields div.field div.input input {
1911 1913 width: 236px;
1912 1914 background: #FFF;
1913 1915 border-top: 1px solid #b3b3b3;
1914 1916 border-left: 1px solid #b3b3b3;
1915 1917 border-right: 1px solid #eaeaea;
1916 1918 border-bottom: 1px solid #eaeaea;
1917 1919 color: #000;
1918 1920 font-size: 11px;
1919 1921 margin: 0;
1920 1922 padding: 5px 7px 4px;
1921 1923 }
1922 1924
1923 1925 #quick_login div.form div.fields div.buttons {
1924 1926 clear: both;
1925 1927 overflow: hidden;
1926 1928 text-align: right;
1927 1929 margin: 0;
1928 1930 padding: 10px 14px 0px 5px;
1929 1931 }
1930 1932
1931 1933 #quick_login div.form div.links {
1932 1934 clear: both;
1933 1935 overflow: hidden;
1934 1936 margin: 10px 0 0;
1935 1937 padding: 0 0 2px;
1936 1938 }
1937 1939
1938 1940 #register div.title {
1939 1941 clear: both;
1940 1942 overflow: hidden;
1941 1943 position: relative;
1942 1944 background-color: #eedc94;
1943 1945 background-repeat: repeat-x;
1944 1946 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1),
1945 1947 to(#eedc94) );
1946 1948 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1947 1949 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1948 1950 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),
1949 1951 color-stop(100%, #00376e) );
1950 1952 background-image: -webkit-linear-gradient(top, #003b76, #00376e) );
1951 1953 background-image: -o-linear-gradient(top, #003b76, #00376e) );
1952 1954 background-image: linear-gradient(top, #003b76, #00376e);
1953 1955 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
1954 1956 endColorstr='#00376e', GradientType=0 );
1955 1957 margin: 0 auto;
1956 1958 padding: 0;
1957 1959 }
1958 1960
1959 1961 #register div.inner {
1960 1962 background: #FFF;
1961 1963 border-top: none;
1962 1964 border-bottom: none;
1963 1965 margin: 0 auto;
1964 1966 padding: 20px;
1965 1967 }
1966 1968
1967 1969 #register div.form div.fields div.field div.label {
1968 1970 width: 135px;
1969 1971 float: left;
1970 1972 text-align: right;
1971 1973 margin: 2px 10px 0 0;
1972 1974 padding: 5px 0 0 5px;
1973 1975 }
1974 1976
1975 1977 #register div.form div.fields div.field div.input input {
1976 1978 width: 300px;
1977 1979 background: #FFF;
1978 1980 border-top: 1px solid #b3b3b3;
1979 1981 border-left: 1px solid #b3b3b3;
1980 1982 border-right: 1px solid #eaeaea;
1981 1983 border-bottom: 1px solid #eaeaea;
1982 1984 color: #000;
1983 1985 font-size: 11px;
1984 1986 margin: 0;
1985 1987 padding: 7px 7px 6px;
1986 1988 }
1987 1989
1988 1990 #register div.form div.fields div.buttons {
1989 1991 clear: both;
1990 1992 overflow: hidden;
1991 1993 border-top: 1px solid #DDD;
1992 1994 text-align: left;
1993 1995 margin: 0;
1994 1996 padding: 10px 0 0 150px;
1995 1997 }
1996 1998
1997 1999 #register div.form div.activation_msg {
1998 2000 padding-top: 4px;
1999 2001 padding-bottom: 4px;
2000 2002 }
2001 2003
2002 2004 #journal .journal_day {
2003 2005 font-size: 20px;
2004 2006 padding: 10px 0px;
2005 2007 border-bottom: 2px solid #DDD;
2006 2008 margin-left: 10px;
2007 2009 margin-right: 10px;
2008 2010 }
2009 2011
2010 2012 #journal .journal_container {
2011 2013 padding: 5px;
2012 2014 clear: both;
2013 2015 margin: 0px 5px 0px 10px;
2014 2016 }
2015 2017
2016 2018 #journal .journal_action_container {
2017 2019 padding-left: 38px;
2018 2020 }
2019 2021
2020 2022 #journal .journal_user {
2021 2023 color: #747474;
2022 2024 font-size: 14px;
2023 2025 font-weight: bold;
2024 2026 height: 30px;
2025 2027 }
2026 2028
2027 2029 #journal .journal_icon {
2028 2030 clear: both;
2029 2031 float: left;
2030 2032 padding-right: 4px;
2031 2033 padding-top: 3px;
2032 2034 }
2033 2035
2034 2036 #journal .journal_action {
2035 2037 padding-top: 4px;
2036 2038 min-height: 2px;
2037 2039 float: left
2038 2040 }
2039 2041
2040 2042 #journal .journal_action_params {
2041 2043 clear: left;
2042 2044 padding-left: 22px;
2043 2045 }
2044 2046
2045 2047 #journal .journal_repo {
2046 2048 float: left;
2047 2049 margin-left: 6px;
2048 2050 padding-top: 3px;
2049 2051 }
2050 2052
2051 2053 #journal .date {
2052 2054 clear: both;
2053 2055 color: #777777;
2054 2056 font-size: 11px;
2055 2057 padding-left: 22px;
2056 2058 }
2057 2059
2058 2060 #journal .journal_repo .journal_repo_name {
2059 2061 font-weight: bold;
2060 2062 font-size: 1.1em;
2061 2063 }
2062 2064
2063 2065 #journal .compare_view {
2064 2066 padding: 5px 0px 5px 0px;
2065 2067 width: 95px;
2066 2068 }
2067 2069
2068 2070 .journal_highlight {
2069 2071 font-weight: bold;
2070 2072 padding: 0 2px;
2071 2073 vertical-align: bottom;
2072 2074 }
2073 2075
2074 2076 .trending_language_tbl,.trending_language_tbl td {
2075 2077 border: 0 !important;
2076 2078 margin: 0 !important;
2077 2079 padding: 0 !important;
2078 2080 }
2079 2081
2080 2082 .trending_language_tbl,.trending_language_tbl tr {
2081 2083 border-spacing: 1px;
2082 2084 }
2083 2085
2084 2086 .trending_language {
2085 2087 background-color: #003367;
2086 2088 color: #FFF;
2087 2089 display: block;
2088 2090 min-width: 20px;
2089 2091 text-decoration: none;
2090 2092 height: 12px;
2091 2093 margin-bottom: 0px;
2092 2094 margin-left: 5px;
2093 2095 white-space: pre;
2094 2096 padding: 3px;
2095 2097 }
2096 2098
2097 2099 h3.files_location {
2098 2100 font-size: 1.8em;
2099 2101 font-weight: 700;
2100 2102 border-bottom: none !important;
2101 2103 margin: 10px 0 !important;
2102 2104 }
2103 2105
2104 2106 #files_data dl dt {
2105 2107 float: left;
2106 2108 width: 60px;
2107 2109 margin: 0 !important;
2108 2110 padding: 5px;
2109 2111 }
2110 2112
2111 2113 #files_data dl dd {
2112 2114 margin: 0 !important;
2113 2115 padding: 5px !important;
2114 2116 }
2115 2117
2116 2118 #changeset_content {
2117 2119 border: 1px solid #CCC;
2118 2120 padding: 5px;
2119 2121 }
2120 2122
2121 2123 #changeset_compare_view_content {
2122 2124 border: 1px solid #CCC;
2123 2125 padding: 5px;
2124 2126 }
2125 2127
2126 2128 #changeset_content .container {
2127 2129 min-height: 120px;
2128 2130 font-size: 1.2em;
2129 2131 overflow: hidden;
2130 2132 }
2131 2133
2132 2134 #changeset_compare_view_content .compare_view_commits {
2133 2135 width: auto !important;
2134 2136 }
2135 2137
2136 2138 #changeset_compare_view_content .compare_view_commits td {
2137 2139 padding: 0px 0px 0px 12px !important;
2138 2140 }
2139 2141
2140 2142 #changeset_content .container .right {
2141 2143 float: right;
2142 2144 width: 25%;
2143 2145 text-align: right;
2144 2146 }
2145 2147
2146 2148 #changeset_content .container .left .message {
2147 2149 font-style: italic;
2148 2150 color: #556CB5;
2149 2151 white-space: pre-wrap;
2150 2152 }
2151 2153 #changeset_content .container .left .message a:hover {
2152 2154 text-decoration: none;
2153 2155 }
2154 2156 .cs_files .cur_cs {
2155 2157 margin: 10px 2px;
2156 2158 font-weight: bold;
2157 2159 }
2158 2160
2159 2161 .cs_files .node {
2160 2162 float: left;
2161 2163 }
2162 2164
2163 2165 .cs_files .changes {
2164 2166 float: right;
2165 2167 color:#003367;
2166 2168
2167 2169 }
2168 2170
2169 2171 .cs_files .changes .added {
2170 2172 background-color: #BBFFBB;
2171 2173 float: left;
2172 2174 text-align: center;
2173 2175 font-size: 9px;
2174 2176 padding: 2px 0px 2px 0px;
2175 2177 }
2176 2178
2177 2179 .cs_files .changes .deleted {
2178 2180 background-color: #FF8888;
2179 2181 float: left;
2180 2182 text-align: center;
2181 2183 font-size: 9px;
2182 2184 padding: 2px 0px 2px 0px;
2183 2185 }
2184 2186
2185 2187 .cs_files .cs_added {
2186 2188 background: url("../images/icons/page_white_add.png") no-repeat scroll
2187 2189 3px;
2188 2190 height: 16px;
2189 2191 padding-left: 20px;
2190 2192 margin-top: 7px;
2191 2193 text-align: left;
2192 2194 }
2193 2195
2194 2196 .cs_files .cs_changed {
2195 2197 background: url("../images/icons/page_white_edit.png") no-repeat scroll
2196 2198 3px;
2197 2199 height: 16px;
2198 2200 padding-left: 20px;
2199 2201 margin-top: 7px;
2200 2202 text-align: left;
2201 2203 }
2202 2204
2203 2205 .cs_files .cs_removed {
2204 2206 background: url("../images/icons/page_white_delete.png") no-repeat
2205 2207 scroll 3px;
2206 2208 height: 16px;
2207 2209 padding-left: 20px;
2208 2210 margin-top: 7px;
2209 2211 text-align: left;
2210 2212 }
2211 2213
2212 2214 #graph {
2213 2215 overflow: hidden;
2214 2216 }
2215 2217
2216 2218 #graph_nodes {
2217 2219 float: left;
2218 2220 margin-right: -6px;
2219 2221 margin-top: 0px;
2220 2222 }
2221 2223
2222 2224 #graph_content {
2223 2225 width: 800px;
2224 2226 float: left;
2225 2227 }
2226 2228
2227 2229 #graph_content .container_header {
2228 2230 border: 1px solid #CCC;
2229 2231 padding: 10px;
2230 2232 height: 45px;
2231 2233 -webkit-border-radius: 6px 6px 0px 0px;
2232 2234 -moz-border-radius: 6px 6px 0px 0px;
2233 2235 border-radius: 6px 6px 0px 0px;
2234 2236 }
2235 2237
2236 2238 #graph_content #rev_range_container {
2237 2239 padding: 10px 0px;
2238 2240 clear: both;
2239 2241 }
2240 2242
2241 2243 #graph_content .container {
2242 2244 border-bottom: 1px solid #CCC;
2243 2245 border-left: 1px solid #CCC;
2244 2246 border-right: 1px solid #CCC;
2245 2247 min-height: 70px;
2246 2248 overflow: hidden;
2247 2249 font-size: 1.2em;
2248 2250 }
2249 2251
2250 2252 #graph_content .container .right {
2251 2253 float: right;
2252 2254 width: 28%;
2253 2255 text-align: right;
2254 2256 padding-bottom: 5px;
2255 2257 }
2256 2258
2257 2259 #graph_content .container .left .date {
2258 2260 font-weight: 700;
2259 2261 padding-bottom: 5px;
2260 2262 }
2261 2263
2262 2264 #graph_content .container .left .date span {
2263 2265 vertical-align: text-top;
2264 2266 }
2265 2267
2266 2268 #graph_content .container .left .author {
2267 2269 height: 22px;
2268 2270 }
2269 2271
2270 2272 #graph_content .container .left .author .user {
2271 2273 color: #444444;
2272 2274 float: left;
2273 2275 font-size: 12px;
2274 2276 margin-left: -4px;
2275 2277 margin-top: 4px;
2276 2278 }
2277 2279
2278 2280 #graph_content .container .left .message {
2279 2281 font-size: 100%;
2280 2282 padding-top: 3px;
2281 2283 white-space: pre-wrap;
2282 2284 }
2283 2285
2284 2286 #graph_content .container .left .message a:hover{
2285 2287 text-decoration: none;
2286 2288 }
2287 2289
2288 2290 .right div {
2289 2291 clear: both;
2290 2292 }
2291 2293
2292 2294 .right .changes .changed_total {
2293 2295 border: 0px solid #DDD;
2294 2296 display: block;
2295 2297 float: right;
2296 2298 text-align: center;
2297 2299 min-width: 45px;
2298 2300 cursor: pointer;
2299 2301 background: #FD8;
2300 2302 font-weight: bold;
2301 2303 -webkit-border-radius: 0px 0px 0px 6px;
2302 2304 -moz-border-radius: 0px 0px 0px 6px;
2303 2305 border-radius: 0px 0px 0px 6px;
2304 2306 padding: 2px;
2305 2307 }
2306 2308
2307 2309 .right .changes .added,.changed,.removed {
2308 2310 border: 1px solid #DDD;
2309 2311 display: block;
2310 2312 float: right;
2311 2313 text-align: center;
2312 2314 min-width: 15px;
2313 2315 cursor: help;
2314 2316 }
2315 2317
2316 2318 .right .changes .large {
2317 2319 border: 1px solid #DDD;
2318 2320 display: block;
2319 2321 float: right;
2320 2322 text-align: center;
2321 2323 min-width: 45px;
2322 2324 cursor: help;
2323 2325 background: #54A9F7;
2324 2326 }
2325 2327
2326 2328 .right .changes .added {
2327 2329 background: #BFB;
2328 2330 }
2329 2331
2330 2332 .right .changes .changed {
2331 2333 background: #FD8;
2332 2334 }
2333 2335
2334 2336 .right .changes .removed {
2335 2337 background: #F88;
2336 2338 }
2337 2339
2338 2340 .right .merge {
2339 2341 vertical-align: top;
2340 2342 font-size: 0.75em;
2341 2343 font-weight: 700;
2342 2344 }
2343 2345
2344 2346 .right .parent {
2345 2347 font-size: 90%;
2346 2348 font-family: monospace;
2347 2349 padding: 2px 2px 2px 2px;
2348 2350 }
2349 2351 .right .logtags{
2350 2352 padding: 2px 2px 2px 2px;
2351 2353 }
2352 2354 .right .logtags .branchtag,.logtags .branchtag {
2353 2355 padding: 1px 3px 2px;
2354 2356 background-color: #bfbfbf;
2355 2357 font-size: 9.75px;
2356 2358 font-weight: bold;
2357 2359 color: #ffffff;
2358 2360 text-transform: uppercase;
2359 2361 white-space: nowrap;
2360 2362 -webkit-border-radius: 3px;
2361 2363 -moz-border-radius: 3px;
2362 2364 border-radius: 3px;
2363 2365 padding-left:4px;
2364 2366 }
2365 2367 .right .logtags .branchtag a:hover,.logtags .branchtag a{
2366 2368 color: #ffffff;
2367 2369 }
2368 2370 .right .logtags .branchtag a:hover,.logtags .branchtag a:hover{
2369 2371 text-decoration: none;
2370 2372 color: #ffffff;
2371 2373 }
2372 2374 .right .logtags .tagtag,.logtags .tagtag {
2373 2375 padding: 1px 3px 2px;
2374 2376 background-color: #62cffc;
2375 2377 font-size: 9.75px;
2376 2378 font-weight: bold;
2377 2379 color: #ffffff;
2378 2380 text-transform: uppercase;
2379 2381 white-space: nowrap;
2380 2382 -webkit-border-radius: 3px;
2381 2383 -moz-border-radius: 3px;
2382 2384 border-radius: 3px;
2383 2385 }
2384 2386 .right .logtags .tagtag a:hover,.logtags .tagtag a{
2385 2387 color: #ffffff;
2386 2388 }
2387 2389 .right .logtags .tagtag a:hover,.logtags .tagtag a:hover{
2388 2390 text-decoration: none;
2389 2391 color: #ffffff;
2390 2392 }
2391 2393 .right .logbooks .bookbook,.logbooks .bookbook {
2392 2394 padding: 1px 3px 2px;
2393 2395 background-color: #46A546;
2394 2396 font-size: 9.75px;
2395 2397 font-weight: bold;
2396 2398 color: #ffffff;
2397 2399 text-transform: uppercase;
2398 2400 white-space: nowrap;
2399 2401 -webkit-border-radius: 3px;
2400 2402 -moz-border-radius: 3px;
2401 2403 border-radius: 3px;
2402 2404 }
2403 2405 .right .logbooks .bookbook,.logbooks .bookbook a{
2404 2406 color: #ffffff;
2405 2407 }
2406 2408 .right .logbooks .bookbook,.logbooks .bookbook a:hover{
2407 2409 text-decoration: none;
2408 2410 color: #ffffff;
2409 2411 }
2410 2412 div.browserblock {
2411 2413 overflow: hidden;
2412 2414 border: 1px solid #ccc;
2413 2415 background: #f8f8f8;
2414 2416 font-size: 100%;
2415 2417 line-height: 125%;
2416 2418 padding: 0;
2417 2419 -webkit-border-radius: 6px 6px 0px 0px;
2418 2420 -moz-border-radius: 6px 6px 0px 0px;
2419 2421 border-radius: 6px 6px 0px 0px;
2420 2422 }
2421 2423
2422 2424 div.browserblock .browser-header {
2423 2425 background: #FFF;
2424 2426 padding: 10px 0px 15px 0px;
2425 2427 width: 100%;
2426 2428 }
2427 2429
2428 2430 div.browserblock .browser-nav {
2429 2431 float: left
2430 2432 }
2431 2433
2432 2434 div.browserblock .browser-branch {
2433 2435 float: left;
2434 2436 }
2435 2437
2436 2438 div.browserblock .browser-branch label {
2437 2439 color: #4A4A4A;
2438 2440 vertical-align: text-top;
2439 2441 }
2440 2442
2441 2443 div.browserblock .browser-header span {
2442 2444 margin-left: 5px;
2443 2445 font-weight: 700;
2444 2446 }
2445 2447
2446 2448 div.browserblock .browser-search {
2447 2449 clear: both;
2448 2450 padding: 8px 8px 0px 5px;
2449 2451 height: 20px;
2450 2452 }
2451 2453
2452 2454 div.browserblock #node_filter_box {
2453 2455
2454 2456 }
2455 2457
2456 2458 div.browserblock .search_activate {
2457 2459 float: left
2458 2460 }
2459 2461
2460 2462 div.browserblock .add_node {
2461 2463 float: left;
2462 2464 padding-left: 5px;
2463 2465 }
2464 2466
2465 2467 div.browserblock .search_activate a:hover,div.browserblock .add_node a:hover
2466 2468 {
2467 2469 text-decoration: none !important;
2468 2470 }
2469 2471
2470 2472 div.browserblock .browser-body {
2471 2473 background: #EEE;
2472 2474 border-top: 1px solid #CCC;
2473 2475 }
2474 2476
2475 2477 table.code-browser {
2476 2478 border-collapse: collapse;
2477 2479 width: 100%;
2478 2480 }
2479 2481
2480 2482 table.code-browser tr {
2481 2483 margin: 3px;
2482 2484 }
2483 2485
2484 2486 table.code-browser thead th {
2485 2487 background-color: #EEE;
2486 2488 height: 20px;
2487 2489 font-size: 1.1em;
2488 2490 font-weight: 700;
2489 2491 text-align: left;
2490 2492 padding-left: 10px;
2491 2493 }
2492 2494
2493 2495 table.code-browser tbody td {
2494 2496 padding-left: 10px;
2495 2497 height: 20px;
2496 2498 }
2497 2499
2498 2500 table.code-browser .browser-file {
2499 2501 background: url("../images/icons/document_16.png") no-repeat scroll 3px;
2500 2502 height: 16px;
2501 2503 padding-left: 20px;
2502 2504 text-align: left;
2503 2505 }
2504 2506 .diffblock .changeset_header {
2505 2507 height: 16px;
2506 2508 }
2507 2509 .diffblock .changeset_file {
2508 2510 background: url("../images/icons/file.png") no-repeat scroll 3px;
2509 2511 text-align: left;
2510 2512 float: left;
2511 2513 padding: 2px 0px 2px 22px;
2512 2514 }
2513 2515 .diffblock .diff-menu-wrapper{
2514 2516 float: left;
2515 2517 }
2516 2518
2517 2519 .diffblock .diff-menu{
2518 2520 position: absolute;
2519 2521 background: none repeat scroll 0 0 #FFFFFF;
2520 2522 border-color: #003367 #666666 #666666;
2521 2523 border-right: 1px solid #666666;
2522 2524 border-style: solid solid solid;
2523 2525 border-width: 1px;
2524 2526 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
2525 2527 margin-top:5px;
2526 2528 margin-left:1px;
2527 2529
2528 2530 }
2529 2531
2530 2532 .diffblock .diff-menu ul li {
2531 2533 padding: 0px 0px 0px 0px !important;
2532 2534 }
2533 2535 .diffblock .diff-menu ul li a{
2534 2536 display: block;
2535 2537 padding: 3px 8px 3px 8px !important;
2536 2538 }
2537 2539 .diffblock .diff-menu ul li a:hover{
2538 2540 text-decoration: none;
2539 2541 background-color: #EEEEEE;
2540 2542 }
2541 2543 table.code-browser .browser-dir {
2542 2544 background: url("../images/icons/folder_16.png") no-repeat scroll 3px;
2543 2545 height: 16px;
2544 2546 padding-left: 20px;
2545 2547 text-align: left;
2546 2548 }
2547 2549
2548 2550 .box .search {
2549 2551 clear: both;
2550 2552 overflow: hidden;
2551 2553 margin: 0;
2552 2554 padding: 0 20px 10px;
2553 2555 }
2554 2556
2555 2557 .box .search div.search_path {
2556 2558 background: none repeat scroll 0 0 #EEE;
2557 2559 border: 1px solid #CCC;
2558 2560 color: blue;
2559 2561 margin-bottom: 10px;
2560 2562 padding: 10px 0;
2561 2563 }
2562 2564
2563 2565 .box .search div.search_path div.link {
2564 2566 font-weight: 700;
2565 2567 margin-left: 25px;
2566 2568 }
2567 2569
2568 2570 .box .search div.search_path div.link a {
2569 2571 color: #003367;
2570 2572 cursor: pointer;
2571 2573 text-decoration: none;
2572 2574 }
2573 2575
2574 2576 #path_unlock {
2575 2577 color: red;
2576 2578 font-size: 1.2em;
2577 2579 padding-left: 4px;
2578 2580 }
2579 2581
2580 2582 .info_box span {
2581 2583 margin-left: 3px;
2582 2584 margin-right: 3px;
2583 2585 }
2584 2586
2585 2587 .info_box .rev {
2586 2588 color: #003367;
2587 2589 font-size: 1.6em;
2588 2590 font-weight: bold;
2589 2591 vertical-align: sub;
2590 2592 }
2591 2593
2592 2594 .info_box input#at_rev,.info_box input#size {
2593 2595 background: #FFF;
2594 2596 border-top: 1px solid #b3b3b3;
2595 2597 border-left: 1px solid #b3b3b3;
2596 2598 border-right: 1px solid #eaeaea;
2597 2599 border-bottom: 1px solid #eaeaea;
2598 2600 color: #000;
2599 2601 font-size: 12px;
2600 2602 margin: 0;
2601 2603 padding: 1px 5px 1px;
2602 2604 }
2603 2605
2604 2606 .info_box input#view {
2605 2607 text-align: center;
2606 2608 padding: 4px 3px 2px 2px;
2607 2609 }
2608 2610
2609 2611 .yui-overlay,.yui-panel-container {
2610 2612 visibility: hidden;
2611 2613 position: absolute;
2612 2614 z-index: 2;
2613 2615 }
2614 2616
2615 2617 .yui-tt {
2616 2618 visibility: hidden;
2617 2619 position: absolute;
2618 2620 color: #666;
2619 2621 background-color: #FFF;
2620 2622 border: 2px solid #003367;
2621 2623 font: 100% sans-serif;
2622 2624 width: auto;
2623 2625 opacity: 1px;
2624 2626 padding: 8px;
2625 2627 white-space: pre-wrap;
2626 2628 -webkit-border-radius: 8px 8px 8px 8px;
2627 2629 -khtml-border-radius: 8px 8px 8px 8px;
2628 2630 -moz-border-radius: 8px 8px 8px 8px;
2629 2631 border-radius: 8px 8px 8px 8px;
2630 2632 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
2631 2633 }
2632 2634
2633 2635 .ac {
2634 2636 vertical-align: top;
2635 2637 }
2636 2638
2637 2639 .ac .yui-ac {
2638 2640 position: relative;
2639 2641 font-size: 100%;
2640 2642 }
2641 2643
2642 2644 .ac .perm_ac {
2643 2645 width: 15em;
2644 2646 }
2645 2647
2646 2648 .ac .yui-ac-input {
2647 2649 width: 100%;
2648 2650 }
2649 2651
2650 2652 .ac .yui-ac-container {
2651 2653 position: absolute;
2652 2654 top: 1.6em;
2653 2655 width: 100%;
2654 2656 }
2655 2657
2656 2658 .ac .yui-ac-content {
2657 2659 position: absolute;
2658 2660 width: 100%;
2659 2661 border: 1px solid gray;
2660 2662 background: #fff;
2661 2663 overflow: hidden;
2662 2664 z-index: 9050;
2663 2665 }
2664 2666
2665 2667 .ac .yui-ac-shadow {
2666 2668 position: absolute;
2667 2669 width: 100%;
2668 2670 background: #000;
2669 2671 -moz-opacity: 0.1px;
2670 2672 opacity: .10;
2671 2673 filter: alpha(opacity = 10);
2672 2674 z-index: 9049;
2673 2675 margin: .3em;
2674 2676 }
2675 2677
2676 2678 .ac .yui-ac-content ul {
2677 2679 width: 100%;
2678 2680 margin: 0;
2679 2681 padding: 0;
2680 2682 }
2681 2683
2682 2684 .ac .yui-ac-content li {
2683 2685 cursor: default;
2684 2686 white-space: nowrap;
2685 2687 margin: 0;
2686 2688 padding: 2px 5px;
2687 2689 }
2688 2690
2689 2691 .ac .yui-ac-content li.yui-ac-prehighlight {
2690 2692 background: #B3D4FF;
2691 2693 }
2692 2694
2693 2695 .ac .yui-ac-content li.yui-ac-highlight {
2694 2696 background: #556CB5;
2695 2697 color: #FFF;
2696 2698 }
2697 2699
2698 2700 .follow {
2699 2701 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
2700 2702 height: 16px;
2701 2703 width: 20px;
2702 2704 cursor: pointer;
2703 2705 display: block;
2704 2706 float: right;
2705 2707 margin-top: 2px;
2706 2708 }
2707 2709
2708 2710 .following {
2709 2711 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
2710 2712 height: 16px;
2711 2713 width: 20px;
2712 2714 cursor: pointer;
2713 2715 display: block;
2714 2716 float: right;
2715 2717 margin-top: 2px;
2716 2718 }
2717 2719
2718 2720 .currently_following {
2719 2721 padding-left: 10px;
2720 2722 padding-bottom: 5px;
2721 2723 }
2722 2724
2723 2725 .add_icon {
2724 2726 background: url("../images/icons/add.png") no-repeat scroll 3px;
2725 2727 padding-left: 20px;
2726 2728 padding-top: 0px;
2727 2729 text-align: left;
2728 2730 }
2729 2731
2730 2732 .edit_icon {
2731 2733 background: url("../images/icons/folder_edit.png") no-repeat scroll 3px;
2732 2734 padding-left: 20px;
2733 2735 padding-top: 0px;
2734 2736 text-align: left;
2735 2737 }
2736 2738
2737 2739 .delete_icon {
2738 2740 background: url("../images/icons/delete.png") no-repeat scroll 3px;
2739 2741 padding-left: 20px;
2740 2742 padding-top: 0px;
2741 2743 text-align: left;
2742 2744 }
2743 2745
2744 2746 .refresh_icon {
2745 2747 background: url("../images/icons/arrow_refresh.png") no-repeat scroll
2746 2748 3px;
2747 2749 padding-left: 20px;
2748 2750 padding-top: 0px;
2749 2751 text-align: left;
2750 2752 }
2751 2753
2752 2754 .pull_icon {
2753 2755 background: url("../images/icons/connect.png") no-repeat scroll 3px;
2754 2756 padding-left: 20px;
2755 2757 padding-top: 0px;
2756 2758 text-align: left;
2757 2759 }
2758 2760
2759 2761 .rss_icon {
2760 2762 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
2761 2763 padding-left: 20px;
2762 2764 padding-top: 4px;
2763 2765 text-align: left;
2764 2766 font-size: 8px
2765 2767 }
2766 2768
2767 2769 .atom_icon {
2768 2770 background: url("../images/icons/atom.png") no-repeat scroll 3px;
2769 2771 padding-left: 20px;
2770 2772 padding-top: 4px;
2771 2773 text-align: left;
2772 2774 font-size: 8px
2773 2775 }
2774 2776
2775 2777 .archive_icon {
2776 2778 background: url("../images/icons/compress.png") no-repeat scroll 3px;
2777 2779 padding-left: 20px;
2778 2780 text-align: left;
2779 2781 padding-top: 1px;
2780 2782 }
2781 2783
2782 2784 .start_following_icon {
2783 2785 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
2784 2786 padding-left: 20px;
2785 2787 text-align: left;
2786 2788 padding-top: 0px;
2787 2789 }
2788 2790
2789 2791 .stop_following_icon {
2790 2792 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
2791 2793 padding-left: 20px;
2792 2794 text-align: left;
2793 2795 padding-top: 0px;
2794 2796 }
2795 2797
2796 2798 .action_button {
2797 2799 border: 0;
2798 2800 display: inline;
2799 2801 }
2800 2802
2801 2803 .action_button:hover {
2802 2804 border: 0;
2803 2805 text-decoration: underline;
2804 2806 cursor: pointer;
2805 2807 }
2806 2808
2807 2809 #switch_repos {
2808 2810 position: absolute;
2809 2811 height: 25px;
2810 2812 z-index: 1;
2811 2813 }
2812 2814
2813 2815 #switch_repos select {
2814 2816 min-width: 150px;
2815 2817 max-height: 250px;
2816 2818 z-index: 1;
2817 2819 }
2818 2820
2819 2821 .breadcrumbs {
2820 2822 border: medium none;
2821 2823 color: #FFF;
2822 2824 float: left;
2823 2825 text-transform: uppercase;
2824 2826 font-weight: 700;
2825 2827 font-size: 14px;
2826 2828 margin: 0;
2827 2829 padding: 11px 0 11px 10px;
2828 2830 }
2829 2831
2830 2832 .breadcrumbs a {
2831 2833 color: #FFF;
2832 2834 }
2833 2835
2834 2836 .flash_msg {
2835 2837
2836 2838 }
2837 2839
2838 2840 .flash_msg ul {
2839 2841
2840 2842 }
2841 2843
2842 2844 .error_msg {
2843 2845 background-color: #c43c35;
2844 2846 background-repeat: repeat-x;
2845 2847 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b),
2846 2848 to(#c43c35) );
2847 2849 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
2848 2850 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
2849 2851 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b),
2850 2852 color-stop(100%, #c43c35) );
2851 2853 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
2852 2854 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
2853 2855 background-image: linear-gradient(top, #ee5f5b, #c43c35);
2854 2856 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',
2855 2857 endColorstr='#c43c35', GradientType=0 );
2856 2858 border-color: #c43c35 #c43c35 #882a25;
2857 2859 }
2858 2860
2859 2861 .warning_msg {
2860 2862 color: #404040 !important;
2861 2863 background-color: #eedc94;
2862 2864 background-repeat: repeat-x;
2863 2865 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1),
2864 2866 to(#eedc94) );
2865 2867 background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
2866 2868 background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
2867 2869 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1),
2868 2870 color-stop(100%, #eedc94) );
2869 2871 background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
2870 2872 background-image: -o-linear-gradient(top, #fceec1, #eedc94);
2871 2873 background-image: linear-gradient(top, #fceec1, #eedc94);
2872 2874 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1',
2873 2875 endColorstr='#eedc94', GradientType=0 );
2874 2876 border-color: #eedc94 #eedc94 #e4c652;
2875 2877 }
2876 2878
2877 2879 .success_msg {
2878 2880 background-color: #57a957;
2879 2881 background-repeat: repeat-x !important;
2880 2882 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462),
2881 2883 to(#57a957) );
2882 2884 background-image: -moz-linear-gradient(top, #62c462, #57a957);
2883 2885 background-image: -ms-linear-gradient(top, #62c462, #57a957);
2884 2886 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462),
2885 2887 color-stop(100%, #57a957) );
2886 2888 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
2887 2889 background-image: -o-linear-gradient(top, #62c462, #57a957);
2888 2890 background-image: linear-gradient(top, #62c462, #57a957);
2889 2891 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462',
2890 2892 endColorstr='#57a957', GradientType=0 );
2891 2893 border-color: #57a957 #57a957 #3d773d;
2892 2894 }
2893 2895
2894 2896 .notice_msg {
2895 2897 background-color: #339bb9;
2896 2898 background-repeat: repeat-x;
2897 2899 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de),
2898 2900 to(#339bb9) );
2899 2901 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
2900 2902 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
2901 2903 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de),
2902 2904 color-stop(100%, #339bb9) );
2903 2905 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
2904 2906 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
2905 2907 background-image: linear-gradient(top, #5bc0de, #339bb9);
2906 2908 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de',
2907 2909 endColorstr='#339bb9', GradientType=0 );
2908 2910 border-color: #339bb9 #339bb9 #22697d;
2909 2911 }
2910 2912
2911 2913 .success_msg,.error_msg,.notice_msg,.warning_msg {
2912 2914 font-size: 12px;
2913 2915 font-weight: 700;
2914 2916 min-height: 14px;
2915 2917 line-height: 14px;
2916 2918 margin-bottom: 10px;
2917 2919 margin-top: 0;
2918 2920 display: block;
2919 2921 overflow: auto;
2920 2922 padding: 6px 10px 6px 10px;
2921 2923 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
2922 2924 position: relative;
2923 2925 color: #FFF;
2924 2926 border-width: 1px;
2925 2927 border-style: solid;
2926 2928 -webkit-border-radius: 4px;
2927 2929 -moz-border-radius: 4px;
2928 2930 border-radius: 4px;
2929 2931 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
2930 2932 -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
2931 2933 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
2932 2934 }
2933 2935
2934 2936 #msg_close {
2935 2937 background: transparent url("../icons/cross_grey_small.png") no-repeat
2936 2938 scroll 0 0;
2937 2939 cursor: pointer;
2938 2940 height: 16px;
2939 2941 position: absolute;
2940 2942 right: 5px;
2941 2943 top: 5px;
2942 2944 width: 16px;
2943 2945 }
2944 2946
2945 2947 div#legend_container table,div#legend_choices table {
2946 2948 width: auto !important;
2947 2949 }
2948 2950
2949 2951 table#permissions_manage {
2950 2952 width: 0 !important;
2951 2953 }
2952 2954
2953 2955 table#permissions_manage span.private_repo_msg {
2954 2956 font-size: 0.8em;
2955 2957 opacity: 0.6px;
2956 2958 }
2957 2959
2958 2960 table#permissions_manage td.private_repo_msg {
2959 2961 font-size: 0.8em;
2960 2962 }
2961 2963
2962 2964 table#permissions_manage tr#add_perm_input td {
2963 2965 vertical-align: middle;
2964 2966 }
2965 2967
2966 2968 div.gravatar {
2967 2969 background-color: #FFF;
2968 2970 border: 0px solid #D0D0D0;
2969 2971 float: left;
2970 2972 margin-right: 0.7em;
2971 2973 padding: 2px 2px 2px 2px;
2972 2974 line-height:0;
2973 2975 -webkit-border-radius: 6px;
2974 2976 -khtml-border-radius: 6px;
2975 2977 -moz-border-radius: 6px;
2976 2978 border-radius: 6px;
2977 2979 }
2978 2980
2979 2981 div.gravatar img {
2980 2982 -webkit-border-radius: 4px;
2981 2983 -khtml-border-radius: 4px;
2982 2984 -moz-border-radius: 4px;
2983 2985 border-radius: 4px;
2984 2986 }
2985 2987
2986 2988 #header,#content,#footer {
2987 2989 min-width: 978px;
2988 2990 }
2989 2991
2990 2992 #content {
2991 2993 clear: both;
2992 2994 overflow: hidden;
2993 2995 padding: 14px 10px;
2994 2996 }
2995 2997
2996 2998 #content div.box div.title div.search {
2997 2999
2998 3000 border-left: 1px solid #316293;
2999 3001 }
3000 3002
3001 3003 #content div.box div.title div.search div.input input {
3002 3004 border: 1px solid #316293;
3003 3005 }
3004 3006
3005 3007 .ui-btn{
3006 3008 color: #515151;
3007 3009 background-color: #DADADA;
3008 3010 background-repeat: repeat-x;
3009 3011 background-image: -khtml-gradient(linear, left top, left bottom, from(#F4F4F4),to(#DADADA) );
3010 3012 background-image: -moz-linear-gradient(top, #F4F4F4, #DADADA);
3011 3013 background-image: -ms-linear-gradient(top, #F4F4F4, #DADADA);
3012 3014 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) );
3013 3015 background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) );
3014 3016 background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) );
3015 3017 background-image: linear-gradient(top, #F4F4F4, #DADADA);
3016 3018 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0);
3017 3019
3018 3020 border-top: 1px solid #DDD;
3019 3021 border-left: 1px solid #c6c6c6;
3020 3022 border-right: 1px solid #DDD;
3021 3023 border-bottom: 1px solid #c6c6c6;
3022 3024 color: #515151;
3023 3025 outline: none;
3024 3026 margin: 0px 3px 3px 0px;
3025 3027 -webkit-border-radius: 4px 4px 4px 4px !important;
3026 3028 -khtml-border-radius: 4px 4px 4px 4px !important;
3027 3029 -moz-border-radius: 4px 4px 4px 4px !important;
3028 3030 border-radius: 4px 4px 4px 4px !important;
3029 3031 cursor: pointer !important;
3030 3032 padding: 3px 3px 3px 3px;
3031 3033 background-position: 0 -15px;
3032 3034
3033 3035 }
3034 3036 .ui-btn.xsmall{
3035 3037 padding: 1px 2px 1px 1px;
3036 3038 }
3037
3039 .ui-btn.clone{
3040 padding: 5px 2px 6px 1px;
3041 margin: 0px -4px 3px 0px;
3042 -webkit-border-radius: 4px 0px 0px 4px !important;
3043 -khtml-border-radius: 4px 0px 0px 4px !important;
3044 -moz-border-radius: 4px 0px 0px 4px !important;
3045 border-radius: 4px 0px 0px 4px !important;
3046 width: 100px;
3047 text-align: center;
3048 float: left;
3049 position: absolute;
3050 }
3038 3051 .ui-btn:focus {
3039 3052 outline: none;
3040 3053 }
3041 3054 .ui-btn:hover{
3042 3055 background-position: 0 0px;
3043 3056 text-decoration: none;
3044 3057 color: #515151;
3045 3058 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 3px #FFFFFF !important;
3046 3059 }
3047 3060
3048 3061 .ui-btn.red{
3049 3062 color:#fff;
3050 3063 background-color: #c43c35;
3051 3064 background-repeat: repeat-x;
3052 3065 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
3053 3066 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3054 3067 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3055 3068 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));
3056 3069 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3057 3070 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3058 3071 background-image: linear-gradient(top, #ee5f5b, #c43c35);
3059 3072 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
3060 3073 border-color: #c43c35 #c43c35 #882a25;
3061 3074 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3062 3075 }
3063 3076
3064 3077
3065 3078 .ui-btn.blue{
3066 3079 background-color: #339bb9;
3067 3080 background-repeat: repeat-x;
3068 3081 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));
3069 3082 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3070 3083 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3071 3084 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));
3072 3085 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3073 3086 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3074 3087 background-image: linear-gradient(top, #5bc0de, #339bb9);
3075 3088 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
3076 3089 border-color: #339bb9 #339bb9 #22697d;
3077 3090 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3078 3091 }
3079 3092
3080 3093 .ui-btn.green{
3081 3094 background-color: #57a957;
3082 3095 background-repeat: repeat-x;
3083 3096 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));
3084 3097 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3085 3098 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3086 3099 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));
3087 3100 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3088 3101 background-image: -o-linear-gradient(top, #62c462, #57a957);
3089 3102 background-image: linear-gradient(top, #62c462, #57a957);
3090 3103 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
3091 3104 border-color: #57a957 #57a957 #3d773d;
3092 3105 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3093 3106 }
3094 3107
3095 3108 ins,div.options a:hover {
3096 3109 text-decoration: none;
3097 3110 }
3098 3111
3099 3112 img,
3100 3113 #header #header-inner #quick li a:hover span.normal,
3101 3114 #header #header-inner #quick li ul li.last,
3102 3115 #content div.box div.form div.fields div.field div.textarea table td table td a,
3103 #clone_url
3116 #clone_url,
3117 #clone_url_id
3104 3118 {
3105 3119 border: none;
3106 3120 }
3107 3121
3108 3122 img.icon,.right .merge img {
3109 3123 vertical-align: bottom;
3110 3124 }
3111 3125
3112 3126 #header ul#logged-user,#content div.box div.title ul.links,
3113 3127 #content div.box div.message div.dismiss,
3114 3128 #content div.box div.traffic div.legend ul
3115 3129 {
3116 3130 float: right;
3117 3131 margin: 0;
3118 3132 padding: 0;
3119 3133 }
3120 3134
3121 3135 #header #header-inner #home,#header #header-inner #logo,
3122 3136 #content div.box ul.left,#content div.box ol.left,
3123 3137 #content div.box div.pagination-left,div#commit_history,
3124 3138 div#legend_data,div#legend_container,div#legend_choices
3125 3139 {
3126 3140 float: left;
3127 3141 }
3128 3142
3129 3143 #header #header-inner #quick li:hover ul ul,
3130 3144 #header #header-inner #quick li:hover ul ul ul,
3131 3145 #header #header-inner #quick li:hover ul ul ul ul,
3132 3146 #content #left #menu ul.closed,#content #left #menu li ul.collapsed,.yui-tt-shadow
3133 3147 {
3134 3148 display: none;
3135 3149 }
3136 3150
3137 3151 #header #header-inner #quick li:hover ul,#header #header-inner #quick li li:hover ul,#header #header-inner #quick li li li:hover ul,#header #header-inner #quick li li li li:hover ul,#content #left #menu ul.opened,#content #left #menu li ul.expanded
3138 3152 {
3139 3153 display: block;
3140 3154 }
3141 3155
3142 3156 #content div.graph {
3143 3157 padding: 0 10px 10px;
3144 3158 }
3145 3159
3146 3160 #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a
3147 3161 {
3148 3162 color: #bfe3ff;
3149 3163 }
3150 3164
3151 3165 #content div.box ol.lower-roman,#content div.box ol.upper-roman,#content div.box ol.lower-alpha,#content div.box ol.upper-alpha,#content div.box ol.decimal
3152 3166 {
3153 3167 margin: 10px 24px 10px 44px;
3154 3168 }
3155 3169
3156 3170 #content div.box div.form,#content div.box div.table,#content div.box div.traffic
3157 3171 {
3158 3172 clear: both;
3159 3173 overflow: hidden;
3160 3174 margin: 0;
3161 3175 padding: 0 20px 10px;
3162 3176 }
3163 3177
3164 3178 #content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields
3165 3179 {
3166 3180 clear: both;
3167 3181 overflow: hidden;
3168 3182 margin: 0;
3169 3183 padding: 0;
3170 3184 }
3171 3185
3172 3186 #content div.box div.form div.fields div.field div.label span,#login div.form div.fields div.field div.label span,#register div.form div.fields div.field div.label span
3173 3187 {
3174 3188 height: 1%;
3175 3189 display: block;
3176 3190 color: #363636;
3177 3191 margin: 0;
3178 3192 padding: 2px 0 0;
3179 3193 }
3180 3194
3181 3195 #content div.box div.form div.fields div.field div.input input.error,#login div.form div.fields div.field div.input input.error,#register div.form div.fields div.field div.input input.error
3182 3196 {
3183 3197 background: #FBE3E4;
3184 3198 border-top: 1px solid #e1b2b3;
3185 3199 border-left: 1px solid #e1b2b3;
3186 3200 border-right: 1px solid #FBC2C4;
3187 3201 border-bottom: 1px solid #FBC2C4;
3188 3202 }
3189 3203
3190 3204 #content div.box div.form div.fields div.field div.input input.success,#login div.form div.fields div.field div.input input.success,#register div.form div.fields div.field div.input input.success
3191 3205 {
3192 3206 background: #E6EFC2;
3193 3207 border-top: 1px solid #cebb98;
3194 3208 border-left: 1px solid #cebb98;
3195 3209 border-right: 1px solid #c6d880;
3196 3210 border-bottom: 1px solid #c6d880;
3197 3211 }
3198 3212
3199 3213 #content div.box-left div.form div.fields div.field div.textarea,#content div.box-right div.form div.fields div.field div.textarea,#content div.box div.form div.fields div.field div.select select,#content div.box table th.selected input,#content div.box table td.selected input
3200 3214 {
3201 3215 margin: 0;
3202 3216 }
3203 3217
3204 3218 #content div.box-left div.form div.fields div.field div.select,#content div.box-left div.form div.fields div.field div.checkboxes,#content div.box-left div.form div.fields div.field div.radios,#content div.box-right div.form div.fields div.field div.select,#content div.box-right div.form div.fields div.field div.checkboxes,#content div.box-right div.form div.fields div.field div.radios
3205 3219 {
3206 3220 margin: 0 0 0 0px !important;
3207 3221 padding: 0;
3208 3222 }
3209 3223
3210 3224 #content div.box div.form div.fields div.field div.select,#content div.box div.form div.fields div.field div.checkboxes,#content div.box div.form div.fields div.field div.radios
3211 3225 {
3212 3226 margin: 0 0 0 200px;
3213 3227 padding: 0;
3214 3228 }
3215 3229
3216 3230 #content div.box div.form div.fields div.field div.select a:hover,#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover,#content div.box div.action a:hover
3217 3231 {
3218 3232 color: #000;
3219 3233 text-decoration: none;
3220 3234 }
3221 3235
3222 3236 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus
3223 3237 {
3224 3238 border: 1px solid #666;
3225 3239 }
3226 3240
3227 3241 #content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio
3228 3242 {
3229 3243 clear: both;
3230 3244 overflow: hidden;
3231 3245 margin: 0;
3232 3246 padding: 8px 0 2px;
3233 3247 }
3234 3248
3235 3249 #content div.box div.form div.fields div.field div.checkboxes div.checkbox input,#content div.box div.form div.fields div.field div.radios div.radio input
3236 3250 {
3237 3251 float: left;
3238 3252 margin: 0;
3239 3253 }
3240 3254
3241 3255 #content div.box div.form div.fields div.field div.checkboxes div.checkbox label,#content div.box div.form div.fields div.field div.radios div.radio label
3242 3256 {
3243 3257 height: 1%;
3244 3258 display: block;
3245 3259 float: left;
3246 3260 margin: 2px 0 0 4px;
3247 3261 }
3248 3262
3249 3263 div.form div.fields div.field div.button input,#content div.box div.form div.fields div.buttons input,div.form div.fields div.buttons input,#content div.box div.action div.button input
3250 3264 {
3251 3265 color: #000;
3252 3266 font-size: 11px;
3253 3267 font-weight: 700;
3254 3268 margin: 0;
3255 3269 }
3256 3270
3257 3271 input.ui-button {
3258 3272 background: #e5e3e3 url("../images/button.png") repeat-x;
3259 3273 border-top: 1px solid #DDD;
3260 3274 border-left: 1px solid #c6c6c6;
3261 3275 border-right: 1px solid #DDD;
3262 3276 border-bottom: 1px solid #c6c6c6;
3263 3277 color: #515151 !important;
3264 3278 outline: none;
3265 3279 margin: 0;
3266 3280 padding: 6px 12px;
3267 3281 -webkit-border-radius: 4px 4px 4px 4px;
3268 3282 -khtml-border-radius: 4px 4px 4px 4px;
3269 3283 -moz-border-radius: 4px 4px 4px 4px;
3270 3284 border-radius: 4px 4px 4px 4px;
3271 3285 box-shadow: 0 1px 0 #ececec;
3272 3286 cursor: pointer;
3273 3287 }
3274 3288
3275 3289 input.ui-button:hover {
3276 3290 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3277 3291 border-top: 1px solid #ccc;
3278 3292 border-left: 1px solid #bebebe;
3279 3293 border-right: 1px solid #b1b1b1;
3280 3294 border-bottom: 1px solid #afafaf;
3281 3295 }
3282 3296
3283 3297 div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight
3284 3298 {
3285 3299 display: inline;
3286 3300 }
3287 3301
3288 3302 #content div.box div.form div.fields div.buttons,div.form div.fields div.buttons
3289 3303 {
3290 3304 margin: 10px 0 0 200px;
3291 3305 padding: 0;
3292 3306 }
3293 3307
3294 3308 #content div.box-left div.form div.fields div.buttons,#content div.box-right div.form div.fields div.buttons,div.box-left div.form div.fields div.buttons,div.box-right div.form div.fields div.buttons
3295 3309 {
3296 3310 margin: 10px 0 0;
3297 3311 }
3298 3312
3299 3313 #content div.box table td.user,#content div.box table td.address {
3300 3314 width: 10%;
3301 3315 text-align: center;
3302 3316 }
3303 3317
3304 3318 #content div.box div.action div.button,#login div.form div.fields div.field div.input div.link,#register div.form div.fields div.field div.input div.link
3305 3319 {
3306 3320 text-align: right;
3307 3321 margin: 6px 0 0;
3308 3322 padding: 0;
3309 3323 }
3310 3324
3311 3325 #content div.box div.action div.button input.ui-state-hover,#login div.form div.fields div.buttons input.ui-state-hover,#register div.form div.fields div.buttons input.ui-state-hover
3312 3326 {
3313 3327 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3314 3328 border-top: 1px solid #ccc;
3315 3329 border-left: 1px solid #bebebe;
3316 3330 border-right: 1px solid #b1b1b1;
3317 3331 border-bottom: 1px solid #afafaf;
3318 3332 color: #515151;
3319 3333 margin: 0;
3320 3334 padding: 6px 12px;
3321 3335 }
3322 3336
3323 3337 #content div.box div.pagination div.results,#content div.box div.pagination-wh div.results
3324 3338 {
3325 3339 text-align: left;
3326 3340 float: left;
3327 3341 margin: 0;
3328 3342 padding: 0;
3329 3343 }
3330 3344
3331 3345 #content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span
3332 3346 {
3333 3347 height: 1%;
3334 3348 display: block;
3335 3349 float: left;
3336 3350 background: #ebebeb url("../images/pager.png") repeat-x;
3337 3351 border-top: 1px solid #dedede;
3338 3352 border-left: 1px solid #cfcfcf;
3339 3353 border-right: 1px solid #c4c4c4;
3340 3354 border-bottom: 1px solid #c4c4c4;
3341 3355 color: #4A4A4A;
3342 3356 font-weight: 700;
3343 3357 margin: 0;
3344 3358 padding: 6px 8px;
3345 3359 }
3346 3360
3347 3361 #content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled
3348 3362 {
3349 3363 color: #B4B4B4;
3350 3364 padding: 6px;
3351 3365 }
3352 3366
3353 3367 #login,#register {
3354 3368 width: 520px;
3355 3369 margin: 10% auto 0;
3356 3370 padding: 0;
3357 3371 }
3358 3372
3359 3373 #login div.color,#register div.color {
3360 3374 clear: both;
3361 3375 overflow: hidden;
3362 3376 background: #FFF;
3363 3377 margin: 10px auto 0;
3364 3378 padding: 3px 3px 3px 0;
3365 3379 }
3366 3380
3367 3381 #login div.color a,#register div.color a {
3368 3382 width: 20px;
3369 3383 height: 20px;
3370 3384 display: block;
3371 3385 float: left;
3372 3386 margin: 0 0 0 3px;
3373 3387 padding: 0;
3374 3388 }
3375 3389
3376 3390 #login div.title h5,#register div.title h5 {
3377 3391 color: #fff;
3378 3392 margin: 10px;
3379 3393 padding: 0;
3380 3394 }
3381 3395
3382 3396 #login div.form div.fields div.field,#register div.form div.fields div.field
3383 3397 {
3384 3398 clear: both;
3385 3399 overflow: hidden;
3386 3400 margin: 0;
3387 3401 padding: 0 0 10px;
3388 3402 }
3389 3403
3390 3404 #login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message
3391 3405 {
3392 3406 height: 1%;
3393 3407 display: block;
3394 3408 color: red;
3395 3409 margin: 8px 0 0;
3396 3410 padding: 0;
3397 3411 max-width: 320px;
3398 3412 }
3399 3413
3400 3414 #login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label
3401 3415 {
3402 3416 color: #000;
3403 3417 font-weight: 700;
3404 3418 }
3405 3419
3406 3420 #login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input
3407 3421 {
3408 3422 float: left;
3409 3423 margin: 0;
3410 3424 padding: 0;
3411 3425 }
3412 3426
3413 3427 #login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox
3414 3428 {
3415 3429 margin: 0 0 0 184px;
3416 3430 padding: 0;
3417 3431 }
3418 3432
3419 3433 #login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label
3420 3434 {
3421 3435 color: #565656;
3422 3436 font-weight: 700;
3423 3437 }
3424 3438
3425 3439 #login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input
3426 3440 {
3427 3441 color: #000;
3428 3442 font-size: 1em;
3429 3443 font-weight: 700;
3430 3444 margin: 0;
3431 3445 }
3432 3446
3433 3447 #changeset_content .container .wrapper,#graph_content .container .wrapper
3434 3448 {
3435 3449 width: 600px;
3436 3450 }
3437 3451
3438 3452 #changeset_content .container .left,#graph_content .container .left {
3439 3453 float: left;
3440 3454 width: 70%;
3441 3455 padding-left: 5px;
3442 3456 }
3443 3457
3444 3458 #changeset_content .container .left .date,.ac .match {
3445 3459 font-weight: 700;
3446 3460 padding-top: 5px;
3447 3461 padding-bottom: 5px;
3448 3462 }
3449 3463
3450 3464 div#legend_container table td,div#legend_choices table td {
3451 3465 border: none !important;
3452 3466 height: 20px !important;
3453 3467 padding: 0 !important;
3454 3468 }
3455 3469
3456 3470 .q_filter_box {
3457 3471 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3458 3472 -webkit-border-radius: 4px;
3459 3473 -moz-border-radius: 4px;
3460 3474 border-radius: 4px;
3461 3475 border: 0 none;
3462 3476 color: #AAAAAA;
3463 3477 margin-bottom: -4px;
3464 3478 margin-top: -4px;
3465 3479 padding-left: 3px;
3466 3480 }
3467 3481
3468 3482 #node_filter {
3469 3483 border: 0px solid #545454;
3470 3484 color: #AAAAAA;
3471 3485 padding-left: 3px;
3472 3486 }
3473 3487
3474 3488 /*README STYLE*/
3475 3489
3476 3490 div.readme {
3477 3491 padding:0px;
3478 3492 }
3479 3493
3480 3494 div.readme h2 {
3481 3495 font-weight: normal;
3482 3496 }
3483 3497
3484 3498 div.readme .readme_box {
3485 3499 background-color: #fafafa;
3486 3500 }
3487 3501
3488 3502 div.readme .readme_box {
3489 3503 clear:both;
3490 3504 overflow:hidden;
3491 3505 margin:0;
3492 3506 padding:0 20px 10px;
3493 3507 }
3494 3508
3495 3509 div.readme .readme_box h1, div.readme .readme_box h2, div.readme .readme_box h3, div.readme .readme_box h4, div.readme .readme_box h5, div.readme .readme_box h6 {
3496 3510 border-bottom: 0 !important;
3497 3511 margin: 0 !important;
3498 3512 padding: 0 !important;
3499 3513 line-height: 1.5em !important;
3500 3514 }
3501 3515
3502 3516
3503 3517 div.readme .readme_box h1:first-child {
3504 3518 padding-top: .25em !important;
3505 3519 }
3506 3520
3507 3521 div.readme .readme_box h2, div.readme .readme_box h3 {
3508 3522 margin: 1em 0 !important;
3509 3523 }
3510 3524
3511 3525 div.readme .readme_box h2 {
3512 3526 margin-top: 1.5em !important;
3513 3527 border-top: 4px solid #e0e0e0 !important;
3514 3528 padding-top: .5em !important;
3515 3529 }
3516 3530
3517 3531 div.readme .readme_box p {
3518 3532 color: black !important;
3519 3533 margin: 1em 0 !important;
3520 3534 line-height: 1.5em !important;
3521 3535 }
3522 3536
3523 3537 div.readme .readme_box ul {
3524 3538 list-style: disc !important;
3525 3539 margin: 1em 0 1em 2em !important;
3526 3540 }
3527 3541
3528 3542 div.readme .readme_box ol {
3529 3543 list-style: decimal;
3530 3544 margin: 1em 0 1em 2em !important;
3531 3545 }
3532 3546
3533 3547 div.readme .readme_box pre, code {
3534 3548 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
3535 3549 }
3536 3550
3537 3551 div.readme .readme_box code {
3538 3552 font-size: 12px !important;
3539 3553 background-color: ghostWhite !important;
3540 3554 color: #444 !important;
3541 3555 padding: 0 .2em !important;
3542 3556 border: 1px solid #dedede !important;
3543 3557 }
3544 3558
3545 3559 div.readme .readme_box pre code {
3546 3560 padding: 0 !important;
3547 3561 font-size: 12px !important;
3548 3562 background-color: #eee !important;
3549 3563 border: none !important;
3550 3564 }
3551 3565
3552 3566 div.readme .readme_box pre {
3553 3567 margin: 1em 0;
3554 3568 font-size: 12px;
3555 3569 background-color: #eee;
3556 3570 border: 1px solid #ddd;
3557 3571 padding: 5px;
3558 3572 color: #444;
3559 3573 overflow: auto;
3560 3574 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3561 3575 -webkit-border-radius: 3px;
3562 3576 -moz-border-radius: 3px;
3563 3577 border-radius: 3px;
3564 3578 }
3565 3579
3566 3580
3567 3581 /** RST STYLE **/
3568 3582
3569 3583
3570 3584 div.rst-block {
3571 3585 padding:0px;
3572 3586 }
3573 3587
3574 3588 div.rst-block h2 {
3575 3589 font-weight: normal;
3576 3590 }
3577 3591
3578 3592 div.rst-block {
3579 3593 background-color: #fafafa;
3580 3594 }
3581 3595
3582 3596 div.rst-block {
3583 3597 clear:both;
3584 3598 overflow:hidden;
3585 3599 margin:0;
3586 3600 padding:0 20px 10px;
3587 3601 }
3588 3602
3589 3603 div.rst-block h1, div.rst-block h2, div.rst-block h3, div.rst-block h4, div.rst-block h5, div.rst-block h6 {
3590 3604 border-bottom: 0 !important;
3591 3605 margin: 0 !important;
3592 3606 padding: 0 !important;
3593 3607 line-height: 1.5em !important;
3594 3608 }
3595 3609
3596 3610
3597 3611 div.rst-block h1:first-child {
3598 3612 padding-top: .25em !important;
3599 3613 }
3600 3614
3601 3615 div.rst-block h2, div.rst-block h3 {
3602 3616 margin: 1em 0 !important;
3603 3617 }
3604 3618
3605 3619 div.rst-block h2 {
3606 3620 margin-top: 1.5em !important;
3607 3621 border-top: 4px solid #e0e0e0 !important;
3608 3622 padding-top: .5em !important;
3609 3623 }
3610 3624
3611 3625 div.rst-block p {
3612 3626 color: black !important;
3613 3627 margin: 1em 0 !important;
3614 3628 line-height: 1.5em !important;
3615 3629 }
3616 3630
3617 3631 div.rst-block ul {
3618 3632 list-style: disc !important;
3619 3633 margin: 1em 0 1em 2em !important;
3620 3634 }
3621 3635
3622 3636 div.rst-block ol {
3623 3637 list-style: decimal;
3624 3638 margin: 1em 0 1em 2em !important;
3625 3639 }
3626 3640
3627 3641 div.rst-block pre, code {
3628 3642 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
3629 3643 }
3630 3644
3631 3645 div.rst-block code {
3632 3646 font-size: 12px !important;
3633 3647 background-color: ghostWhite !important;
3634 3648 color: #444 !important;
3635 3649 padding: 0 .2em !important;
3636 3650 border: 1px solid #dedede !important;
3637 3651 }
3638 3652
3639 3653 div.rst-block pre code {
3640 3654 padding: 0 !important;
3641 3655 font-size: 12px !important;
3642 3656 background-color: #eee !important;
3643 3657 border: none !important;
3644 3658 }
3645 3659
3646 3660 div.rst-block pre {
3647 3661 margin: 1em 0;
3648 3662 font-size: 12px;
3649 3663 background-color: #eee;
3650 3664 border: 1px solid #ddd;
3651 3665 padding: 5px;
3652 3666 color: #444;
3653 3667 overflow: auto;
3654 3668 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3655 3669 -webkit-border-radius: 3px;
3656 3670 -moz-border-radius: 3px;
3657 3671 border-radius: 3px;
3658 3672 }
3659 3673
3660 3674
3661 3675 /** comment main **/
3662 3676 .comments {
3663 3677 padding:10px 20px;
3664 3678 }
3665 3679
3666 3680 .comments .comment {
3667 3681 border: 1px solid #ddd;
3668 3682 margin-top: 10px;
3669 3683 -webkit-border-radius: 4px;
3670 3684 -moz-border-radius: 4px;
3671 3685 border-radius: 4px;
3672 3686 }
3673 3687
3674 3688 .comments .comment .meta {
3675 3689 background: #f8f8f8;
3676 3690 padding: 6px;
3677 3691 border-bottom: 1px solid #ddd;
3678 3692 }
3679 3693
3680 3694 .comments .comment .meta img {
3681 3695 vertical-align: middle;
3682 3696 }
3683 3697
3684 3698 .comments .comment .meta .user {
3685 3699 font-weight: bold;
3686 3700 }
3687 3701
3688 3702 .comments .comment .meta .date {
3689 3703 float: right;
3690 3704 }
3691 3705
3692 3706 .comments .comment .text {
3693 3707 padding: 8px 6px 6px 14px;
3694 3708 background-color: #FAFAFA;
3695 3709 }
3696 3710
3697 3711 .comments .comments-number{
3698 3712 padding:0px 0px 10px 0px;
3699 3713 font-weight: bold;
3700 3714 color: #666;
3701 3715 font-size: 16px;
3702 3716 }
3703 3717
3704 3718 /** comment form **/
3705 3719
3706 3720 .comment-form .clearfix{
3707 3721 background: #EEE;
3708 3722 -webkit-border-radius: 4px;
3709 3723 -moz-border-radius: 4px;
3710 3724 border-radius: 4px;
3711 3725 padding: 10px;
3712 3726 }
3713 3727
3714 3728 div.comment-form {
3715 3729 margin-top: 20px;
3716 3730 }
3717 3731
3718 3732 .comment-form strong {
3719 3733 display: block;
3720 3734 margin-bottom: 15px;
3721 3735 }
3722 3736
3723 3737 .comment-form textarea {
3724 3738 width: 100%;
3725 3739 height: 100px;
3726 3740 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
3727 3741 }
3728 3742
3729 3743 form.comment-form {
3730 3744 margin-top: 10px;
3731 3745 margin-left: 10px;
3732 3746 }
3733 3747
3734 3748 .comment-form-submit {
3735 3749 margin-top: 5px;
3736 3750 margin-left: 525px;
3737 3751 }
3738 3752
3739 3753 .file-comments {
3740 3754 display: none;
3741 3755 }
3742 3756
3743 3757 .comment-form .comment {
3744 3758 margin-left: 10px;
3745 3759 }
3746 3760
3747 3761 .comment-form .comment-help{
3748 3762 padding: 0px 0px 5px 0px;
3749 3763 color: #666;
3750 3764 }
3751 3765
3752 3766 .comment-form .comment-button{
3753 3767 padding-top:5px;
3754 3768 }
3755 3769
3756 3770 .add-another-button {
3757 3771 margin-left: 10px;
3758 3772 margin-top: 10px;
3759 3773 margin-bottom: 10px;
3760 3774 }
3761 3775
3762 3776 .comment .buttons {
3763 3777 position: absolute;
3764 3778 right:40px;
3765 3779 }
3766 3780
3767 3781
3768 3782 .show-inline-comments{
3769 3783 position: relative;
3770 3784 top:1px
3771 3785 }
3772 3786
3773 3787 /** comment inline form **/
3774 3788
3775 3789 .comment-inline-form .clearfix{
3776 3790 background: #EEE;
3777 3791 -webkit-border-radius: 4px;
3778 3792 -moz-border-radius: 4px;
3779 3793 border-radius: 4px;
3780 3794 padding: 5px;
3781 3795 }
3782 3796
3783 3797 div.comment-inline-form {
3784 3798 margin-top: 5px;
3785 3799 padding:2px 6px 8px 6px;
3786 3800 }
3787 3801
3788 3802 .comment-inline-form strong {
3789 3803 display: block;
3790 3804 margin-bottom: 15px;
3791 3805 }
3792 3806
3793 3807 .comment-inline-form textarea {
3794 3808 width: 100%;
3795 3809 height: 100px;
3796 3810 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
3797 3811 }
3798 3812
3799 3813 form.comment-inline-form {
3800 3814 margin-top: 10px;
3801 3815 margin-left: 10px;
3802 3816 }
3803 3817
3804 3818 .comment-inline-form-submit {
3805 3819 margin-top: 5px;
3806 3820 margin-left: 525px;
3807 3821 }
3808 3822
3809 3823 .file-comments {
3810 3824 display: none;
3811 3825 }
3812 3826
3813 3827 .comment-inline-form .comment {
3814 3828 margin-left: 10px;
3815 3829 }
3816 3830
3817 3831 .comment-inline-form .comment-help{
3818 3832 padding: 0px 0px 2px 0px;
3819 3833 color: #666666;
3820 3834 font-size: 10px;
3821 3835 }
3822 3836
3823 3837 .comment-inline-form .comment-button{
3824 3838 padding-top:5px;
3825 3839 }
3826 3840
3827 3841 /** comment inline **/
3828 3842 .inline-comments {
3829 3843 padding:10px 20px;
3830 3844 }
3831 3845
3832 3846 .inline-comments div.rst-block {
3833 3847 clear:both;
3834 3848 overflow:hidden;
3835 3849 margin:0;
3836 3850 padding:0 20px 0px;
3837 3851 }
3838 3852 .inline-comments .comment {
3839 3853 border: 1px solid #ddd;
3840 3854 -webkit-border-radius: 4px;
3841 3855 -moz-border-radius: 4px;
3842 3856 border-radius: 4px;
3843 3857 margin: 3px 3px 5px 5px;
3844 3858 background-color: #FAFAFA;
3845 3859 }
3846 3860 .inline-comments .comment-wrapp{
3847 3861 padding:1px;
3848 3862 }
3849 3863 .inline-comments .comment .meta {
3850 3864 background: #f8f8f8;
3851 3865 padding: 6px;
3852 3866 border-bottom: 1px solid #ddd;
3853 3867 }
3854 3868
3855 3869 .inline-comments .comment .meta img {
3856 3870 vertical-align: middle;
3857 3871 }
3858 3872
3859 3873 .inline-comments .comment .meta .user {
3860 3874 font-weight: bold;
3861 3875 }
3862 3876
3863 3877 .inline-comments .comment .meta .date {
3864 3878 float: right;
3865 3879 }
3866 3880
3867 3881 .inline-comments .comment .text {
3868 3882 padding: 8px 6px 6px 14px;
3869 3883 background-color: #FAFAFA;
3870 3884 }
3871 3885
3872 3886 .inline-comments .comments-number{
3873 3887 padding:0px 0px 10px 0px;
3874 3888 font-weight: bold;
3875 3889 color: #666;
3876 3890 font-size: 16px;
3877 3891 }
3878 3892 .inline-comments-button .add-comment{
3879 3893 margin:10px 5px !important;
3880 3894 }
3881 3895 .notifications{
3882 3896 width:22px;
3883 3897 padding:2px;
3884 3898 float:right;
3885 3899 -webkit-border-radius: 4px;
3886 3900 -moz-border-radius: 4px;
3887 3901 border-radius: 4px;
3888 3902 text-align: center;
3889 3903 margin: 0px -10px 0px 5px;
3890 3904 background-color: #DEDEDE;
3891 3905 }
3892 3906 .notifications a{
3893 3907 color:#888 !important;
3894 3908 display: block;
3895 3909 font-size: 10px
3896 3910 }
3897 3911 .notifications a:hover{
3898 3912 text-decoration: none !important;
3899 3913 }
3900 3914 .notification-header{
3901 3915 padding-top:6px;
3902 3916 }
3903 3917 .notification-header .desc{
3904 3918 font-size: 16px;
3905 3919 height: 24px;
3906 3920 float: left
3907 3921 }
3908 3922 .notification-list .container.unread{
3909 3923
3910 3924 }
3911 3925 .notification-header .gravatar{
3912 3926
3913 3927 }
3914 3928 .notification-header .desc.unread{
3915 3929 font-weight: bold;
3916 3930 font-size: 17px;
3917 3931 }
3918 3932
3919 3933 .notification-header .delete-notifications{
3920 3934 float: right;
3921 3935 padding-top: 8px;
3922 3936 cursor: pointer;
3923 3937 }
3924 3938 .notification-subject{
3925 3939 clear:both;
3926 3940 border-bottom: 1px solid #eee;
3927 3941 padding:5px 0px 5px 38px;
3928 3942 }
3929 3943
3930 3944
3931 3945 /*****************************************************************************
3932 3946 DIFFS CSS
3933 3947 ******************************************************************************/
3934 3948
3935 3949 div.diffblock {
3936 3950 overflow: auto;
3937 3951 padding: 0px;
3938 3952 border: 1px solid #ccc;
3939 3953 background: #f8f8f8;
3940 3954 font-size: 100%;
3941 3955 line-height: 100%;
3942 3956 /* new */
3943 3957 line-height: 125%;
3944 3958 -webkit-border-radius: 6px 6px 0px 0px;
3945 3959 -moz-border-radius: 6px 6px 0px 0px;
3946 3960 border-radius: 6px 6px 0px 0px;
3947 3961 }
3948 3962 div.diffblock.margined{
3949 3963 margin: 0px 20px 0px 20px;
3950 3964 }
3951 3965 div.diffblock .code-header{
3952 3966 border-bottom: 1px solid #CCCCCC;
3953 3967 background: #EEEEEE;
3954 3968 padding:10px 0 10px 0;
3955 3969 height: 14px;
3956 3970 }
3957 3971 div.diffblock .code-header.cv{
3958 3972 height: 34px;
3959 3973 }
3960 3974 div.diffblock .code-header-title{
3961 3975 padding: 0px 0px 10px 5px !important;
3962 3976 margin: 0 !important;
3963 3977 }
3964 3978
3965 3979 div.diffblock .code-header .date{
3966 3980 float:left;
3967 3981 text-transform: uppercase;
3968 3982 }
3969 3983 div.diffblock .code-header div{
3970 3984 margin-left:4px;
3971 3985 font-weight: bold;
3972 3986 font-size: 14px;
3973 3987 }
3974 3988 div.diffblock .code-body{
3975 3989 background: #FFFFFF;
3976 3990 }
3977 3991 div.diffblock pre.raw{
3978 3992 background: #FFFFFF;
3979 3993 color:#000000;
3980 3994 }
3981 3995 table.code-difftable{
3982 3996 border-collapse: collapse;
3983 3997 width: 99%;
3984 3998 }
3985 3999 table.code-difftable td {
3986 4000 padding: 0 !important;
3987 4001 background: none !important;
3988 4002 border:0 !important;
3989 4003 vertical-align: none !important;
3990 4004 }
3991 4005 table.code-difftable .context{
3992 4006 background:none repeat scroll 0 0 #DDE7EF;
3993 4007 }
3994 4008 table.code-difftable .add{
3995 4009 background:none repeat scroll 0 0 #DDFFDD;
3996 4010 }
3997 4011 table.code-difftable .add ins{
3998 4012 background:none repeat scroll 0 0 #AAFFAA;
3999 4013 text-decoration:none;
4000 4014 }
4001 4015 table.code-difftable .del{
4002 4016 background:none repeat scroll 0 0 #FFDDDD;
4003 4017 }
4004 4018 table.code-difftable .del del{
4005 4019 background:none repeat scroll 0 0 #FFAAAA;
4006 4020 text-decoration:none;
4007 4021 }
4008 4022
4009 4023 /** LINE NUMBERS **/
4010 4024 table.code-difftable .lineno{
4011 4025
4012 4026 padding-left:2px;
4013 4027 padding-right:2px;
4014 4028 text-align:right;
4015 4029 width:32px;
4016 4030 -moz-user-select:none;
4017 4031 -webkit-user-select: none;
4018 4032 border-right: 1px solid #CCC !important;
4019 4033 border-left: 0px solid #CCC !important;
4020 4034 border-top: 0px solid #CCC !important;
4021 4035 border-bottom: none !important;
4022 4036 vertical-align: middle !important;
4023 4037
4024 4038 }
4025 4039 table.code-difftable .lineno.new {
4026 4040 }
4027 4041 table.code-difftable .lineno.old {
4028 4042 }
4029 4043 table.code-difftable .lineno a{
4030 4044 color:#747474 !important;
4031 4045 font:11px "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace !important;
4032 4046 letter-spacing:-1px;
4033 4047 text-align:right;
4034 4048 padding-right: 2px;
4035 4049 cursor: pointer;
4036 4050 display: block;
4037 4051 width: 32px;
4038 4052 }
4039 4053
4040 4054 table.code-difftable .lineno-inline{
4041 4055 background:none repeat scroll 0 0 #FFF !important;
4042 4056 padding-left:2px;
4043 4057 padding-right:2px;
4044 4058 text-align:right;
4045 4059 width:30px;
4046 4060 -moz-user-select:none;
4047 4061 -webkit-user-select: none;
4048 4062 }
4049 4063
4050 4064 /** CODE **/
4051 4065 table.code-difftable .code {
4052 4066 display: block;
4053 4067 width: 100%;
4054 4068 }
4055 4069 table.code-difftable .code td{
4056 4070 margin:0;
4057 4071 padding:0;
4058 4072 }
4059 4073 table.code-difftable .code pre{
4060 4074 margin:0;
4061 4075 padding:0;
4062 4076 height: 17px;
4063 4077 line-height: 17px;
4064 4078 }
4065 4079
4066 4080
4067 4081 .diffblock.margined.comm .line .code:hover{
4068 4082 background-color:#FFFFCC !important;
4069 4083 cursor: pointer !important;
4070 4084 background-image:url("../images/icons/comment_add.png") !important;
4071 4085 background-repeat:no-repeat !important;
4072 4086 background-position: right !important;
4073 4087 background-position: 0% 50% !important;
4074 4088 }
4075 4089 .diffblock.margined.comm .line .code.no-comment:hover{
4076 4090 background-image: none !important;
4077 4091 cursor: auto !important;
4078 4092 background-color: inherit !important;
4079 4093
4080 4094 } No newline at end of file
@@ -1,670 +1,695 b''
1 1 <%inherit file="/base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
5 5 </%def>
6 6
7 7 <%def name="breadcrumbs_links()">
8 8 ${h.link_to(u'Home',h.url('/'))}
9 9 &raquo;
10 10 ${h.link_to(c.dbrepo.just_name,h.url('summary_home',repo_name=c.repo_name))}
11 11 &raquo;
12 12 ${_('summary')}
13 13 </%def>
14 14
15 15 <%def name="page_nav()">
16 16 ${self.menu('summary')}
17 17 </%def>
18 18
19 19 <%def name="main()">
20 20 <%
21 21 summary = lambda n:{False:'summary-short'}.get(n)
22 22 %>
23 23 %if c.show_stats:
24 24 <div class="box box-left">
25 25 %else:
26 26 <div class="box">
27 27 %endif
28 28 <!-- box / title -->
29 29 <div class="title">
30 30 ${self.breadcrumbs()}
31 31 </div>
32 32 <!-- end box / title -->
33 33 <div class="form">
34 34 <div id="summary" class="fields">
35 35
36 36 <div class="field">
37 37 <div class="label-summary">
38 38 <label>${_('Name')}:</label>
39 39 </div>
40 40 <div class="input ${summary(c.show_stats)}">
41 41 <div style="float:right;padding:5px 0px 0px 5px">
42 42 %if c.rhodecode_user.username != 'default':
43 43 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='rss_icon')}
44 44 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='atom_icon')}
45 45 %else:
46 46 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name),class_='rss_icon')}
47 47 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name),class_='atom_icon')}
48 48 %endif
49 49 </div>
50 50 %if c.rhodecode_user.username != 'default':
51 51 %if c.following:
52 52 <span id="follow_toggle" class="following" title="${_('Stop following this repository')}"
53 53 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
54 54 </span>
55 55 %else:
56 56 <span id="follow_toggle" class="follow" title="${_('Start following this repository')}"
57 57 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
58 58 </span>
59 59 %endif
60 60 %endif:
61 61 ##REPO TYPE
62 62 %if c.dbrepo.repo_type =='hg':
63 63 <img style="margin-bottom:2px" class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
64 64 %endif
65 65 %if c.dbrepo.repo_type =='git':
66 66 <img style="margin-bottom:2px" class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
67 67 %endif
68 68
69 69 ##PUBLIC/PRIVATE
70 70 %if c.dbrepo.private:
71 71 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
72 72 %else:
73 73 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
74 74 %endif
75 75
76 76 ##REPO NAME
77 <span class="repo_name">${h.repo_link(c.dbrepo.groups_and_repo)}</span>
77 <span class="repo_name" title="${_('Non changable ID %s') % c.dbrepo.repo_id}">${h.repo_link(c.dbrepo.groups_and_repo)}</span>
78 78
79 79 ##FORK
80 80 %if c.dbrepo.fork:
81 81 <div style="margin-top:5px;clear:both"">
82 82 <a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}"><img class="icon" alt="${_('public')}" title="${_('Fork of')} ${c.dbrepo.fork.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/>
83 83 ${_('Fork of')} ${c.dbrepo.fork.repo_name}
84 84 </a>
85 85 </div>
86 86 %endif
87 87 ##REMOTE
88 88 %if c.dbrepo.clone_uri:
89 89 <div style="margin-top:5px;clear:both">
90 90 <a href="${h.url(str(h.hide_credentials(c.dbrepo.clone_uri)))}"><img class="icon" alt="${_('remote clone')}" title="${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}" src="${h.url('/images/icons/connect.png')}"/>
91 91 ${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}
92 92 </a>
93 93 </div>
94 94 %endif
95 95 </div>
96 96 </div>
97 97
98 98 <div class="field">
99 99 <div class="label-summary">
100 100 <label>${_('Description')}:</label>
101 101 </div>
102 102 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(c.dbrepo.description)}</div>
103 103 </div>
104 104
105 105 <div class="field">
106 106 <div class="label-summary">
107 107 <label>${_('Contact')}:</label>
108 108 </div>
109 109 <div class="input ${summary(c.show_stats)}">
110 110 <div class="gravatar">
111 111 <img alt="gravatar" src="${h.gravatar_url(c.dbrepo.user.email)}"/>
112 112 </div>
113 113 ${_('Username')}: ${c.dbrepo.user.username}<br/>
114 114 ${_('Name')}: ${c.dbrepo.user.name} ${c.dbrepo.user.lastname}<br/>
115 115 ${_('Email')}: <a href="mailto:${c.dbrepo.user.email}">${c.dbrepo.user.email}</a>
116 116 </div>
117 117 </div>
118 118
119 119 <div class="field">
120 120 <div class="label-summary">
121 121 <label>${_('Clone url')}:</label>
122 122 </div>
123 123 <div class="input ${summary(c.show_stats)}">
124 <input type="text" id="clone_url" readonly="readonly" value="${c.clone_repo_url}" size="70"/>
124 <div style="display:none" id="clone_by_name" class="ui-btn clone">${_('Show by Name')}</div>
125 <div id="clone_by_id" class="ui-btn clone">${_('Show by ID')}</div>
126 <input style="width:80%;margin-left:105px" type="text" id="clone_url" readonly="readonly" value="${c.clone_repo_url}"/>
127 <input style="display:none;width:80%;margin-left:105px" type="text" id="clone_url_id" readonly="readonly" value="${c.clone_repo_url_id}"/>
125 128 </div>
126 129 </div>
127 130
128 131 <div class="field">
129 132 <div class="label-summary">
130 133 <label>${_('Trending files')}:</label>
131 134 </div>
132 135 <div class="input ${summary(c.show_stats)}">
133 136 %if c.show_stats:
134 137 <div id="lang_stats"></div>
135 138 %else:
136 139 ${_('Statistics are disabled for this repository')}
137 140 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
138 141 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
139 142 %endif
140 143 %endif
141 144 </div>
142 145 </div>
143 146
144 147 <div class="field">
145 148 <div class="label-summary">
146 149 <label>${_('Download')}:</label>
147 150 </div>
148 151 <div class="input ${summary(c.show_stats)}">
149 152 %if len(c.rhodecode_repo.revisions) == 0:
150 153 ${_('There are no downloads yet')}
151 154 %elif c.enable_downloads is False:
152 155 ${_('Downloads are disabled for this repository')}
153 156 %if h.HasPermissionAll('hg.admin')('enable downloads on from summary'):
154 157 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
155 158 %endif
156 159 %else:
157 160 ${h.select('download_options',c.rhodecode_repo.get_changeset().raw_id,c.download_options)}
158 161 <span id="${'zip_link'}">${h.link_to('Download as zip',h.url('files_archive_home',repo_name=c.dbrepo.repo_name,fname='tip.zip'),class_="archive_icon ui-btn")}</span>
159 162 <span style="vertical-align: bottom">
160 163 <input id="archive_subrepos" type="checkbox" name="subrepos"/> <span class="tooltip" title="${_('Check this to download archive with subrepos')}" >${_('with subrepos')}</span>
161 164 </span>
162 165 %endif
163 166 </div>
164 167 </div>
165 168 </div>
166 169 </div>
167 170 </div>
168 171
169 172 %if c.show_stats:
170 173 <div class="box box-right" style="min-height:455px">
171 174 <!-- box / title -->
172 175 <div class="title">
173 176 <h5>${_('Commit activity by day / author')}</h5>
174 177 </div>
175 178
176 179 <div class="graph">
177 180 <div style="padding:0 10px 10px 15px;font-size: 1.2em;">
178 181 %if c.no_data:
179 182 ${c.no_data_msg}
180 183 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
181 184 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-btn")}
182 185 %endif
183 186 %else:
184 187 ${_('Loaded in')} ${c.stats_percentage} %
185 188 %endif
186 189 </div>
187 190 <div id="commit_history" style="width:450px;height:300px;float:left"></div>
188 191 <div style="clear: both;height: 10px"></div>
189 192 <div id="overview" style="width:450px;height:100px;float:left"></div>
190 193
191 194 <div id="legend_data" style="clear:both;margin-top:10px;">
192 195 <div id="legend_container"></div>
193 196 <div id="legend_choices">
194 197 <table id="legend_choices_tables" class="noborder" style="font-size:smaller;color:#545454"></table>
195 198 </div>
196 199 </div>
197 200 </div>
198 201 </div>
199 202 %endif
200 203
201 204 <div class="box">
202 205 <div class="title">
203 206 <div class="breadcrumbs">
204 207 %if c.repo_changesets:
205 208 ${h.link_to(_('Shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}
206 209 %else:
207 210 ${_('Quick start')}
208 211 %endif
209 212 </div>
210 213 </div>
211 214 <div class="table">
212 215 <div id="shortlog_data">
213 216 <%include file='../shortlog/shortlog_data.html'/>
214 217 </div>
215 218 </div>
216 219 </div>
217 220
218 221 %if c.readme_data:
219 222 <div class="box" style="background-color: #FAFAFA">
220 223 <div class="title">
221 224 <div class="breadcrumbs"><a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a></div>
222 225 </div>
223 226 <div class="readme">
224 227 <div class="readme_box">
225 228 ${c.readme_data|n}
226 229 </div>
227 230 </div>
228 231 </div>
229 232 %endif
230 233
231 234 <script type="text/javascript">
232 235 var clone_url = 'clone_url';
233 236 YUE.on(clone_url,'click',function(e){
234 237 if(YUD.hasClass(clone_url,'selected')){
235 238 return
236 239 }
237 240 else{
238 241 YUD.addClass(clone_url,'selected');
239 242 YUD.get(clone_url).select();
240 243 }
241 244 })
242 245
246 YUE.on('clone_by_name','click',function(e){
247 // show url by name and hide name button
248 YUD.setStyle('clone_url','display','');
249 YUD.setStyle('clone_by_name','display','none');
250
251 // hide url by id and show name button
252 YUD.setStyle('clone_by_id','display','');
253 YUD.setStyle('clone_url_id','display','none');
254
255 })
256 YUE.on('clone_by_id','click',function(e){
257
258 // show url by id and hide id button
259 YUD.setStyle('clone_by_id','display','none');
260 YUD.setStyle('clone_url_id','display','');
261
262 // hide url by name and show id button
263 YUD.setStyle('clone_by_name','display','');
264 YUD.setStyle('clone_url','display','none');
265 })
266
267
243 268 var tmpl_links = {};
244 269 %for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
245 270 tmpl_links["${archive['type']}"] = '${h.link_to('__NAME__', h.url('files_archive_home',repo_name=c.dbrepo.repo_name, fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_='archive_icon ui-btn')}';
246 271 %endfor
247 272
248 273 YUE.on(['download_options','archive_subrepos'],'change',function(e){
249 274 var sm = YUD.get('download_options');
250 275 var new_cs = sm.options[sm.selectedIndex];
251 276
252 277 for(k in tmpl_links){
253 278 var s = YUD.get(k+'_link');
254 279 if(s){
255 280 var title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}";
256 281 title_tmpl= title_tmpl.replace('__CS_NAME__',new_cs.text);
257 282 title_tmpl = title_tmpl.replace('__CS_EXT__',k);
258 283
259 284 var url = tmpl_links[k].replace('__CS__',new_cs.value);
260 285 var subrepos = YUD.get('archive_subrepos').checked;
261 286 url = url.replace('__SUB__',subrepos);
262 287 url = url.replace('__NAME__',title_tmpl);
263 288 s.innerHTML = url
264 289 }
265 290 }
266 291 });
267 292 </script>
268 293 %if c.show_stats:
269 294 <script type="text/javascript">
270 295 var data = ${c.trending_languages|n};
271 296 var total = 0;
272 297 var no_data = true;
273 298 for (k in data){
274 299 total += data[k].count;
275 300 no_data = false;
276 301 }
277 302 var tbl = document.createElement('table');
278 303 tbl.setAttribute('class','trending_language_tbl');
279 304 var cnt = 0;
280 305 for (k in data){
281 306 cnt += 1;
282 307 var hide = cnt>2;
283 308 var tr = document.createElement('tr');
284 309 if (hide){
285 310 tr.setAttribute('style','display:none');
286 311 tr.setAttribute('class','stats_hidden');
287 312 }
288 313 var percentage = Math.round((data[k].count/total*100),2);
289 314 var value = data[k].count;
290 315 var td1 = document.createElement('td');
291 316 td1.width = 150;
292 317 var trending_language_label = document.createElement('div');
293 318 trending_language_label.innerHTML = data[k].desc+" ("+k+")";
294 319 td1.appendChild(trending_language_label);
295 320
296 321 var td2 = document.createElement('td');
297 322 td2.setAttribute('style','padding-right:14px !important');
298 323 var trending_language = document.createElement('div');
299 324 var nr_files = value+" ${_('files')}";
300 325
301 326 trending_language.title = k+" "+nr_files;
302 327
303 328 if (percentage>22){
304 329 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
305 330 }
306 331 else{
307 332 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
308 333 }
309 334
310 335 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
311 336 trending_language.style.width=percentage+"%";
312 337 td2.appendChild(trending_language);
313 338
314 339 tr.appendChild(td1);
315 340 tr.appendChild(td2);
316 341 tbl.appendChild(tr);
317 342 if(cnt == 3){
318 343 var show_more = document.createElement('tr');
319 344 var td = document.createElement('td');
320 345 lnk = document.createElement('a');
321 346
322 347 lnk.href='#';
323 348 lnk.innerHTML = "${_('show more')}";
324 349 lnk.id='code_stats_show_more';
325 350 td.appendChild(lnk);
326 351
327 352 show_more.appendChild(td);
328 353 show_more.appendChild(document.createElement('td'));
329 354 tbl.appendChild(show_more);
330 355 }
331 356
332 357 }
333 358
334 359 YUD.get('lang_stats').appendChild(tbl);
335 360 YUE.on('code_stats_show_more','click',function(){
336 361 l = YUD.getElementsByClassName('stats_hidden')
337 362 for (e in l){
338 363 YUD.setStyle(l[e],'display','');
339 364 };
340 365 YUD.setStyle(YUD.get('code_stats_show_more'),
341 366 'display','none');
342 367 });
343 368 </script>
344 369 <script type="text/javascript">
345 370 /**
346 371 * Plots summary graph
347 372 *
348 373 * @class SummaryPlot
349 374 * @param {from} initial from for detailed graph
350 375 * @param {to} initial to for detailed graph
351 376 * @param {dataset}
352 377 * @param {overview_dataset}
353 378 */
354 379 function SummaryPlot(from,to,dataset,overview_dataset) {
355 380 var initial_ranges = {
356 381 "xaxis":{
357 382 "from":from,
358 383 "to":to,
359 384 },
360 385 };
361 386 var dataset = dataset;
362 387 var overview_dataset = [overview_dataset];
363 388 var choiceContainer = YUD.get("legend_choices");
364 389 var choiceContainerTable = YUD.get("legend_choices_tables");
365 390 var plotContainer = YUD.get('commit_history');
366 391 var overviewContainer = YUD.get('overview');
367 392
368 393 var plot_options = {
369 394 bars: {show:true,align:'center',lineWidth:4},
370 395 legend: {show:true, container:"legend_container"},
371 396 points: {show:true,radius:0,fill:false},
372 397 yaxis: {tickDecimals:0,},
373 398 xaxis: {
374 399 mode: "time",
375 400 timeformat: "%d/%m",
376 401 min:from,
377 402 max:to,
378 403 },
379 404 grid: {
380 405 hoverable: true,
381 406 clickable: true,
382 407 autoHighlight:true,
383 408 color: "#999"
384 409 },
385 410 //selection: {mode: "x"}
386 411 };
387 412 var overview_options = {
388 413 legend:{show:false},
389 414 bars: {show:true,barWidth: 2,},
390 415 shadowSize: 0,
391 416 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
392 417 yaxis: {ticks: 3, min: 0,tickDecimals:0,},
393 418 grid: {color: "#999",},
394 419 selection: {mode: "x"}
395 420 };
396 421
397 422 /**
398 423 *get dummy data needed in few places
399 424 */
400 425 function getDummyData(label){
401 426 return {"label":label,
402 427 "data":[{"time":0,
403 428 "commits":0,
404 429 "added":0,
405 430 "changed":0,
406 431 "removed":0,
407 432 }],
408 433 "schema":["commits"],
409 434 "color":'#ffffff',
410 435 }
411 436 }
412 437
413 438 /**
414 439 * generate checkboxes accordindly to data
415 440 * @param keys
416 441 * @returns
417 442 */
418 443 function generateCheckboxes(data) {
419 444 //append checkboxes
420 445 var i = 0;
421 446 choiceContainerTable.innerHTML = '';
422 447 for(var pos in data) {
423 448
424 449 data[pos].color = i;
425 450 i++;
426 451 if(data[pos].label != ''){
427 452 choiceContainerTable.innerHTML += '<tr><td>'+
428 453 '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
429 454 +data[pos].label+
430 455 '</td></tr>';
431 456 }
432 457 }
433 458 }
434 459
435 460 /**
436 461 * ToolTip show
437 462 */
438 463 function showTooltip(x, y, contents) {
439 464 var div=document.getElementById('tooltip');
440 465 if(!div) {
441 466 div = document.createElement('div');
442 467 div.id="tooltip";
443 468 div.style.position="absolute";
444 469 div.style.border='1px solid #fdd';
445 470 div.style.padding='2px';
446 471 div.style.backgroundColor='#fee';
447 472 document.body.appendChild(div);
448 473 }
449 474 YUD.setStyle(div, 'opacity', 0);
450 475 div.innerHTML = contents;
451 476 div.style.top=(y + 5) + "px";
452 477 div.style.left=(x + 5) + "px";
453 478
454 479 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
455 480 anim.animate();
456 481 }
457 482
458 483 /**
459 484 * This function will detect if selected period has some changesets
460 485 for this user if it does this data is then pushed for displaying
461 486 Additionally it will only display users that are selected by the checkbox
462 487 */
463 488 function getDataAccordingToRanges(ranges) {
464 489
465 490 var data = [];
466 491 var new_dataset = {};
467 492 var keys = [];
468 493 var max_commits = 0;
469 494 for(var key in dataset){
470 495
471 496 for(var ds in dataset[key].data){
472 497 commit_data = dataset[key].data[ds];
473 498 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
474 499
475 500 if(new_dataset[key] === undefined){
476 501 new_dataset[key] = {data:[],schema:["commits"],label:key};
477 502 }
478 503 new_dataset[key].data.push(commit_data);
479 504 }
480 505 }
481 506 if (new_dataset[key] !== undefined){
482 507 data.push(new_dataset[key]);
483 508 }
484 509 }
485 510
486 511 if (data.length > 0){
487 512 return data;
488 513 }
489 514 else{
490 515 //just return dummy data for graph to plot itself
491 516 return [getDummyData('')];
492 517 }
493 518 }
494 519
495 520 /**
496 521 * redraw using new checkbox data
497 522 */
498 523 function plotchoiced(e,args){
499 524 var cur_data = args[0];
500 525 var cur_ranges = args[1];
501 526
502 527 var new_data = [];
503 528 var inputs = choiceContainer.getElementsByTagName("input");
504 529
505 530 //show only checked labels
506 531 for(var i=0; i<inputs.length; i++) {
507 532 var checkbox_key = inputs[i].name;
508 533
509 534 if(inputs[i].checked){
510 535 for(var d in cur_data){
511 536 if(cur_data[d].label == checkbox_key){
512 537 new_data.push(cur_data[d]);
513 538 }
514 539 }
515 540 }
516 541 else{
517 542 //push dummy data to not hide the label
518 543 new_data.push(getDummyData(checkbox_key));
519 544 }
520 545 }
521 546
522 547 var new_options = YAHOO.lang.merge(plot_options, {
523 548 xaxis: {
524 549 min: cur_ranges.xaxis.from,
525 550 max: cur_ranges.xaxis.to,
526 551 mode:"time",
527 552 timeformat: "%d/%m",
528 553 },
529 554 });
530 555 if (!new_data){
531 556 new_data = [[0,1]];
532 557 }
533 558 // do the zooming
534 559 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
535 560
536 561 plot.subscribe("plotselected", plotselected);
537 562
538 563 //resubscribe plothover
539 564 plot.subscribe("plothover", plothover);
540 565
541 566 // don't fire event on the overview to prevent eternal loop
542 567 overview.setSelection(cur_ranges, true);
543 568
544 569 }
545 570
546 571 /**
547 572 * plot only selected items from overview
548 573 * @param ranges
549 574 * @returns
550 575 */
551 576 function plotselected(ranges,cur_data) {
552 577 //updates the data for new plot
553 578 var data = getDataAccordingToRanges(ranges);
554 579 generateCheckboxes(data);
555 580
556 581 var new_options = YAHOO.lang.merge(plot_options, {
557 582 xaxis: {
558 583 min: ranges.xaxis.from,
559 584 max: ranges.xaxis.to,
560 585 mode:"time",
561 586 timeformat: "%d/%m",
562 587 },
563 588 });
564 589 // do the zooming
565 590 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
566 591
567 592 plot.subscribe("plotselected", plotselected);
568 593
569 594 //resubscribe plothover
570 595 plot.subscribe("plothover", plothover);
571 596
572 597 // don't fire event on the overview to prevent eternal loop
573 598 overview.setSelection(ranges, true);
574 599
575 600 //resubscribe choiced
576 601 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
577 602 }
578 603
579 604 var previousPoint = null;
580 605
581 606 function plothover(o) {
582 607 var pos = o.pos;
583 608 var item = o.item;
584 609
585 610 //YUD.get("x").innerHTML = pos.x.toFixed(2);
586 611 //YUD.get("y").innerHTML = pos.y.toFixed(2);
587 612 if (item) {
588 613 if (previousPoint != item.datapoint) {
589 614 previousPoint = item.datapoint;
590 615
591 616 var tooltip = YUD.get("tooltip");
592 617 if(tooltip) {
593 618 tooltip.parentNode.removeChild(tooltip);
594 619 }
595 620 var x = item.datapoint.x.toFixed(2);
596 621 var y = item.datapoint.y.toFixed(2);
597 622
598 623 if (!item.series.label){
599 624 item.series.label = 'commits';
600 625 }
601 626 var d = new Date(x*1000);
602 627 var fd = d.toDateString()
603 628 var nr_commits = parseInt(y);
604 629
605 630 var cur_data = dataset[item.series.label].data[item.dataIndex];
606 631 var added = cur_data.added;
607 632 var changed = cur_data.changed;
608 633 var removed = cur_data.removed;
609 634
610 635 var nr_commits_suffix = " ${_('commits')} ";
611 636 var added_suffix = " ${_('files added')} ";
612 637 var changed_suffix = " ${_('files changed')} ";
613 638 var removed_suffix = " ${_('files removed')} ";
614 639
615 640
616 641 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
617 642 if(added==1){added_suffix=" ${_('file added')} ";}
618 643 if(changed==1){changed_suffix=" ${_('file changed')} ";}
619 644 if(removed==1){removed_suffix=" ${_('file removed')} ";}
620 645
621 646 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
622 647 +'<br/>'+
623 648 nr_commits + nr_commits_suffix+'<br/>'+
624 649 added + added_suffix +'<br/>'+
625 650 changed + changed_suffix + '<br/>'+
626 651 removed + removed_suffix + '<br/>');
627 652 }
628 653 }
629 654 else {
630 655 var tooltip = YUD.get("tooltip");
631 656
632 657 if(tooltip) {
633 658 tooltip.parentNode.removeChild(tooltip);
634 659 }
635 660 previousPoint = null;
636 661 }
637 662 }
638 663
639 664 /**
640 665 * MAIN EXECUTION
641 666 */
642 667
643 668 var data = getDataAccordingToRanges(initial_ranges);
644 669 generateCheckboxes(data);
645 670
646 671 //main plot
647 672 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
648 673
649 674 //overview
650 675 var overview = YAHOO.widget.Flot(overviewContainer,
651 676 overview_dataset, overview_options);
652 677
653 678 //show initial selection on overview
654 679 overview.setSelection(initial_ranges);
655 680
656 681 plot.subscribe("plotselected", plotselected);
657 682 plot.subscribe("plothover", plothover)
658 683
659 684 overview.subscribe("plotselected", function (ranges) {
660 685 plot.setSelection(ranges);
661 686 });
662 687
663 688 // user choices on overview
664 689 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
665 690 }
666 691 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
667 692 </script>
668 693 %endif
669 694
670 695 </%def>
@@ -1,206 +1,210 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.tests.test_hg_operations
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Test suite for making push/pull operations
7 7
8 8 :created_on: Dec 30, 2010
9 9 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 10 :license: GPLv3, see COPYING for more details.
11 11 """
12 12 # This program is free software: you can redistribute it and/or modify
13 13 # it under the terms of the GNU General Public License as published by
14 14 # the Free Software Foundation, either version 3 of the License, or
15 15 # (at your option) any later version.
16 16 #
17 17 # This program is distributed in the hope that it will be useful,
18 18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 20 # GNU General Public License for more details.
21 21 #
22 22 # You should have received a copy of the GNU General Public License
23 23 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 24
25 25 import os
26 26 import sys
27 27 import shutil
28 28 import logging
29 29 from os.path import join as jn
30 30 from os.path import dirname as dn
31 31
32 32 from tempfile import _RandomNameSequence
33 33 from subprocess import Popen, PIPE
34 34
35 35 from paste.deploy import appconfig
36 36 from pylons import config
37 37 from sqlalchemy import engine_from_config
38 38
39 39 from rhodecode.lib.utils import add_cache
40 40 from rhodecode.model import init_model
41 41 from rhodecode.model import meta
42 42 from rhodecode.model.db import User, Repository
43 43 from rhodecode.lib.auth import get_crypt_password
44 44
45 45 from rhodecode.tests import TESTS_TMP_PATH, NEW_HG_REPO, HG_REPO
46 46 from rhodecode.config.environment import load_environment
47 47
48 48 rel_path = dn(dn(dn(os.path.abspath(__file__))))
49 49 conf = appconfig('config:development.ini', relative_to=rel_path)
50 50 load_environment(conf.global_conf, conf.local_conf)
51 51
52 52 add_cache(conf)
53 53
54 54 USER = 'test_admin'
55 55 PASS = 'test12'
56 56 HOST = 'hg.local'
57 57 METHOD = 'pull'
58 58 DEBUG = True
59 59 log = logging.getLogger(__name__)
60 60
61 61
62 62 class Command(object):
63 63
64 64 def __init__(self, cwd):
65 65 self.cwd = cwd
66 66
67 67 def execute(self, cmd, *args):
68 68 """Runs command on the system with given ``args``.
69 69 """
70 70
71 71 command = cmd + ' ' + ' '.join(args)
72 72 log.debug('Executing %s' % command)
73 73 if DEBUG:
74 74 print command
75 75 p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
76 76 stdout, stderr = p.communicate()
77 77 if DEBUG:
78 78 print stdout, stderr
79 79 return stdout, stderr
80 80
81 81 def get_session():
82 82 engine = engine_from_config(conf, 'sqlalchemy.db1.')
83 83 init_model(engine)
84 84 sa = meta.Session
85 85 return sa
86 86
87 87
88 88 def create_test_user(force=True):
89 89 print 'creating test user'
90 90 sa = get_session()
91 91
92 92 user = sa.query(User).filter(User.username == USER).scalar()
93 93
94 94 if force and user is not None:
95 95 print 'removing current user'
96 96 for repo in sa.query(Repository).filter(Repository.user == user).all():
97 97 sa.delete(repo)
98 98 sa.delete(user)
99 99 sa.commit()
100 100
101 101 if user is None or force:
102 102 print 'creating new one'
103 103 new_usr = User()
104 104 new_usr.username = USER
105 105 new_usr.password = get_crypt_password(PASS)
106 106 new_usr.email = 'mail@mail.com'
107 107 new_usr.name = 'test'
108 108 new_usr.lastname = 'lasttestname'
109 109 new_usr.active = True
110 110 new_usr.admin = True
111 111 sa.add(new_usr)
112 112 sa.commit()
113 113
114 114 print 'done'
115 115
116 116
117 117 def create_test_repo(force=True):
118 118 print 'creating test repo'
119 119 from rhodecode.model.repo import RepoModel
120 120 sa = get_session()
121 121
122 122 user = sa.query(User).filter(User.username == USER).scalar()
123 123 if user is None:
124 124 raise Exception('user not found')
125 125
126 126
127 127 repo = sa.query(Repository).filter(Repository.repo_name == HG_REPO).scalar()
128 128
129 129 if repo is None:
130 130 print 'repo not found creating'
131 131
132 132 form_data = {'repo_name':HG_REPO,
133 133 'repo_type':'hg',
134 134 'private':False,
135 135 'clone_uri':'' }
136 136 rm = RepoModel(sa)
137 137 rm.base_path = '/home/hg'
138 138 rm.create(form_data, user)
139 139
140 140 print 'done'
141 141
142 142 def set_anonymous_access(enable=True):
143 143 sa = get_session()
144 144 user = sa.query(User).filter(User.username == 'default').one()
145 145 user.active = enable
146 146 sa.add(user)
147 147 sa.commit()
148 148
149 149 def get_anonymous_access():
150 150 sa = get_session()
151 151 return sa.query(User).filter(User.username == 'default').one().active
152 152
153 153
154 154 #==============================================================================
155 155 # TESTS
156 156 #==============================================================================
157 157 def test_clone_with_credentials(no_errors=False, repo=HG_REPO, method=METHOD,
158 158 seq=None):
159 159 cwd = path = jn(TESTS_TMP_PATH, repo)
160 160
161 161 if seq == None:
162 162 seq = _RandomNameSequence().next()
163 163
164 164 try:
165 165 shutil.rmtree(path, ignore_errors=True)
166 166 os.makedirs(path)
167 167 #print 'made dirs %s' % jn(path)
168 168 except OSError:
169 169 raise
170 170
171
172 171 clone_url = 'http://%(user)s:%(pass)s@%(host)s/%(cloned_repo)s' % \
173 172 {'user':USER,
174 173 'pass':PASS,
175 174 'host':HOST,
176 175 'cloned_repo':repo, }
177 176
178 177 dest = path + seq
179 178 if method == 'pull':
180 179 stdout, stderr = Command(cwd).execute('hg', method, '--cwd', dest, clone_url)
181 180 else:
182 181 stdout, stderr = Command(cwd).execute('hg', method, clone_url, dest)
183 182
184 183 if no_errors is False:
185 184 assert """adding file changes""" in stdout, 'no messages about cloning'
186 185 assert """abort""" not in stderr , 'got error from clone'
187 186
188 187 if __name__ == '__main__':
189 188 try:
190 189 create_test_user(force=False)
191 190 seq = None
192 191 import time
193 192
193 try:
194 METHOD = sys.argv[3]
195 except:
196 pass
197
194 198 if METHOD == 'pull':
195 199 seq = _RandomNameSequence().next()
196 200 test_clone_with_credentials(repo=sys.argv[1], method='clone',
197 201 seq=seq)
198 202 s = time.time()
199 for i in range(int(sys.argv[2])):
203 for i in range(1, int(sys.argv[2]) + 1):
200 204 print 'take', i
201 205 test_clone_with_credentials(repo=sys.argv[1], method=METHOD,
202 206 seq=seq)
203 207 print 'time taken %.3f' % (time.time() - s)
204 208 except Exception, e:
205 209 raise
206 210 sys.exit('stop on %s' % e)
@@ -1,47 +1,62 b''
1 1 from rhodecode.tests import *
2 2 from rhodecode.model.db import Repository
3 3 from rhodecode.lib.utils import invalidate_cache
4 4
5
5 6 class TestSummaryController(TestController):
6 7
7 8 def test_index(self):
8 9 self.log_user()
10 ID = Repository.get_by_repo_name(HG_REPO).repo_id
9 11 response = self.app.get(url(controller='summary',
10 action='index', repo_name=HG_REPO))
12 action='index',
13 repo_name=HG_REPO))
11 14
12 15 #repo type
13 self.assertTrue("""<img style="margin-bottom:2px" class="icon" """
16 response.mustcontain("""<img style="margin-bottom:2px" class="icon" """
14 17 """title="Mercurial repository" alt="Mercurial """
15 """repository" src="/images/icons/hgicon.png"/>"""
16 in response.body)
17 self.assertTrue("""<img style="margin-bottom:2px" class="icon" """
18 """repository" src="/images/icons/hgicon.png"/>""")
19 response.mustcontain("""<img style="margin-bottom:2px" class="icon" """
18 20 """title="public repository" alt="public """
19 """repository" src="/images/icons/lock_open.png"/>"""
20 in response.body)
21 """repository" src="/images/icons/lock_open.png"/>""")
21 22
22 23 #codes stats
23 24 self._enable_stats()
24 25
25
26 26 invalidate_cache('get_repo_cached_%s' % HG_REPO)
27 27 response = self.app.get(url(controller='summary', action='index',
28 28 repo_name=HG_REPO))
29 29
30 30 self.assertTrue("""var data = {"py": {"count": 42, "desc": """
31 31 """["Python"]}, "rst": {"count": 11, "desc": """
32 32 """["Rst"]}, "sh": {"count": 2, "desc": ["Bash"]}, """
33 33 """"makefile": {"count": 1, "desc": ["Makefile", """
34 34 """"Makefile"]}, "cfg": {"count": 1, "desc": ["Ini"]},"""
35 35 """ "css": {"count": 1, "desc": ["Css"]}, "bat": """
36 36 """{"count": 1, "desc": ["Batch"]}};"""
37 37 in response.body)
38 38
39 39 # clone url...
40 self.assertTrue("""<input type="text" id="clone_url" readonly="readonly" value="http://test_admin@localhost:80/%s" size="70"/>""" % HG_REPO in response.body)
40 response.mustcontain("""<input style="width:80%;margin-left:105px" type="text" id="clone_url" readonly="readonly" value="http://test_admin@localhost:80/vcs_test_hg"/>""")
41 response.mustcontain("""<input style="display:none;width:80%;margin-left:105px" type="text" id="clone_url_id" readonly="readonly" value="http://test_admin@localhost:80/_1"/>""")
41 42
43 def test_index_by_id(self):
44 self.log_user()
45 ID = Repository.get_by_repo_name(HG_REPO).repo_id
46 response = self.app.get(url(controller='summary',
47 action='index',
48 repo_name='_%s' % ID))
49
50 #repo type
51 response.mustcontain("""<img style="margin-bottom:2px" class="icon" """
52 """title="Mercurial repository" alt="Mercurial """
53 """repository" src="/images/icons/hgicon.png"/>""")
54 response.mustcontain("""<img style="margin-bottom:2px" class="icon" """
55 """title="public repository" alt="public """
56 """repository" src="/images/icons/lock_open.png"/>""")
42 57
43 58 def _enable_stats(self):
44 59 r = Repository.get_by_repo_name(HG_REPO)
45 60 r.enable_statistics = True
46 61 self.Session.add(r)
47 62 self.Session.commit()
General Comments 0
You need to be logged in to leave comments. Login now