# HG changeset patch # User Marcin Kuzminski # Date 1338924143 -7200 # Node ID 91fae60bf2b6f9803df3a7a6b64cd61da2f4d0c1 # Parent 9d61aad859bca53987ab35dc709beb8adf00cdc0# Parent b0d09c20f608196c925b323967ffd3efc9c6fb81 merge with beta diff -r 9d61aad859bc -r 91fae60bf2b6 .hgignore --- a/.hgignore Wed May 30 23:12:24 2012 +0200 +++ b/.hgignore Tue Jun 05 21:22:23 2012 +0200 @@ -19,3 +19,4 @@ ^RhodeCode\.egg-info$ ^rc\.ini$ ^fabfile.py +^\.rhodecode$ diff -r 9d61aad859bc -r 91fae60bf2b6 docs/api/api.rst --- a/docs/api/api.rst Wed May 30 23:12:24 2012 +0200 +++ b/docs/api/api.rst Tue Jun 05 21:22:23 2012 +0200 @@ -59,6 +59,47 @@ calling api *error* key from response will contain failure description and result will be null. + +API CLIENT +++++++++++ + +From version 1.4 RhodeCode adds a binary script that allows to easily +communicate with API. After installing RhodeCode a `rhodecode-api` script +will be available. + +To get started quickly simply run:: + + rhodecode-api _create_config --apikey= --apihost= + +This will create a file named .config in the directory you executed it storing +json config file with credentials. You can skip this step and always provide +both of the arguments to be able to communicate with server + + +after that simply run any api command for example get_repo:: + + rhodecode-api get_repo + + calling {"api_key": "", "id": 75, "args": {}, "method": "get_repo"} to http://127.0.0.1:5000 + rhodecode said: + {'error': 'Missing non optional `repoid` arg in JSON DATA', + 'id': 75, + 'result': None} + +Ups looks like we forgot to add an argument + +Let's try again now giving the repoid as parameters:: + + rhodecode-api get_repo repoid:rhodecode + + calling {"api_key": "", "id": 39, "args": {"repoid": "rhodecode"}, "method": "get_repo"} to http://127.0.0.1:5000 + rhodecode said: + {'error': None, + 'id': 39, + 'result': } + + + API METHODS +++++++++++ @@ -187,7 +228,18 @@ result: { "id" : "", - "msg" : "created new user " + "msg" : "created new user ", + "user": { + "id" : "", + "username" : "", + "firstname": "", + "lastname" : "", + "email" : "", + "active" : "", + "admin" :  "", + "ldap_dn" : "", + "last_login": "", + }, } error: null @@ -195,7 +247,7 @@ update_user ----------- -updates current one if such user exists. This command can +updates given user if such user exists. This command can be executed only using api_key belonging to user with admin rights. @@ -220,7 +272,33 @@ result: { "id" : "", - "msg" : "updated user " + "msg" : "updated user ID: " + } + error: null + + +delete_user +----------- + + +deletes givenuser if such user exists. This command can +be executed only using api_key belonging to user with admin rights. + + +INPUT:: + + id : + api_key : "" + method : "delete_user" + args : { + "userid" : "", + } + +OUTPUT:: + + result: { + "id" : "", + "msg" : "deleted user ID: " } error: null @@ -534,6 +612,15 @@ result: { "id": "", "msg": "Created new repository ", + "repo": { + "id" : "", + "repo_name" : "" + "type" : "", + "description" : "", + "clone_uri" : "", + "private": : "", + "created_on" : "", + }, } error: null diff -r 9d61aad859bc -r 91fae60bf2b6 docs/changelog.rst --- a/docs/changelog.rst Wed May 30 23:12:24 2012 +0200 +++ b/docs/changelog.rst Tue Jun 05 21:22:23 2012 +0200 @@ -18,6 +18,13 @@ their accounts - changed setup-app into setup-rhodecode and added default options to it. - new git repos are created as bare now by default +- #464 added links to groups in permission box +- #465 mentions autocomplete inside comments boxes +- #469 added --update-only option to whoosh to re-index only given list + of repos in index +- rhodecode-api CLI client +- new git http protocol replaced buggy dulwich implementation. + Now based on pygrack & gitweb fixes +++++ diff -r 9d61aad859bc -r 91fae60bf2b6 requires.txt --- a/requires.txt Wed May 30 23:12:24 2012 +0200 +++ b/requires.txt Tue Jun 05 21:22:23 2012 +0200 @@ -13,5 +13,6 @@ webob==1.0.8 markdown==2.1.1 docutils==0.8.1 +simplejson==2.5.2 py-bcrypt -mercurial>=2.2.1,<2.3 \ No newline at end of file +mercurial>=2.2.2,<2.3 \ No newline at end of file diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/__init__.py --- a/rhodecode/__init__.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/__init__.py Tue Jun 05 21:22:23 2012 +0200 @@ -72,10 +72,10 @@ requirements.append("pysqlite") if is_windows: - requirements.append("mercurial>=2.2.1,<2.3") + requirements.append("mercurial>=2.2.2,<2.3") else: requirements.append("py-bcrypt") - requirements.append("mercurial>=2.2.1,<2.3") + requirements.append("mercurial>=2.2.2,<2.3") def get_version(): diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/bin/__init__.py diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/bin/rhodecode_api.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rhodecode/bin/rhodecode_api.py Tue Jun 05 21:22:23 2012 +0200 @@ -0,0 +1,230 @@ +# -*- coding: utf-8 -*- +""" + rhodecode.bin.backup_manager + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Api CLI client for RhodeCode + + :created_on: Jun 3, 2012 + :author: marcink + :copyright: (C) 2010-2012 Marcin Kuzminski + :license: GPLv3, see COPYING for more details. +""" +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import with_statement +import os +import sys +import random +import urllib2 +import pprint +import argparse + +try: + from rhodecode.lib.ext_json import json +except ImportError: + try: + import simplejson as json + except ImportError: + import json + + +CONFIG_NAME = '.rhodecode' +FORMAT_PRETTY = 'pretty' +FORMAT_JSON = 'json' + + +class RcConf(object): + """ + RhodeCode config for API + + conf = RcConf() + conf['key'] + + """ + + def __init__(self, autoload=True, autocreate=False, config=None): + self._conf_name = CONFIG_NAME + self._conf = {} + if autocreate: + self.make_config(config) + if autoload: + self._conf = self.load_config() + + def __getitem__(self, key): + return self._conf[key] + + def __nonzero__(self): + if self._conf: + return True + return False + + def __eq__(self): + return self._conf.__eq__() + + def __repr__(self): + return 'RcConf<%s>' % self._conf.__repr__() + + def make_config(self, config): + """ + Saves given config as a JSON dump in the _conf_name location + + :param config: + :type config: + """ + with open(self._conf_name, 'wb') as f: + json.dump(config, f, indent=4) + sys.stdout.write('Updated conf\n') + + def update_config(self, new_config): + """ + Reads the JSON config updates it's values with new_config and + saves it back as JSON dump + + :param new_config: + """ + config = {} + try: + with open(self._conf_name, 'rb') as conf: + config = json.load(conf) + except IOError, e: + sys.stderr.write(str(e) + '\n') + + config.update(new_config) + self.make_config(config) + + def load_config(self): + """ + Loads config from file and returns loaded JSON object + """ + try: + with open(self._conf_name, 'rb') as conf: + return json.load(conf) + except IOError, e: + #sys.stderr.write(str(e) + '\n') + pass + + +def api_call(apikey, apihost, format, method=None, **kw): + """ + Api_call wrapper for RhodeCode + + :param apikey: + :param apihost: + :param format: formatting, pretty means prints and pprint of json + json returns unparsed json + :param method: + """ + def _build_data(random_id): + """ + Builds API data with given random ID + + :param random_id: + :type random_id: + """ + return { + "id": random_id, + "api_key": apikey, + "method": method, + "args": kw + } + + if not method: + raise Exception('please specify method name !') + id_ = random.randrange(1, 200) + req = urllib2.Request('%s/_admin/api' % apihost, + data=json.dumps(_build_data(id_)), + headers={'content-type': 'text/plain'}) + if format == FORMAT_PRETTY: + sys.stdout.write('calling %s to %s \n' % (req.get_data(), apihost)) + ret = urllib2.urlopen(req) + raw_json = ret.read() + json_data = json.loads(raw_json) + id_ret = json_data['id'] + _formatted_json = pprint.pformat(json_data) + if id_ret == id_: + if format == FORMAT_JSON: + sys.stdout.write(str(raw_json)) + else: + sys.stdout.write('rhodecode returned:\n%s\n' % (_formatted_json)) + + else: + raise Exception('something went wrong. ' + 'ID mismatch got %s, expected %s | %s' % ( + id_ret, id_, _formatted_json)) + + +def argparser(argv): + usage = ("rhodecode_api [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] " + "_create_config or METHOD ...") + + parser = argparse.ArgumentParser(description='RhodeCode API cli', + usage=usage) + + ## config + group = parser.add_argument_group('config') + group.add_argument('--apikey', help='api access key') + group.add_argument('--apihost', help='api host') + + group = parser.add_argument_group('API') + group.add_argument('method', metavar='METHOD', type=str, + help='API method name to call followed by key:value attributes', + ) + group.add_argument('--format', dest='format', type=str, + help='output format default: `pretty` can ' + 'be also `%s`' % FORMAT_JSON, + default=FORMAT_PRETTY + ) + args, other = parser.parse_known_args() + return parser, args, other + + +def main(argv=None): + """ + Main execution function for cli + + :param argv: + :type argv: + """ + if argv is None: + argv = sys.argv + + conf = None + parser, args, other = argparser(argv) + + api_credentials_given = (args.apikey and args.apihost) + if args.method == '_create_config': + if not api_credentials_given: + raise parser.error('_create_config requires --apikey and --apihost') + conf = RcConf(autocreate=True, config={'apikey': args.apikey, + 'apihost': args.apihost}) + sys.stdout.write('Create new config in %s\n' % CONFIG_NAME) + + if not conf: + conf = RcConf(autoload=True) + if not conf: + if not api_credentials_given: + parser.error('Could not find config file and missing ' + '--apikey or --apihost in params') + + apikey = args.apikey or conf['apikey'] + host = args.apihost or conf['apihost'] + method = args.method + margs = dict(map(lambda s: s.split(':', 1), other)) + + api_call(apikey, host, args.format, method, **margs) + return 0 + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/bin/rhodecode_backup.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rhodecode/bin/rhodecode_backup.py Tue Jun 05 21:22:23 2012 +0200 @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +""" + rhodecode.bin.backup_manager + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Repositories backup manager, it allows to backups all + repositories and send it to backup server using RSA key via ssh. + + :created_on: Feb 28, 2010 + :author: marcink + :copyright: (C) 2010-2012 Marcin Kuzminski + :license: GPLv3, see COPYING for more details. +""" +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import sys + +import logging +import tarfile +import datetime +import subprocess + +logging.basicConfig(level=logging.DEBUG, + format="%(asctime)s %(levelname)-5.5s %(message)s") + + +class BackupManager(object): + def __init__(self, repos_location, rsa_key, backup_server): + today = datetime.datetime.now().weekday() + 1 + self.backup_file_name = "rhodecode_repos.%s.tar.gz" % today + + self.id_rsa_path = self.get_id_rsa(rsa_key) + self.repos_path = self.get_repos_path(repos_location) + self.backup_server = backup_server + + self.backup_file_path = '/tmp' + + logging.info('starting backup for %s', self.repos_path) + logging.info('backup target %s', self.backup_file_path) + + def get_id_rsa(self, rsa_key): + if not os.path.isfile(rsa_key): + logging.error('Could not load id_rsa key file in %s', rsa_key) + sys.exit() + return rsa_key + + def get_repos_path(self, path): + if not os.path.isdir(path): + logging.error('Wrong location for repositories in %s', path) + sys.exit() + return path + + def backup_repos(self): + bckp_file = os.path.join(self.backup_file_path, self.backup_file_name) + tar = tarfile.open(bckp_file, "w:gz") + + for dir_name in os.listdir(self.repos_path): + logging.info('backing up %s', dir_name) + tar.add(os.path.join(self.repos_path, dir_name), dir_name) + tar.close() + logging.info('finished backup of mercurial repositories') + + def transfer_files(self): + params = { + 'id_rsa_key': self.id_rsa_path, + 'backup_file': os.path.join(self.backup_file_path, + self.backup_file_name), + 'backup_server': self.backup_server + } + cmd = ['scp', '-l', '40000', '-i', '%(id_rsa_key)s' % params, + '%(backup_file)s' % params, + '%(backup_server)s' % params] + + subprocess.call(cmd) + logging.info('Transfered file %s to %s', self.backup_file_name, cmd[4]) + + def rm_file(self): + logging.info('Removing file %s', self.backup_file_name) + os.remove(os.path.join(self.backup_file_path, self.backup_file_name)) + +if __name__ == "__main__": + + repo_location = '/home/repo_path' + backup_server = 'root@192.168.1.100:/backups/mercurial' + rsa_key = '/home/id_rsa' + + B_MANAGER = BackupManager(repo_location, rsa_key, backup_server) + B_MANAGER.backup_repos() + B_MANAGER.transfer_files() + B_MANAGER.rm_file() diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/config/routing.py --- a/rhodecode/config/routing.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/config/routing.py Tue Jun 05 21:22:23 2012 +0200 @@ -217,7 +217,7 @@ m.connect("user_emails_delete", "/users_emails/{id}", action="delete_email", conditions=dict(method=["DELETE"])) - #ADMIN USERS REST ROUTES + #ADMIN USERS GROUPS REST ROUTES with rmap.submapper(path_prefix=ADMIN_PREFIX, controller='admin/users_groups') as m: m.connect("users_groups", "/users_groups", @@ -346,10 +346,17 @@ rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX, controller='journal', action="public_journal") - rmap.connect('public_journal_rss', '%s/public_journal_rss' % ADMIN_PREFIX, + rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX, + controller='journal', action="public_journal_rss") + + rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX, controller='journal', action="public_journal_rss") rmap.connect('public_journal_atom', + '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal', + action="public_journal_atom") + + rmap.connect('public_journal_atom_old', '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal', action="public_journal_atom") diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/admin/repos.py --- a/rhodecode/controllers/admin/repos.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/admin/repos.py Tue Jun 05 21:22:23 2012 +0200 @@ -151,10 +151,12 @@ if request.POST.get('user_created'): # created by regular non admin user action_logger(self.rhodecode_user, 'user_created_repo', - form_result['repo_name_full'], '', self.sa) + form_result['repo_name_full'], self.ip_addr, + self.sa) else: action_logger(self.rhodecode_user, 'admin_created_repo', - form_result['repo_name_full'], '', self.sa) + form_result['repo_name_full'], self.ip_addr, + self.sa) Session.commit() except formencode.Invalid, errors: @@ -212,7 +214,7 @@ category='success') changed_name = repo.repo_name action_logger(self.rhodecode_user, 'admin_updated_repo', - changed_name, '', self.sa) + changed_name, self.ip_addr, self.sa) Session.commit() except formencode.Invalid, errors: defaults = self.__load_data(repo_name) @@ -253,7 +255,7 @@ return redirect(url('repos')) try: action_logger(self.rhodecode_user, 'admin_deleted_repo', - repo_name, '', self.sa) + repo_name, self.ip_addr, self.sa) repo_model.delete(repo) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('deleted repository %s') % repo_name, category='success') diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/admin/users.py --- a/rhodecode/controllers/admin/users.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/admin/users.py Tue Jun 05 21:22:23 2012 +0200 @@ -42,6 +42,7 @@ from rhodecode.model.forms import UserForm from rhodecode.model.user import UserModel from rhodecode.model.meta import Session +from rhodecode.lib.utils import action_logger log = logging.getLogger(__name__) @@ -76,10 +77,12 @@ try: form_result = user_form.to_python(dict(request.POST)) user_model.create(form_result) - h.flash(_('created user %s') % form_result['username'], + usr = form_result['username'] + action_logger(self.rhodecode_user, 'admin_created_user:%s' % usr, + None, self.ip_addr, self.sa) + h.flash(_('created user %s') % usr, category='success') Session.commit() - #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa) except formencode.Invalid, errors: return htmlfill.render( render('admin/users/user_add.html'), @@ -115,6 +118,9 @@ try: form_result = _form.to_python(dict(request.POST)) user_model.update(id, form_result) + usr = form_result['username'] + action_logger(self.rhodecode_user, 'admin_updated_user:%s' % usr, + None, self.ip_addr, self.sa) h.flash(_('User updated successfully'), category='success') Session.commit() except formencode.Invalid, errors: diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/admin/users_groups.py --- a/rhodecode/controllers/admin/users_groups.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/admin/users_groups.py Tue Jun 05 21:22:23 2012 +0200 @@ -43,6 +43,7 @@ from rhodecode.model.db import User, UsersGroup, Permission, UsersGroupToPerm from rhodecode.model.forms import UsersGroupForm from rhodecode.model.meta import Session +from rhodecode.lib.utils import action_logger log = logging.getLogger(__name__) @@ -76,9 +77,11 @@ form_result = users_group_form.to_python(dict(request.POST)) UsersGroupModel().create(name=form_result['users_group_name'], active=form_result['users_group_active']) - h.flash(_('created users group %s') \ - % form_result['users_group_name'], category='success') - #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa) + gr = form_result['users_group_name'] + action_logger(self.rhodecode_user, + 'admin_created_users_group:%s' % gr, + None, self.ip_addr, self.sa) + h.flash(_('created users group %s') % gr, category='success') Session.commit() except formencode.Invalid, errors: return htmlfill.render( @@ -125,10 +128,11 @@ try: form_result = users_group_form.to_python(request.POST) UsersGroupModel().update(c.users_group, form_result) - h.flash(_('updated users group %s') \ - % form_result['users_group_name'], - category='success') - #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa) + gr = form_result['users_group_name'] + action_logger(self.rhodecode_user, + 'admin_updated_users_group:%s' % gr, + None, self.ip_addr, self.sa) + h.flash(_('updated users group %s') % gr, category='success') Session.commit() except formencode.Invalid, errors: e = errors.error_dict or {} diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/api/__init__.py --- a/rhodecode/controllers/api/__init__.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/api/__init__.py Tue Jun 05 21:22:23 2012 +0200 @@ -57,15 +57,16 @@ return str(self.message) -def jsonrpc_error(message, code=None): +def jsonrpc_error(message, retid=None, code=None): """ Generate a Response object with a JSON-RPC error body """ from pylons.controllers.util import Response - resp = Response(body=json.dumps(dict(id=None, result=None, error=message)), - status=code, - content_type='application/json') - return resp + return Response( + body=json.dumps(dict(id=retid, result=None, error=message)), + status=code, + content_type='application/json' + ) class JSONRPCController(WSGIController): @@ -94,9 +95,11 @@ Parse the request body as JSON, look up the method on the controller and if it exists, dispatch to it. """ + self._req_id = None if 'CONTENT_LENGTH' not in environ: log.debug("No Content-Length") - return jsonrpc_error(message="No Content-Length in request") + return jsonrpc_error(retid=self._req_id, + message="No Content-Length in request") else: length = environ['CONTENT_LENGTH'] or 0 length = int(environ['CONTENT_LENGTH']) @@ -104,7 +107,8 @@ if length == 0: log.debug("Content-Length is 0") - return jsonrpc_error(message="Content-Length is 0") + return jsonrpc_error(retid=self._req_id, + message="Content-Length is 0") raw_body = environ['wsgi.input'].read(length) @@ -112,7 +116,8 @@ json_body = json.loads(urllib.unquote_plus(raw_body)) except ValueError, e: # catch JSON errors Here - return jsonrpc_error(message="JSON parse error ERR:%s RAW:%r" \ + return jsonrpc_error(retid=self._req_id, + message="JSON parse error ERR:%s RAW:%r" \ % (e, urllib.unquote_plus(raw_body))) # check AUTH based on API KEY @@ -126,22 +131,26 @@ self._request_params) ) except KeyError, e: - return jsonrpc_error(message='Incorrect JSON query missing %s' % e) + return jsonrpc_error(retid=self._req_id, + message='Incorrect JSON query missing %s' % e) # check if we can find this session using api_key try: u = User.get_by_api_key(self._req_api_key) if u is None: - return jsonrpc_error(message='Invalid API KEY') + return jsonrpc_error(retid=self._req_id, + message='Invalid API KEY') auth_u = AuthUser(u.user_id, self._req_api_key) except Exception, e: - return jsonrpc_error(message='Invalid API KEY') + return jsonrpc_error(retid=self._req_id, + message='Invalid API KEY') self._error = None try: self._func = self._find_method() except AttributeError, e: - return jsonrpc_error(message=str(e)) + return jsonrpc_error(retid=self._req_id, + message=str(e)) # now that we have a method, add self._req_params to # self.kargs and dispatch control to WGIController @@ -164,9 +173,12 @@ USER_SESSION_ATTR = 'apiuser' if USER_SESSION_ATTR not in arglist: - return jsonrpc_error(message='This method [%s] does not support ' - 'authentication (missing %s param)' % - (self._func.__name__, USER_SESSION_ATTR)) + return jsonrpc_error( + retid=self._req_id, + message='This method [%s] does not support ' + 'authentication (missing %s param)' % ( + self._func.__name__, USER_SESSION_ATTR) + ) # get our arglist and check if we provided them as args for arg, default in func_kwargs.iteritems(): @@ -179,6 +191,7 @@ # NotImplementedType (default_empty) if (default == default_empty and arg not in self._request_params): return jsonrpc_error( + retid=self._req_id, message=( 'Missing non optional `%s` arg in JSON DATA' % arg ) diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/api/api.py --- a/rhodecode/controllers/api/api.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/api/api.py Tue Jun 05 21:22:23 2012 +0200 @@ -156,14 +156,25 @@ password = PasswordGenerator().gen_password(length=8) try: - usr = UserModel().create_or_update( + user = UserModel().create_or_update( username, password, email, firstname, lastname, active, admin, ldap_dn ) Session.commit() return dict( - id=usr.user_id, - msg='created new user %s' % username + id=user.user_id, + msg='created new user %s' % username, + user=dict( + id=user.user_id, + username=user.username, + firstname=user.name, + lastname=user.lastname, + email=user.email, + active=user.active, + admin=user.admin, + ldap_dn=user.ldap_dn, + last_login=user.last_login, + ) ) except Exception: log.error(traceback.format_exc()) @@ -185,8 +196,9 @@ :param admin: :param ldap_dn: """ - if not UserModel().get_user(userid): - raise JSONRPCError("user %s does not exist" % username) + usr = UserModel().get_user(userid) + if not usr: + raise JSONRPCError("user ID:%s does not exist" % userid) try: usr = UserModel().create_or_update( @@ -196,11 +208,34 @@ Session.commit() return dict( id=usr.user_id, - msg='updated user %s' % username + msg='updated user ID:%s %s' % (usr.user_id, usr.username) ) except Exception: log.error(traceback.format_exc()) - raise JSONRPCError('failed to update user %s' % username) + raise JSONRPCError('failed to update user %s' % userid) + + @HasPermissionAllDecorator('hg.admin') + def delete_user(self, apiuser, userid): + """" + Deletes an user + + :param apiuser: + """ + usr = UserModel().get_user(userid) + if not usr: + raise JSONRPCError("user ID:%s does not exist" % userid) + + try: + UserModel().delete(userid) + Session.commit() + return dict( + id=usr.user_id, + msg='deleted user ID:%s %s' % (usr.user_id, usr.username) + ) + except Exception: + log.error(traceback.format_exc()) + raise JSONRPCError('failed to delete ID:%s %s' % (usr.user_id, + usr.username)) @HasPermissionAllDecorator('hg.admin') def get_users_group(self, apiuser, group_name): @@ -354,7 +389,7 @@ repo = RepoModel().get_repo(repoid) if repo is None: - raise JSONRPCError('unknown repository %s' % repo) + raise JSONRPCError('unknown repository "%s"' % (repo or repoid)) members = [] for user in repo.repo_to_perm: @@ -486,14 +521,22 @@ repo_type=repo_type, repo_group=group.group_id if group else None, clone_uri=clone_uri - ), - owner + ) ) Session.commit() return dict( id=repo.repo_id, - msg="Created new repository %s" % repo.repo_name + msg="Created new repository %s" % (repo.repo_name), + repo=dict( + id=repo.repo_id, + repo_name=repo.repo_name, + type=repo.repo_type, + clone_uri=repo.clone_uri, + private=repo.private, + created_on=repo.created_on, + description=repo.description, + ) ) except Exception: @@ -501,6 +544,15 @@ raise JSONRPCError('failed to create repository %s' % repo_name) @HasPermissionAnyDecorator('hg.admin') + def fork_repo(self, apiuser, repoid): + repo = RepoModel().get_repo(repoid) + if repo is None: + raise JSONRPCError('unknown repository "%s"' % (repo or repoid)) + + RepoModel().create_fork(form_data, cur_user) + + + @HasPermissionAnyDecorator('hg.admin') def delete_repo(self, apiuser, repo_name): """ Deletes a given repository diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/changelog.py --- a/rhodecode/controllers/changelog.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/changelog.py Tue Jun 05 21:22:23 2012 +0200 @@ -26,7 +26,6 @@ import logging import traceback -from mercurial import graphmod from pylons import request, url, session, tmpl_context as c from pylons.controllers.util import redirect from pylons.i18n.translation import _ @@ -36,9 +35,8 @@ from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.helpers import RepoPage from rhodecode.lib.compat import json - +from rhodecode.lib.graphmod import _colored, _dagwalker from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetDoesNotExistError -from rhodecode.model.db import Repository log = logging.getLogger(__name__) @@ -118,18 +116,9 @@ data = [] revs = [x.revision for x in collection] - if repo.alias == 'git': - for _ in revs: - vtx = [0, 1] - edges = [[0, 0, 1]] - data.append(['', vtx, edges]) - - elif repo.alias == 'hg': - dag = graphmod.dagwalker(repo._repo, revs) - c.dag = graphmod.colored(dag, repo._repo) - for (id, type, ctx, vtx, edges) in c.dag: - if type != graphmod.CHANGESET: - continue - data.append(['', vtx, edges]) + dag = _dagwalker(repo, revs, repo.alias) + dag = _colored(dag) + for (id, type, ctx, vtx, edges) in dag: + data.append(['', vtx, edges]) c.jsdata = json.dumps(data) diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/changeset.py --- a/rhodecode/controllers/changeset.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/changeset.py Tue Jun 05 21:22:23 2012 +0200 @@ -40,7 +40,7 @@ import rhodecode.lib.helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.base import BaseRepoController, render -from rhodecode.lib.utils import EmptyChangeset +from rhodecode.lib.utils import EmptyChangeset, action_logger from rhodecode.lib.compat import OrderedDict from rhodecode.lib import diffs from rhodecode.model.db import ChangesetComment, ChangesetStatus @@ -48,6 +48,7 @@ from rhodecode.model.changeset_status import ChangesetStatusModel from rhodecode.model.meta import Session from rhodecode.lib.diffs import wrapped_diff +from rhodecode.model.repo import RepoModel log = logging.getLogger(__name__) @@ -166,6 +167,9 @@ def __before__(self): super(ChangesetController, self).__before__() c.affected_files_cut_off = 60 + repo_model = RepoModel() + c.users_array = repo_model.get_users_js() + c.users_groups_array = repo_model.get_users_groups_js() def index(self, revision): @@ -391,8 +395,12 @@ c.rhodecode_user.user_id, comm, ) + action_logger(self.rhodecode_user, + 'user_commented_revision:%s' % revision, + c.rhodecode_db_repo, self.ip_addr, self.sa) Session.commit() + if not request.environ.get('HTTP_X_PARTIAL_XHR'): return redirect(h.url('changeset_home', repo_name=repo_name, revision=revision)) diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/feed.py --- a/rhodecode/controllers/feed.py Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/controllers/feed.py Tue Jun 05 21:22:23 2012 +0200 @@ -28,11 +28,12 @@ from pylons import url, response, tmpl_context as c from pylons.i18n.translation import _ -from rhodecode.lib.utils2 import safe_unicode +from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed + +from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.base import BaseRepoController - -from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed +from rhodecode.lib.diffs import DiffProcessor log = logging.getLogger(__name__) @@ -49,31 +50,36 @@ self.title = self.title = _('%s %s feed') % (c.rhodecode_name, '%s') self.language = 'en-us' self.ttl = "5" - self.feed_nr = 10 + self.feed_nr = 20 def _get_title(self, cs): - return "R%s:%s - %s" % ( - cs.revision, cs.short_id, cs.message + return "%s" % ( + h.shorter(cs.message, 160) ) def __changes(self, cs): changes = [] - a = [safe_unicode(n.path) for n in cs.added] - if a: - changes.append('\nA ' + '\nA '.join(a)) - - m = [safe_unicode(n.path) for n in cs.changed] - if m: - changes.append('\nM ' + '\nM '.join(m)) + diffprocessor = DiffProcessor(cs.diff()) + stats = diffprocessor.prepare(inline_diff=False) + for st in stats: + st.update({'added': st['stats'][0], + 'removed': st['stats'][1]}) + changes.append('\n %(operation)s %(filename)s ' + '(%(added)s lines added, %(removed)s lines removed)' + % st) + return changes - d = [safe_unicode(n.path) for n in cs.removed] - if d: - changes.append('\nD ' + '\nD '.join(d)) - - changes.append('') - - return ''.join(changes) + def __get_desc(self, cs): + desc_msg = [] + desc_msg.append('%s %s %s:
' % (cs.author, _('commited on'), + cs.date)) + desc_msg.append('
')
+        desc_msg.append(cs.message)
+        desc_msg.append('\n')
+        desc_msg.extend(self.__changes(cs))
+        desc_msg.append('
') + return desc_msg def atom(self, repo_name): """Produce an atom-1.0 feed via feedgenerator module""" @@ -87,15 +93,13 @@ ) for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])): - desc_msg = [] - desc_msg.append('%s - %s
' % (cs.author, cs.date))
-            desc_msg.append(self.__changes(cs))
-
             feed.add_item(title=self._get_title(cs),
                           link=url('changeset_home', repo_name=repo_name,
                                    revision=cs.raw_id, qualified=True),
                           author_name=cs.author,
-                          description=''.join(desc_msg))
+                          description=''.join(self.__get_desc(cs)),
+                          pubdate=cs.date,
+                          )
 
         response.content_type = feed.mime_type
         return feed.writeString('utf-8')
@@ -112,15 +116,12 @@
         )
 
         for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])):
-            desc_msg = []
-            desc_msg.append('%s - %s
' % (cs.author, cs.date))
-            desc_msg.append(self.__changes(cs))
-
             feed.add_item(title=self._get_title(cs),
                           link=url('changeset_home', repo_name=repo_name,
                                    revision=cs.raw_id, qualified=True),
                           author_name=cs.author,
-                          description=''.join(desc_msg),
+                          description=''.join(self.__get_desc(cs)),
+                          pubdate=cs.date,
                          )
 
         response.content_type = feed.mime_type
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/journal.py
--- a/rhodecode/controllers/journal.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/controllers/journal.py	Tue Jun 05 21:22:23 2012 +0200
@@ -192,9 +192,8 @@
                          ttl=self.ttl)
 
         for entry in journal[:self.feed_nr]:
-            #tmpl = h.action_parser(entry)[0]
-            action, action_extra = h.action_parser(entry, feed=True)
-            title = "%s - %s %s" % (entry.user.short_contact, action,
+            action, action_extra, ico = h.action_parser(entry, feed=True)
+            title = "%s - %s %s" % (entry.user.short_contact, action(),
                                  entry.repository.repo_name)
             desc = action_extra()
             feed.add_item(title=title,
@@ -226,9 +225,8 @@
                          ttl=self.ttl)
 
         for entry in journal[:self.feed_nr]:
-            #tmpl = h.action_parser(entry)[0]
-            action, action_extra = h.action_parser(entry, feed=True)
-            title = "%s - %s %s" % (entry.user.short_contact, action,
+            action, action_extra, ico = h.action_parser(entry, feed=True)
+            title = "%s - %s %s" % (entry.user.short_contact, action(),
                                  entry.repository.repo_name)
             desc = action_extra()
             feed.add_item(title=title,
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/controllers/settings.py
--- a/rhodecode/controllers/settings.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/controllers/settings.py	Tue Jun 05 21:22:23 2012 +0200
@@ -104,7 +104,7 @@
                     category='success')
             changed_name = form_result['repo_name_full']
             action_logger(self.rhodecode_user, 'user_updated_repo',
-                          changed_name, '', self.sa)
+                          changed_name, self.ip_addr, self.sa)
             Session.commit()
         except formencode.Invalid, errors:
             c.repo_info = repo_model.get_by_repo_name(repo_name)
@@ -145,7 +145,7 @@
             return redirect(url('home'))
         try:
             action_logger(self.rhodecode_user, 'user_deleted_repo',
-                              repo_name, '', self.sa)
+                              repo_name, self.ip_addr, self.sa)
             repo_model.delete(repo)
             invalidate_cache('get_repo_cached_%s' % repo_name)
             h.flash(_('deleted repository %s') % repo_name, category='success')
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/i18n/en/LC_MESSAGES/rhodecode.po
--- a/rhodecode/i18n/en/LC_MESSAGES/rhodecode.po	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/i18n/en/LC_MESSAGES/rhodecode.po	Tue Jun 05 21:22:23 2012 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: rhodecode 0.1\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2012-05-27 17:41+0200\n"
+"POT-Creation-Date: 2012-06-03 01:06+0200\n"
 "PO-Revision-Date: 2011-02-25 19:13+0100\n"
 "Last-Translator: FULL NAME \n"
 "Language-Team: en \n"
@@ -17,25 +17,25 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 0.9.6\n"
 
-#: rhodecode/controllers/changelog.py:96
+#: rhodecode/controllers/changelog.py:95
 msgid "All Branches"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:79
+#: rhodecode/controllers/changeset.py:80
 msgid "show white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:86 rhodecode/controllers/changeset.py:93
+#: rhodecode/controllers/changeset.py:87 rhodecode/controllers/changeset.py:94
 msgid "ignore white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:153
+#: rhodecode/controllers/changeset.py:154
 #, python-format
 msgid "%s line context"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:320
-#: rhodecode/controllers/changeset.py:335 rhodecode/lib/diffs.py:62
+#: rhodecode/controllers/changeset.py:324
+#: rhodecode/controllers/changeset.py:339 rhodecode/lib/diffs.py:62
 msgid "binary file"
 msgstr ""
 
@@ -181,7 +181,7 @@
 msgid "%s public journal %s feed"
 msgstr ""
 
-#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:224
+#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:223
 #: rhodecode/templates/admin/repos/repo_edit.html:177
 #: rhodecode/templates/base/base.html:307
 #: rhodecode/templates/base/base.html:309
@@ -216,19 +216,19 @@
 msgstr ""
 
 #: rhodecode/controllers/settings.py:103
-#: rhodecode/controllers/admin/repos.py:211
+#: rhodecode/controllers/admin/repos.py:213
 #, python-format
 msgid "Repository %s updated successfully"
 msgstr ""
 
 #: rhodecode/controllers/settings.py:121
-#: rhodecode/controllers/admin/repos.py:229
+#: rhodecode/controllers/admin/repos.py:231
 #, python-format
 msgid "error occurred during update of repository %s"
 msgstr ""
 
 #: rhodecode/controllers/settings.py:139
-#: rhodecode/controllers/admin/repos.py:247
+#: rhodecode/controllers/admin/repos.py:249
 #, python-format
 msgid ""
 "%s repository is not mapped to db perhaps it was moved or renamed  from "
@@ -237,14 +237,14 @@
 msgstr ""
 
 #: rhodecode/controllers/settings.py:151
-#: rhodecode/controllers/admin/repos.py:259
+#: rhodecode/controllers/admin/repos.py:261
 #, python-format
 msgid "deleted repository %s"
 msgstr ""
 
 #: rhodecode/controllers/settings.py:155
-#: rhodecode/controllers/admin/repos.py:269
-#: rhodecode/controllers/admin/repos.py:275
+#: rhodecode/controllers/admin/repos.py:271
+#: rhodecode/controllers/admin/repos.py:277
 #, python-format
 msgid "An error occurred during deletion of %s"
 msgstr ""
@@ -393,62 +393,62 @@
 msgid "created repository %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:177
+#: rhodecode/controllers/admin/repos.py:179
 #, python-format
 msgid "error occurred during creation of repository %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:264
+#: rhodecode/controllers/admin/repos.py:266
 #, python-format
 msgid "Cannot delete %s it still contains attached forks"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:293
+#: rhodecode/controllers/admin/repos.py:295
 msgid "An error occurred during deletion of repository user"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:312
+#: rhodecode/controllers/admin/repos.py:314
 msgid "An error occurred during deletion of repository users groups"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:329
+#: rhodecode/controllers/admin/repos.py:331
 msgid "An error occurred during deletion of repository stats"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:345
+#: rhodecode/controllers/admin/repos.py:347
 msgid "An error occurred during cache invalidation"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:365
+#: rhodecode/controllers/admin/repos.py:367
 msgid "Updated repository visibility in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:369
+#: rhodecode/controllers/admin/repos.py:371
 msgid "An error occurred during setting this repository in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:374 rhodecode/model/forms.py:54
+#: rhodecode/controllers/admin/repos.py:376 rhodecode/model/forms.py:54
 msgid "Token mismatch"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:387
-msgid "Pulled from remote location"
-msgstr ""
-
 #: rhodecode/controllers/admin/repos.py:389
+msgid "Pulled from remote location"
+msgstr ""
+
+#: rhodecode/controllers/admin/repos.py:391
 msgid "An error occurred during pull from remote location"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:405
-msgid "Nothing"
-msgstr ""
-
 #: rhodecode/controllers/admin/repos.py:407
+msgid "Nothing"
+msgstr ""
+
+#: rhodecode/controllers/admin/repos.py:409
 #, python-format
 msgid "Marked repo %s as fork of %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:411
+#: rhodecode/controllers/admin/repos.py:413
 msgid "An error occurred during this operation"
 msgstr ""
 
@@ -542,77 +542,77 @@
 msgid "You can't edit this user since it's crucial for entire application"
 msgstr ""
 
-#: rhodecode/controllers/admin/settings.py:365
+#: rhodecode/controllers/admin/settings.py:367
 msgid "Your account was updated successfully"
 msgstr ""
 
-#: rhodecode/controllers/admin/settings.py:384
-#: rhodecode/controllers/admin/users.py:132
+#: rhodecode/controllers/admin/settings.py:387
+#: rhodecode/controllers/admin/users.py:138
 #, python-format
 msgid "error occurred during update of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:79
+#: rhodecode/controllers/admin/users.py:83
 #, python-format
 msgid "created user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:92
+#: rhodecode/controllers/admin/users.py:95
 #, python-format
 msgid "error occurred during creation of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:118
+#: rhodecode/controllers/admin/users.py:124
 msgid "User updated successfully"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:149
+#: rhodecode/controllers/admin/users.py:155
 msgid "successfully deleted user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:154
+#: rhodecode/controllers/admin/users.py:160
 msgid "An error occurred during deletion of user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:169
+#: rhodecode/controllers/admin/users.py:175
 msgid "You can't edit this user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:199
-#: rhodecode/controllers/admin/users_groups.py:215
+#: rhodecode/controllers/admin/users.py:205
+#: rhodecode/controllers/admin/users_groups.py:219
 msgid "Granted 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:208
-#: rhodecode/controllers/admin/users_groups.py:225
+#: rhodecode/controllers/admin/users.py:214
+#: rhodecode/controllers/admin/users_groups.py:229
 msgid "Revoked 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:79
+#: rhodecode/controllers/admin/users_groups.py:84
 #, python-format
 msgid "created users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:92
+#: rhodecode/controllers/admin/users_groups.py:95
 #, python-format
 msgid "error occurred during creation of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:128
+#: rhodecode/controllers/admin/users_groups.py:135
 #, python-format
 msgid "updated users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:148
+#: rhodecode/controllers/admin/users_groups.py:152
 #, python-format
 msgid "error occurred during update of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:165
+#: rhodecode/controllers/admin/users_groups.py:169
 msgid "successfully deleted users group"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:170
+#: rhodecode/controllers/admin/users_groups.py:174
 msgid "An error occurred during deletion of users group"
 msgstr ""
 
@@ -670,60 +670,80 @@
 msgid "fork name "
 msgstr ""
 
-#: rhodecode/lib/helpers.py:540
+#: rhodecode/lib/helpers.py:550
 msgid "[deleted] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:541 rhodecode/lib/helpers.py:546
+#: rhodecode/lib/helpers.py:552 rhodecode/lib/helpers.py:562
 msgid "[created] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:542
-msgid "[created] repository as fork"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:543 rhodecode/lib/helpers.py:547
-msgid "[forked] repository"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:544 rhodecode/lib/helpers.py:548
-msgid "[updated] repository"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:545
-msgid "[delete] repository"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:549
-msgid "[pushed] into"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:550
-msgid "[committed via RhodeCode] into"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:551
-msgid "[pulled from remote] into"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:552
-msgid "[pulled] from"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:553
-msgid "[started following] repository"
-msgstr ""
-
 #: rhodecode/lib/helpers.py:554
+msgid "[created] repository as fork"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:556 rhodecode/lib/helpers.py:564
+msgid "[forked] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:558 rhodecode/lib/helpers.py:566
+msgid "[updated] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:560
+msgid "[delete] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:568
+msgid "[created] user"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:570
+msgid "[updated] user"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:572
+msgid "[created] users group"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:574
+msgid "[updated] users group"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:576
+msgid "[commented] on revision in repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:578
+msgid "[pushed] into"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:580
+msgid "[committed via RhodeCode] into repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:582
+msgid "[pulled from remote] into repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:584
+msgid "[pulled] from"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:586
+msgid "[started following] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:588
 msgid "[stopped following] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:732
+#: rhodecode/lib/helpers.py:752
 #, python-format
 msgid " and %s more"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:736
+#: rhodecode/lib/helpers.py:756
 msgid "No Files"
 msgstr ""
 
@@ -971,7 +991,7 @@
 msgstr ""
 
 #: rhodecode/templates/index_base.html:6
-#: rhodecode/templates/admin/users/user_edit_my_account.html:115
+#: rhodecode/templates/admin/users/user_edit_my_account.html:31
 #: rhodecode/templates/bookmarks/bookmarks.html:10
 #: rhodecode/templates/branches/branches.html:9
 #: rhodecode/templates/journal/journal.html:31
@@ -1026,10 +1046,10 @@
 #: rhodecode/templates/admin/repos/repo_edit.html:32
 #: rhodecode/templates/admin/repos/repos.html:36
 #: rhodecode/templates/admin/repos/repos.html:82
-#: rhodecode/templates/admin/users/user_edit_my_account.html:133
-#: rhodecode/templates/admin/users/user_edit_my_account.html:183
-#: rhodecode/templates/admin/users/user_edit_my_account.html:249
-#: rhodecode/templates/admin/users/user_edit_my_account.html:284
+#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account.html:99
+#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:200
 #: rhodecode/templates/bookmarks/bookmarks.html:36
 #: rhodecode/templates/bookmarks/bookmarks_data.html:6
 #: rhodecode/templates/branches/branches.html:36
@@ -1054,7 +1074,7 @@
 #: rhodecode/templates/index_base.html:161
 #: rhodecode/templates/admin/repos/repos.html:39
 #: rhodecode/templates/admin/repos/repos.html:87
-#: rhodecode/templates/admin/users/user_edit_my_account.html:251
+#: rhodecode/templates/admin/users/user_edit_my_account.html:167
 #: rhodecode/templates/journal/journal.html:179
 msgid "Tip"
 msgstr ""
@@ -1097,7 +1117,7 @@
 #: rhodecode/templates/index_base.html:148
 #: rhodecode/templates/index_base.html:188
 #: rhodecode/templates/admin/repos/repos.html:112
-#: rhodecode/templates/admin/users/user_edit_my_account.html:270
+#: rhodecode/templates/admin/users/user_edit_my_account.html:186
 #: rhodecode/templates/bookmarks/bookmarks.html:60
 #: rhodecode/templates/branches/branches.html:60
 #: rhodecode/templates/journal/journal.html:202
@@ -1108,7 +1128,7 @@
 #: rhodecode/templates/index_base.html:149
 #: rhodecode/templates/index_base.html:189
 #: rhodecode/templates/admin/repos/repos.html:113
-#: rhodecode/templates/admin/users/user_edit_my_account.html:271
+#: rhodecode/templates/admin/users/user_edit_my_account.html:187
 #: rhodecode/templates/bookmarks/bookmarks.html:61
 #: rhodecode/templates/branches/branches.html:61
 #: rhodecode/templates/journal/journal.html:203
@@ -1123,7 +1143,7 @@
 
 #: rhodecode/templates/index_base.html:190
 #: rhodecode/templates/admin/repos/repos.html:114
-#: rhodecode/templates/admin/users/user_edit_my_account.html:272
+#: rhodecode/templates/admin/users/user_edit_my_account.html:188
 #: rhodecode/templates/bookmarks/bookmarks.html:62
 #: rhodecode/templates/branches/branches.html:62
 #: rhodecode/templates/journal/journal.html:204
@@ -1133,7 +1153,7 @@
 
 #: rhodecode/templates/index_base.html:191
 #: rhodecode/templates/admin/repos/repos.html:115
-#: rhodecode/templates/admin/users/user_edit_my_account.html:273
+#: rhodecode/templates/admin/users/user_edit_my_account.html:189
 #: rhodecode/templates/bookmarks/bookmarks.html:63
 #: rhodecode/templates/branches/branches.html:63
 #: rhodecode/templates/journal/journal.html:205
@@ -1143,7 +1163,7 @@
 
 #: rhodecode/templates/index_base.html:192
 #: rhodecode/templates/admin/repos/repos.html:116
-#: rhodecode/templates/admin/users/user_edit_my_account.html:274
+#: rhodecode/templates/admin/users/user_edit_my_account.html:190
 #: rhodecode/templates/bookmarks/bookmarks.html:64
 #: rhodecode/templates/branches/branches.html:64
 #: rhodecode/templates/journal/journal.html:206
@@ -1163,7 +1183,7 @@
 #: rhodecode/templates/admin/admin_log.html:5
 #: rhodecode/templates/admin/users/user_add.html:32
 #: rhodecode/templates/admin/users/user_edit.html:50
-#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:26
 #: rhodecode/templates/base/base.html:83
 #: rhodecode/templates/summary/summary.html:113
 msgid "Username"
@@ -1223,21 +1243,21 @@
 #: rhodecode/templates/register.html:47
 #: rhodecode/templates/admin/users/user_add.html:59
 #: rhodecode/templates/admin/users/user_edit.html:86
-#: rhodecode/templates/admin/users/user_edit_my_account.html:76
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:53
 msgid "First Name"
 msgstr ""
 
 #: rhodecode/templates/register.html:56
 #: rhodecode/templates/admin/users/user_add.html:68
 #: rhodecode/templates/admin/users/user_edit.html:95
-#: rhodecode/templates/admin/users/user_edit_my_account.html:85
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:62
 msgid "Last Name"
 msgstr ""
 
 #: rhodecode/templates/register.html:65
 #: rhodecode/templates/admin/users/user_add.html:77
 #: rhodecode/templates/admin/users/user_edit.html:104
-#: rhodecode/templates/admin/users/user_edit_my_account.html:94
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:71
 #: rhodecode/templates/summary/summary.html:115
 msgid "Email"
 msgstr ""
@@ -1300,8 +1320,8 @@
 #: rhodecode/templates/admin/admin_log.html:6
 #: rhodecode/templates/admin/repos/repos.html:41
 #: rhodecode/templates/admin/repos/repos.html:90
-#: rhodecode/templates/admin/users/user_edit_my_account.html:135
-#: rhodecode/templates/admin/users/user_edit_my_account.html:136
+#: rhodecode/templates/admin/users/user_edit_my_account.html:51
+#: rhodecode/templates/admin/users/user_edit_my_account.html:52
 #: rhodecode/templates/journal/journal.html:52
 #: rhodecode/templates/journal/journal.html:53
 msgid "Action"
@@ -1324,7 +1344,7 @@
 msgid "From IP"
 msgstr ""
 
-#: rhodecode/templates/admin/admin_log.html:52
+#: rhodecode/templates/admin/admin_log.html:53
 msgid "No actions yet"
 msgstr ""
 
@@ -1405,7 +1425,7 @@
 #: rhodecode/templates/admin/settings/hooks.html:73
 #: rhodecode/templates/admin/users/user_edit.html:129
 #: rhodecode/templates/admin/users/user_edit.html:154
-#: rhodecode/templates/admin/users/user_edit_my_account.html:102
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:115
 #: rhodecode/templates/settings/repo_settings.html:84
 msgid "Save"
@@ -1557,7 +1577,7 @@
 
 #: rhodecode/templates/admin/repos/repo_edit.html:13
 #: rhodecode/templates/admin/users/user_edit.html:13
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:13
 #: rhodecode/templates/files/files_source.html:32
 #: rhodecode/templates/journal/journal.html:72
@@ -1715,38 +1735,27 @@
 msgstr ""
 
 #: rhodecode/templates/admin/repos/repo_edit_perms.html:33
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:53
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:58
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:23
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:42
 msgid "revoke"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:75
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:80
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:64
 msgid "Add another member"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:89
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:94
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:78
 msgid "Failed to remove user"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:104
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:109
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:93
 msgid "Failed to remove users group"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:123
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:112
-msgid "Group"
-msgstr ""
-
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:124
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:113
-#: rhodecode/templates/admin/users_groups/users_groups.html:33
-msgid "members"
-msgstr ""
-
 #: rhodecode/templates/admin/repos/repos.html:5
 msgid "Repositories administration"
 msgstr ""
@@ -1764,7 +1773,7 @@
 msgstr ""
 
 #: rhodecode/templates/admin/repos/repos.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:158
+#: rhodecode/templates/admin/users/user_edit_my_account.html:74
 #, python-format
 msgid "Confirm to delete this repository: %s"
 msgstr ""
@@ -1815,7 +1824,7 @@
 #: rhodecode/templates/admin/settings/settings.html:177
 #: rhodecode/templates/admin/users/user_edit.html:130
 #: rhodecode/templates/admin/users/user_edit.html:155
-#: rhodecode/templates/admin/users/user_edit_my_account.html:103
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:80
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:116
 #: rhodecode/templates/files/files_add.html:82
 #: rhodecode/templates/files/files_edit.html:68
@@ -2039,17 +2048,17 @@
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:34
-#: rhodecode/templates/admin/users/user_edit_my_account.html:33
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:10
 msgid "Change your avatar at"
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:35
-#: rhodecode/templates/admin/users/user_edit_my_account.html:34
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:11
 msgid "Using"
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:43
-#: rhodecode/templates/admin/users/user_edit_my_account.html:43
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:20
 msgid "API key"
 msgstr ""
 
@@ -2058,12 +2067,12 @@
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:58
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:35
 msgid "New password"
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:77
-#: rhodecode/templates/admin/users/user_edit_my_account.html:67
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:44
 msgid "New password confirmation"
 msgstr ""
 
@@ -2081,21 +2090,21 @@
 msgid "My Account"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #: rhodecode/templates/journal/journal.html:32
 msgid "My repos"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 msgid "My permissions"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:121
+#: rhodecode/templates/admin/users/user_edit_my_account.html:37
 #: rhodecode/templates/journal/journal.html:37
 msgid "ADD"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:134
+#: rhodecode/templates/admin/users/user_edit_my_account.html:50
 #: rhodecode/templates/bookmarks/bookmarks.html:40
 #: rhodecode/templates/bookmarks/bookmarks_data.html:9
 #: rhodecode/templates/branches/branches.html:40
@@ -2105,23 +2114,23 @@
 msgid "Revision"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/journal/journal.html:72
 msgid "private"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:81
 #: rhodecode/templates/journal/journal.html:85
 msgid "No repositories yet"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:167
+#: rhodecode/templates/admin/users/user_edit_my_account.html:83
 #: rhodecode/templates/journal/journal.html:87
 msgid "create one now"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:184
-#: rhodecode/templates/admin/users/user_edit_my_account.html:285
+#: rhodecode/templates/admin/users/user_edit_my_account.html:100
+#: rhodecode/templates/admin/users/user_edit_my_account.html:201
 msgid "Permission"
 msgstr ""
 
@@ -2222,6 +2231,11 @@
 msgid "group name"
 msgstr ""
 
+#: rhodecode/templates/admin/users_groups/users_groups.html:33
+#: rhodecode/templates/base/root.html:46
+msgid "members"
+msgstr ""
+
 #: rhodecode/templates/admin/users_groups/users_groups.html:45
 #, python-format
 msgid "Confirm to delete this users group: %s"
@@ -2381,21 +2395,25 @@
 msgid "Search"
 msgstr ""
 
-#: rhodecode/templates/base/root.html:53
+#: rhodecode/templates/base/root.html:42
 msgid "add another comment"
 msgstr ""
 
-#: rhodecode/templates/base/root.html:54
+#: rhodecode/templates/base/root.html:43
 #: rhodecode/templates/journal/journal.html:111
 #: rhodecode/templates/summary/summary.html:52
 msgid "Stop following this repository"
 msgstr ""
 
-#: rhodecode/templates/base/root.html:55
+#: rhodecode/templates/base/root.html:44
 #: rhodecode/templates/summary/summary.html:56
 msgid "Start following this repository"
 msgstr ""
 
+#: rhodecode/templates/base/root.html:45
+msgid "Group"
+msgstr ""
+
 #: rhodecode/templates/bookmarks/bookmarks.html:5
 msgid "Bookmarks"
 msgstr ""
@@ -2524,7 +2542,7 @@
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "%d comment"
 msgid_plural "%d comments"
@@ -2532,7 +2550,7 @@
 msgstr[1] ""
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "(%d inline)"
 msgid_plural "(%d inline)"
@@ -2557,35 +2575,35 @@
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:39
-#: rhodecode/templates/changeset/changeset_file_comment.html:100
+#: rhodecode/templates/changeset/changeset_file_comment.html:102
 #, python-format
 msgid "Comments parsed using %s syntax with %s support."
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:41
-#: rhodecode/templates/changeset/changeset_file_comment.html:102
+#: rhodecode/templates/changeset/changeset_file_comment.html:104
 msgid "Use @username inside this text to send notification to this RhodeCode user"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:47
-#: rhodecode/templates/changeset/changeset_file_comment.html:107
+#: rhodecode/templates/changeset/changeset_file_comment.html:49
+#: rhodecode/templates/changeset/changeset_file_comment.html:110
 msgid "Comment"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:48
-#: rhodecode/templates/changeset/changeset_file_comment.html:59
+#: rhodecode/templates/changeset/changeset_file_comment.html:50
+#: rhodecode/templates/changeset/changeset_file_comment.html:61
 msgid "Hide"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "You need to be logged in to comment."
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "Login now"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:97
+#: rhodecode/templates/changeset/changeset_file_comment.html:99
 msgid "Leave a comment"
 msgstr ""
 
@@ -3070,9 +3088,9 @@
 msgid "file removed"
 msgstr ""
 
-#~ msgid ""
-#~ "Changeset was to big and was cut"
-#~ " off, use diff menu to display "
-#~ "this diff"
+#~ msgid "[committed via RhodeCode] into"
 #~ msgstr ""
 
+#~ msgid "[pulled from remote] into"
+#~ msgstr ""
+
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/i18n/fr/LC_MESSAGES/rhodecode.po
--- a/rhodecode/i18n/fr/LC_MESSAGES/rhodecode.po	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/i18n/fr/LC_MESSAGES/rhodecode.po	Tue Jun 05 21:22:23 2012 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: RhodeCode 1.1.5\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2012-05-27 17:41+0200\n"
+"POT-Creation-Date: 2012-06-03 01:06+0200\n"
 "PO-Revision-Date: 2012-05-20 11:36+0100\n"
 "Last-Translator: Vincent Duvert \n"
 "Language-Team: fr \n"
@@ -17,25 +17,25 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 0.9.6\n"
 
-#: rhodecode/controllers/changelog.py:96
+#: rhodecode/controllers/changelog.py:95
 msgid "All Branches"
 msgstr "Toutes les branches"
 
-#: rhodecode/controllers/changeset.py:79
+#: rhodecode/controllers/changeset.py:80
 msgid "show white space"
 msgstr "afficher les espaces et tabulations"
 
-#: rhodecode/controllers/changeset.py:86 rhodecode/controllers/changeset.py:93
+#: rhodecode/controllers/changeset.py:87 rhodecode/controllers/changeset.py:94
 msgid "ignore white space"
 msgstr "ignorer les espaces et tabulations"
 
-#: rhodecode/controllers/changeset.py:153
+#: rhodecode/controllers/changeset.py:154
 #, python-format
 msgid "%s line context"
 msgstr "afficher %s lignes de contexte"
 
-#: rhodecode/controllers/changeset.py:320
-#: rhodecode/controllers/changeset.py:335 rhodecode/lib/diffs.py:62
+#: rhodecode/controllers/changeset.py:324
+#: rhodecode/controllers/changeset.py:339 rhodecode/lib/diffs.py:62
 msgid "binary file"
 msgstr "fichier binaire"
 
@@ -191,7 +191,7 @@
 msgid "%s public journal %s feed"
 msgstr "%s — Flux %s du journal public"
 
-#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:224
+#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:223
 #: rhodecode/templates/admin/repos/repo_edit.html:177
 #: rhodecode/templates/base/base.html:307
 #: rhodecode/templates/base/base.html:309
@@ -230,19 +230,19 @@
 msgstr "Une erreur est survenue durant l’opération de recherche."
 
 #: rhodecode/controllers/settings.py:103
-#: rhodecode/controllers/admin/repos.py:211
+#: rhodecode/controllers/admin/repos.py:213
 #, python-format
 msgid "Repository %s updated successfully"
 msgstr "Dépôt %s mis à jour avec succès."
 
 #: rhodecode/controllers/settings.py:121
-#: rhodecode/controllers/admin/repos.py:229
+#: rhodecode/controllers/admin/repos.py:231
 #, python-format
 msgid "error occurred during update of repository %s"
 msgstr "Une erreur est survenue lors de la mise à jour du dépôt %s."
 
 #: rhodecode/controllers/settings.py:139
-#: rhodecode/controllers/admin/repos.py:247
+#: rhodecode/controllers/admin/repos.py:249
 #, python-format
 msgid ""
 "%s repository is not mapped to db perhaps it was moved or renamed  from "
@@ -254,14 +254,14 @@
 "l’application pour rescanner les dépôts."
 
 #: rhodecode/controllers/settings.py:151
-#: rhodecode/controllers/admin/repos.py:259
+#: rhodecode/controllers/admin/repos.py:261
 #, python-format
 msgid "deleted repository %s"
 msgstr "Dépôt %s supprimé"
 
 #: rhodecode/controllers/settings.py:155
-#: rhodecode/controllers/admin/repos.py:269
-#: rhodecode/controllers/admin/repos.py:275
+#: rhodecode/controllers/admin/repos.py:271
+#: rhodecode/controllers/admin/repos.py:277
 #, python-format
 msgid "An error occurred during deletion of %s"
 msgstr "Erreur pendant la suppression de %s"
@@ -410,66 +410,66 @@
 msgid "created repository %s"
 msgstr "Le dépôt %s a été créé."
 
-#: rhodecode/controllers/admin/repos.py:177
+#: rhodecode/controllers/admin/repos.py:179
 #, python-format
 msgid "error occurred during creation of repository %s"
 msgstr "Une erreur est survenue durant la création du dépôt %s."
 
-#: rhodecode/controllers/admin/repos.py:264
+#: rhodecode/controllers/admin/repos.py:266
 #, python-format
 msgid "Cannot delete %s it still contains attached forks"
 msgstr "Impossible de supprimer le dépôt %s : Des forks y sont attachés."
 
-#: rhodecode/controllers/admin/repos.py:293
+#: rhodecode/controllers/admin/repos.py:295
 msgid "An error occurred during deletion of repository user"
 msgstr "Une erreur est survenue durant la suppression de l’utilisateur du dépôt."
 
-#: rhodecode/controllers/admin/repos.py:312
+#: rhodecode/controllers/admin/repos.py:314
 msgid "An error occurred during deletion of repository users groups"
 msgstr ""
 "Une erreur est survenue durant la suppression du groupe d’utilisateurs de"
 " ce dépôt."
 
-#: rhodecode/controllers/admin/repos.py:329
+#: rhodecode/controllers/admin/repos.py:331
 msgid "An error occurred during deletion of repository stats"
 msgstr "Une erreur est survenue durant la suppression des statistiques du dépôt."
 
-#: rhodecode/controllers/admin/repos.py:345
+#: rhodecode/controllers/admin/repos.py:347
 msgid "An error occurred during cache invalidation"
 msgstr "Une erreur est survenue durant l’invalidation du cache."
 
-#: rhodecode/controllers/admin/repos.py:365
+#: rhodecode/controllers/admin/repos.py:367
 msgid "Updated repository visibility in public journal"
 msgstr "La visibilité du dépôt dans le journal public a été mise à jour."
 
-#: rhodecode/controllers/admin/repos.py:369
+#: rhodecode/controllers/admin/repos.py:371
 msgid "An error occurred during setting this repository in public journal"
 msgstr ""
 "Une erreur est survenue durant la configuration du journal public pour ce"
 " dépôt."
 
-#: rhodecode/controllers/admin/repos.py:374 rhodecode/model/forms.py:54
+#: rhodecode/controllers/admin/repos.py:376 rhodecode/model/forms.py:54
 msgid "Token mismatch"
 msgstr "Jeton d’authentification incorrect."
 
-#: rhodecode/controllers/admin/repos.py:387
-msgid "Pulled from remote location"
-msgstr "Les changements distants ont été récupérés."
-
 #: rhodecode/controllers/admin/repos.py:389
+msgid "Pulled from remote location"
+msgstr "Les changements distants ont été récupérés."
+
+#: rhodecode/controllers/admin/repos.py:391
 msgid "An error occurred during pull from remote location"
 msgstr "Une erreur est survenue durant le pull depuis la source distante."
 
-#: rhodecode/controllers/admin/repos.py:405
+#: rhodecode/controllers/admin/repos.py:407
 msgid "Nothing"
 msgstr "[Aucun dépôt]"
 
-#: rhodecode/controllers/admin/repos.py:407
+#: rhodecode/controllers/admin/repos.py:409
 #, python-format
 msgid "Marked repo %s as fork of %s"
 msgstr "Le dépôt %s a été marké comme fork de %s"
 
-#: rhodecode/controllers/admin/repos.py:411
+#: rhodecode/controllers/admin/repos.py:413
 msgid "An error occurred during this operation"
 msgstr "Une erreur est survenue durant cette opération."
 
@@ -569,77 +569,77 @@
 "Vous ne pouvez pas éditer cet utilisateur ; il est nécessaire pour le bon"
 " fonctionnement de l’application."
 
-#: rhodecode/controllers/admin/settings.py:365
+#: rhodecode/controllers/admin/settings.py:367
 msgid "Your account was updated successfully"
 msgstr "Votre compte a été mis à jour avec succès"
 
-#: rhodecode/controllers/admin/settings.py:384
-#: rhodecode/controllers/admin/users.py:132
+#: rhodecode/controllers/admin/settings.py:387
+#: rhodecode/controllers/admin/users.py:138
 #, python-format
 msgid "error occurred during update of user %s"
 msgstr "Une erreur est survenue durant la mise à jour de l’utilisateur %s."
 
-#: rhodecode/controllers/admin/users.py:79
+#: rhodecode/controllers/admin/users.py:83
 #, python-format
 msgid "created user %s"
 msgstr "utilisateur %s créé"
 
-#: rhodecode/controllers/admin/users.py:92
+#: rhodecode/controllers/admin/users.py:95
 #, python-format
 msgid "error occurred during creation of user %s"
 msgstr "Une erreur est survenue durant la création de l’utilisateur %s."
 
-#: rhodecode/controllers/admin/users.py:118
+#: rhodecode/controllers/admin/users.py:124
 msgid "User updated successfully"
 msgstr "L’utilisateur a été mis à jour avec succès."
 
-#: rhodecode/controllers/admin/users.py:149
+#: rhodecode/controllers/admin/users.py:155
 msgid "successfully deleted user"
 msgstr "L’utilisateur a été supprimé avec succès."
 
-#: rhodecode/controllers/admin/users.py:154
+#: rhodecode/controllers/admin/users.py:160
 msgid "An error occurred during deletion of user"
 msgstr "Une erreur est survenue durant la suppression de l’utilisateur."
 
-#: rhodecode/controllers/admin/users.py:169
+#: rhodecode/controllers/admin/users.py:175
 msgid "You can't edit this user"
 msgstr "Vous ne pouvez pas éditer cet utilisateur"
 
-#: rhodecode/controllers/admin/users.py:199
-#: rhodecode/controllers/admin/users_groups.py:215
+#: rhodecode/controllers/admin/users.py:205
+#: rhodecode/controllers/admin/users_groups.py:219
 msgid "Granted 'repository create' permission to user"
 msgstr "La permission de création de dépôts a été accordée à l’utilisateur."
 
-#: rhodecode/controllers/admin/users.py:208
-#: rhodecode/controllers/admin/users_groups.py:225
+#: rhodecode/controllers/admin/users.py:214
+#: rhodecode/controllers/admin/users_groups.py:229
 msgid "Revoked 'repository create' permission to user"
 msgstr "La permission de création de dépôts a été révoquée à l’utilisateur."
 
-#: rhodecode/controllers/admin/users_groups.py:79
+#: rhodecode/controllers/admin/users_groups.py:84
 #, python-format
 msgid "created users group %s"
 msgstr "Le groupe d’utilisateurs %s a été créé."
 
-#: rhodecode/controllers/admin/users_groups.py:92
+#: rhodecode/controllers/admin/users_groups.py:95
 #, python-format
 msgid "error occurred during creation of users group %s"
 msgstr "Une erreur est survenue durant la création du groupe d’utilisateurs %s."
 
-#: rhodecode/controllers/admin/users_groups.py:128
+#: rhodecode/controllers/admin/users_groups.py:135
 #, python-format
 msgid "updated users group %s"
 msgstr "Le groupe d’utilisateurs %s a été mis à jour."
 
-#: rhodecode/controllers/admin/users_groups.py:148
+#: rhodecode/controllers/admin/users_groups.py:152
 #, python-format
 msgid "error occurred during update of users group %s"
 msgstr "Une erreur est survenue durant la mise à jour du groupe d’utilisateurs %s."
 
-#: rhodecode/controllers/admin/users_groups.py:165
+#: rhodecode/controllers/admin/users_groups.py:169
 msgid "successfully deleted users group"
 msgstr "Le groupe d’utilisateurs a été supprimé avec succès."
 
-#: rhodecode/controllers/admin/users_groups.py:170
+#: rhodecode/controllers/admin/users_groups.py:174
 msgid "An error occurred during deletion of users group"
 msgstr "Une erreur est survenue lors de la suppression du groupe d’utilisateurs."
 
@@ -700,60 +700,94 @@
 msgid "fork name "
 msgstr "Nom du fork"
 
-#: rhodecode/lib/helpers.py:540
+#: rhodecode/lib/helpers.py:550
 msgid "[deleted] repository"
 msgstr "[a supprimé] le dépôt"
 
-#: rhodecode/lib/helpers.py:541 rhodecode/lib/helpers.py:546
+#: rhodecode/lib/helpers.py:552 rhodecode/lib/helpers.py:562
 msgid "[created] repository"
 msgstr "[a créé] le dépôt"
 
-#: rhodecode/lib/helpers.py:542
+#: rhodecode/lib/helpers.py:554
 msgid "[created] repository as fork"
 msgstr "[a créé] le dépôt en tant que fork"
 
-#: rhodecode/lib/helpers.py:543 rhodecode/lib/helpers.py:547
+#: rhodecode/lib/helpers.py:556 rhodecode/lib/helpers.py:564
 msgid "[forked] repository"
 msgstr "[a forké] le dépôt"
 
-#: rhodecode/lib/helpers.py:544 rhodecode/lib/helpers.py:548
+#: rhodecode/lib/helpers.py:558 rhodecode/lib/helpers.py:566
 msgid "[updated] repository"
 msgstr "[a mis à jour] le dépôt"
 
-#: rhodecode/lib/helpers.py:545
+#: rhodecode/lib/helpers.py:560
 msgid "[delete] repository"
 msgstr "[a supprimé] le dépôt"
 
-#: rhodecode/lib/helpers.py:549
+#: rhodecode/lib/helpers.py:568
+#, fuzzy, python-format
+#| msgid "created user %s"
+msgid "[created] user"
+msgstr "utilisateur %s créé"
+
+#: rhodecode/lib/helpers.py:570
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] user"
+msgstr "Le groupe d’utilisateurs %s a été mis à jour."
+
+#: rhodecode/lib/helpers.py:572
+#, fuzzy, python-format
+#| msgid "created users group %s"
+msgid "[created] users group"
+msgstr "Le groupe d’utilisateurs %s a été créé."
+
+#: rhodecode/lib/helpers.py:574
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] users group"
+msgstr "Le groupe d’utilisateurs %s a été mis à jour."
+
+#: rhodecode/lib/helpers.py:576
+#, fuzzy
+#| msgid "[created] repository"
+msgid "[commented] on revision in repository"
+msgstr "[a créé] le dépôt"
+
+#: rhodecode/lib/helpers.py:578
 msgid "[pushed] into"
 msgstr "[a pushé] dans"
 
-#: rhodecode/lib/helpers.py:550
-msgid "[committed via RhodeCode] into"
+#: rhodecode/lib/helpers.py:580
+#, fuzzy
+#| msgid "[committed via RhodeCode] into"
+msgid "[committed via RhodeCode] into repository"
 msgstr "[a commité via RhodeCode] dans"
 
-#: rhodecode/lib/helpers.py:551
-msgid "[pulled from remote] into"
+#: rhodecode/lib/helpers.py:582
+#, fuzzy
+#| msgid "[pulled from remote] into"
+msgid "[pulled from remote] into repository"
 msgstr "[a pullé depuis un site distant] dans"
 
-#: rhodecode/lib/helpers.py:552
+#: rhodecode/lib/helpers.py:584
 msgid "[pulled] from"
 msgstr "[a pullé] depuis"
 
-#: rhodecode/lib/helpers.py:553
+#: rhodecode/lib/helpers.py:586
 msgid "[started following] repository"
 msgstr "[suit maintenant] le dépôt"
 
-#: rhodecode/lib/helpers.py:554
+#: rhodecode/lib/helpers.py:588
 msgid "[stopped following] repository"
 msgstr "[ne suit plus] le dépôt"
 
-#: rhodecode/lib/helpers.py:732
+#: rhodecode/lib/helpers.py:752
 #, python-format
 msgid " and %s more"
 msgstr "et %s de plus"
 
-#: rhodecode/lib/helpers.py:736
+#: rhodecode/lib/helpers.py:756
 msgid "No Files"
 msgstr "Aucun fichier"
 
@@ -1017,7 +1051,7 @@
 msgstr "Tableau de bord"
 
 #: rhodecode/templates/index_base.html:6
-#: rhodecode/templates/admin/users/user_edit_my_account.html:115
+#: rhodecode/templates/admin/users/user_edit_my_account.html:31
 #: rhodecode/templates/bookmarks/bookmarks.html:10
 #: rhodecode/templates/branches/branches.html:9
 #: rhodecode/templates/journal/journal.html:31
@@ -1072,10 +1106,10 @@
 #: rhodecode/templates/admin/repos/repo_edit.html:32
 #: rhodecode/templates/admin/repos/repos.html:36
 #: rhodecode/templates/admin/repos/repos.html:82
-#: rhodecode/templates/admin/users/user_edit_my_account.html:133
-#: rhodecode/templates/admin/users/user_edit_my_account.html:183
-#: rhodecode/templates/admin/users/user_edit_my_account.html:249
-#: rhodecode/templates/admin/users/user_edit_my_account.html:284
+#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account.html:99
+#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:200
 #: rhodecode/templates/bookmarks/bookmarks.html:36
 #: rhodecode/templates/bookmarks/bookmarks_data.html:6
 #: rhodecode/templates/branches/branches.html:36
@@ -1100,7 +1134,7 @@
 #: rhodecode/templates/index_base.html:161
 #: rhodecode/templates/admin/repos/repos.html:39
 #: rhodecode/templates/admin/repos/repos.html:87
-#: rhodecode/templates/admin/users/user_edit_my_account.html:251
+#: rhodecode/templates/admin/users/user_edit_my_account.html:167
 #: rhodecode/templates/journal/journal.html:179
 msgid "Tip"
 msgstr "Sommet"
@@ -1143,7 +1177,7 @@
 #: rhodecode/templates/index_base.html:148
 #: rhodecode/templates/index_base.html:188
 #: rhodecode/templates/admin/repos/repos.html:112
-#: rhodecode/templates/admin/users/user_edit_my_account.html:270
+#: rhodecode/templates/admin/users/user_edit_my_account.html:186
 #: rhodecode/templates/bookmarks/bookmarks.html:60
 #: rhodecode/templates/branches/branches.html:60
 #: rhodecode/templates/journal/journal.html:202
@@ -1154,7 +1188,7 @@
 #: rhodecode/templates/index_base.html:149
 #: rhodecode/templates/index_base.html:189
 #: rhodecode/templates/admin/repos/repos.html:113
-#: rhodecode/templates/admin/users/user_edit_my_account.html:271
+#: rhodecode/templates/admin/users/user_edit_my_account.html:187
 #: rhodecode/templates/bookmarks/bookmarks.html:61
 #: rhodecode/templates/branches/branches.html:61
 #: rhodecode/templates/journal/journal.html:203
@@ -1169,7 +1203,7 @@
 
 #: rhodecode/templates/index_base.html:190
 #: rhodecode/templates/admin/repos/repos.html:114
-#: rhodecode/templates/admin/users/user_edit_my_account.html:272
+#: rhodecode/templates/admin/users/user_edit_my_account.html:188
 #: rhodecode/templates/bookmarks/bookmarks.html:62
 #: rhodecode/templates/branches/branches.html:62
 #: rhodecode/templates/journal/journal.html:204
@@ -1179,7 +1213,7 @@
 
 #: rhodecode/templates/index_base.html:191
 #: rhodecode/templates/admin/repos/repos.html:115
-#: rhodecode/templates/admin/users/user_edit_my_account.html:273
+#: rhodecode/templates/admin/users/user_edit_my_account.html:189
 #: rhodecode/templates/bookmarks/bookmarks.html:63
 #: rhodecode/templates/branches/branches.html:63
 #: rhodecode/templates/journal/journal.html:205
@@ -1189,7 +1223,7 @@
 
 #: rhodecode/templates/index_base.html:192
 #: rhodecode/templates/admin/repos/repos.html:116
-#: rhodecode/templates/admin/users/user_edit_my_account.html:274
+#: rhodecode/templates/admin/users/user_edit_my_account.html:190
 #: rhodecode/templates/bookmarks/bookmarks.html:64
 #: rhodecode/templates/branches/branches.html:64
 #: rhodecode/templates/journal/journal.html:206
@@ -1209,7 +1243,7 @@
 #: rhodecode/templates/admin/admin_log.html:5
 #: rhodecode/templates/admin/users/user_add.html:32
 #: rhodecode/templates/admin/users/user_edit.html:50
-#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:26
 #: rhodecode/templates/base/base.html:83
 #: rhodecode/templates/summary/summary.html:113
 msgid "Username"
@@ -1269,21 +1303,21 @@
 #: rhodecode/templates/register.html:47
 #: rhodecode/templates/admin/users/user_add.html:59
 #: rhodecode/templates/admin/users/user_edit.html:86
-#: rhodecode/templates/admin/users/user_edit_my_account.html:76
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:53
 msgid "First Name"
 msgstr "Prénom"
 
 #: rhodecode/templates/register.html:56
 #: rhodecode/templates/admin/users/user_add.html:68
 #: rhodecode/templates/admin/users/user_edit.html:95
-#: rhodecode/templates/admin/users/user_edit_my_account.html:85
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:62
 msgid "Last Name"
 msgstr "Nom"
 
 #: rhodecode/templates/register.html:65
 #: rhodecode/templates/admin/users/user_add.html:77
 #: rhodecode/templates/admin/users/user_edit.html:104
-#: rhodecode/templates/admin/users/user_edit_my_account.html:94
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:71
 #: rhodecode/templates/summary/summary.html:115
 msgid "Email"
 msgstr "E-mail"
@@ -1346,8 +1380,8 @@
 #: rhodecode/templates/admin/admin_log.html:6
 #: rhodecode/templates/admin/repos/repos.html:41
 #: rhodecode/templates/admin/repos/repos.html:90
-#: rhodecode/templates/admin/users/user_edit_my_account.html:135
-#: rhodecode/templates/admin/users/user_edit_my_account.html:136
+#: rhodecode/templates/admin/users/user_edit_my_account.html:51
+#: rhodecode/templates/admin/users/user_edit_my_account.html:52
 #: rhodecode/templates/journal/journal.html:52
 #: rhodecode/templates/journal/journal.html:53
 msgid "Action"
@@ -1370,7 +1404,7 @@
 msgid "From IP"
 msgstr "Depuis l’adresse IP"
 
-#: rhodecode/templates/admin/admin_log.html:52
+#: rhodecode/templates/admin/admin_log.html:53
 msgid "No actions yet"
 msgstr "Aucune action n’a été enregistrée pour le moment."
 
@@ -1451,7 +1485,7 @@
 #: rhodecode/templates/admin/settings/hooks.html:73
 #: rhodecode/templates/admin/users/user_edit.html:129
 #: rhodecode/templates/admin/users/user_edit.html:154
-#: rhodecode/templates/admin/users/user_edit_my_account.html:102
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:115
 #: rhodecode/templates/settings/repo_settings.html:84
 msgid "Save"
@@ -1610,7 +1644,7 @@
 
 #: rhodecode/templates/admin/repos/repo_edit.html:13
 #: rhodecode/templates/admin/users/user_edit.html:13
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:13
 #: rhodecode/templates/files/files_source.html:32
 #: rhodecode/templates/journal/journal.html:72
@@ -1774,38 +1808,27 @@
 msgstr "Dépôt privé"
 
 #: rhodecode/templates/admin/repos/repo_edit_perms.html:33
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:53
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:58
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:23
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:42
 msgid "revoke"
 msgstr "Révoquer"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:75
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:80
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:64
 msgid "Add another member"
 msgstr "Ajouter un utilisateur"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:89
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:94
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:78
 msgid "Failed to remove user"
 msgstr "Échec de suppression de l’utilisateur"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:104
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:109
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:93
 msgid "Failed to remove users group"
 msgstr "Erreur lors de la suppression du groupe d’utilisateurs."
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:123
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:112
-msgid "Group"
-msgstr "Groupe"
-
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:124
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:113
-#: rhodecode/templates/admin/users_groups/users_groups.html:33
-msgid "members"
-msgstr "Membres"
-
 #: rhodecode/templates/admin/repos/repos.html:5
 msgid "Repositories administration"
 msgstr "Administration des dépôts"
@@ -1823,7 +1846,7 @@
 msgstr "Supprimer"
 
 #: rhodecode/templates/admin/repos/repos.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:158
+#: rhodecode/templates/admin/users/user_edit_my_account.html:74
 #, python-format
 msgid "Confirm to delete this repository: %s"
 msgstr "Voulez-vous vraiment supprimer le dépôt %s ?"
@@ -1874,7 +1897,7 @@
 #: rhodecode/templates/admin/settings/settings.html:177
 #: rhodecode/templates/admin/users/user_edit.html:130
 #: rhodecode/templates/admin/users/user_edit.html:155
-#: rhodecode/templates/admin/users/user_edit_my_account.html:103
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:80
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:116
 #: rhodecode/templates/files/files_add.html:82
 #: rhodecode/templates/files/files_edit.html:68
@@ -2103,17 +2126,17 @@
 msgstr "Éditer l'utilisateur"
 
 #: rhodecode/templates/admin/users/user_edit.html:34
-#: rhodecode/templates/admin/users/user_edit_my_account.html:33
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:10
 msgid "Change your avatar at"
 msgstr "Vous pouvez changer votre avatar sur"
 
 #: rhodecode/templates/admin/users/user_edit.html:35
-#: rhodecode/templates/admin/users/user_edit_my_account.html:34
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:11
 msgid "Using"
 msgstr "en utilisant l’adresse"
 
 #: rhodecode/templates/admin/users/user_edit.html:43
-#: rhodecode/templates/admin/users/user_edit_my_account.html:43
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:20
 msgid "API key"
 msgstr "Clé d’API"
 
@@ -2122,12 +2145,12 @@
 msgstr "DN LDAP"
 
 #: rhodecode/templates/admin/users/user_edit.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:58
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:35
 msgid "New password"
 msgstr "Nouveau mot de passe"
 
 #: rhodecode/templates/admin/users/user_edit.html:77
-#: rhodecode/templates/admin/users/user_edit_my_account.html:67
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:44
 msgid "New password confirmation"
 msgstr "Confirmation du nouveau mot de passe"
 
@@ -2145,21 +2168,21 @@
 msgid "My Account"
 msgstr "Mon compte"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #: rhodecode/templates/journal/journal.html:32
 msgid "My repos"
 msgstr "Mes dépôts"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 msgid "My permissions"
 msgstr "Mes permissions"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:121
+#: rhodecode/templates/admin/users/user_edit_my_account.html:37
 #: rhodecode/templates/journal/journal.html:37
 msgid "ADD"
 msgstr "AJOUTER"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:134
+#: rhodecode/templates/admin/users/user_edit_my_account.html:50
 #: rhodecode/templates/bookmarks/bookmarks.html:40
 #: rhodecode/templates/bookmarks/bookmarks_data.html:9
 #: rhodecode/templates/branches/branches.html:40
@@ -2169,23 +2192,23 @@
 msgid "Revision"
 msgstr "Révision"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/journal/journal.html:72
 msgid "private"
 msgstr "privé"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:81
 #: rhodecode/templates/journal/journal.html:85
 msgid "No repositories yet"
 msgstr "Aucun dépôt pour le moment"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:167
+#: rhodecode/templates/admin/users/user_edit_my_account.html:83
 #: rhodecode/templates/journal/journal.html:87
 msgid "create one now"
 msgstr "En créer un maintenant"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:184
-#: rhodecode/templates/admin/users/user_edit_my_account.html:285
+#: rhodecode/templates/admin/users/user_edit_my_account.html:100
+#: rhodecode/templates/admin/users/user_edit_my_account.html:201
 msgid "Permission"
 msgstr "Permission"
 
@@ -2286,6 +2309,11 @@
 msgid "group name"
 msgstr "Nom du groupe"
 
+#: rhodecode/templates/admin/users_groups/users_groups.html:33
+#: rhodecode/templates/base/root.html:46
+msgid "members"
+msgstr "Membres"
+
 #: rhodecode/templates/admin/users_groups/users_groups.html:45
 #, python-format
 msgid "Confirm to delete this users group: %s"
@@ -2445,21 +2473,25 @@
 msgid "Search"
 msgstr "Rechercher"
 
-#: rhodecode/templates/base/root.html:53
+#: rhodecode/templates/base/root.html:42
 msgid "add another comment"
 msgstr "Nouveau commentaire"
 
-#: rhodecode/templates/base/root.html:54
+#: rhodecode/templates/base/root.html:43
 #: rhodecode/templates/journal/journal.html:111
 #: rhodecode/templates/summary/summary.html:52
 msgid "Stop following this repository"
 msgstr "Arrêter de suivre ce dépôt"
 
-#: rhodecode/templates/base/root.html:55
+#: rhodecode/templates/base/root.html:44
 #: rhodecode/templates/summary/summary.html:56
 msgid "Start following this repository"
 msgstr "Suivre ce dépôt"
 
+#: rhodecode/templates/base/root.html:45
+msgid "Group"
+msgstr "Groupe"
+
 #: rhodecode/templates/bookmarks/bookmarks.html:5
 msgid "Bookmarks"
 msgstr "Signets"
@@ -2588,7 +2620,7 @@
 msgstr "Télécharger le diff"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "%d comment"
 msgid_plural "%d comments"
@@ -2596,7 +2628,7 @@
 msgstr[1] "%d commentaires"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "(%d inline)"
 msgid_plural "(%d inline)"
@@ -2621,7 +2653,7 @@
 msgstr "Commentaire sur la ligne {1}."
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:39
-#: rhodecode/templates/changeset/changeset_file_comment.html:100
+#: rhodecode/templates/changeset/changeset_file_comment.html:102
 #, python-format
 msgid "Comments parsed using %s syntax with %s support."
 msgstr ""
@@ -2629,31 +2661,31 @@
 "commande %s."
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:41
-#: rhodecode/templates/changeset/changeset_file_comment.html:102
+#: rhodecode/templates/changeset/changeset_file_comment.html:104
 msgid "Use @username inside this text to send notification to this RhodeCode user"
 msgstr ""
 "Utilisez @nomutilisateur dans ce texte pour envoyer une notification à "
 "l’utilisateur RhodeCode en question."
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:47
-#: rhodecode/templates/changeset/changeset_file_comment.html:107
+#: rhodecode/templates/changeset/changeset_file_comment.html:49
+#: rhodecode/templates/changeset/changeset_file_comment.html:110
 msgid "Comment"
 msgstr "Commentaire"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:48
-#: rhodecode/templates/changeset/changeset_file_comment.html:59
+#: rhodecode/templates/changeset/changeset_file_comment.html:50
+#: rhodecode/templates/changeset/changeset_file_comment.html:61
 msgid "Hide"
 msgstr "Masquer"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "You need to be logged in to comment."
 msgstr "Vous devez être connecté pour poster des commentaires."
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "Login now"
 msgstr "Se connecter maintenant"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:97
+#: rhodecode/templates/changeset/changeset_file_comment.html:99
 msgid "Leave a comment"
 msgstr "Laisser un commentaire"
 
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/i18n/pt_BR/LC_MESSAGES/rhodecode.po
--- a/rhodecode/i18n/pt_BR/LC_MESSAGES/rhodecode.po	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/i18n/pt_BR/LC_MESSAGES/rhodecode.po	Tue Jun 05 21:22:23 2012 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: RhodeCode 1.2.0\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2012-05-27 17:41+0200\n"
+"POT-Creation-Date: 2012-06-03 01:06+0200\n"
 "PO-Revision-Date: 2012-05-22 16:47-0300\n"
 "Last-Translator: Augusto Herrmann \n"
 "Language-Team: pt_BR \n"
@@ -17,25 +17,25 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 0.9.6\n"
 
-#: rhodecode/controllers/changelog.py:96
+#: rhodecode/controllers/changelog.py:95
 msgid "All Branches"
 msgstr "Todos os Ramos"
 
-#: rhodecode/controllers/changeset.py:79
+#: rhodecode/controllers/changeset.py:80
 msgid "show white space"
 msgstr "mostrar espaços em branco"
 
-#: rhodecode/controllers/changeset.py:86 rhodecode/controllers/changeset.py:93
+#: rhodecode/controllers/changeset.py:87 rhodecode/controllers/changeset.py:94
 msgid "ignore white space"
 msgstr "ignorar espaços em branco"
 
-#: rhodecode/controllers/changeset.py:153
+#: rhodecode/controllers/changeset.py:154
 #, python-format
 msgid "%s line context"
 msgstr "contexto de %s linhas"
 
-#: rhodecode/controllers/changeset.py:320
-#: rhodecode/controllers/changeset.py:335 rhodecode/lib/diffs.py:62
+#: rhodecode/controllers/changeset.py:324
+#: rhodecode/controllers/changeset.py:339 rhodecode/lib/diffs.py:62
 msgid "binary file"
 msgstr "arquivo binário"
 
@@ -191,7 +191,7 @@
 msgid "%s public journal %s feed"
 msgstr "diário público de %s - feed %s"
 
-#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:224
+#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:223
 #: rhodecode/templates/admin/repos/repo_edit.html:177
 #: rhodecode/templates/base/base.html:307
 #: rhodecode/templates/base/base.html:309
@@ -228,19 +228,19 @@
 msgstr "Ocorreu um erro durante essa operação de busca"
 
 #: rhodecode/controllers/settings.py:103
-#: rhodecode/controllers/admin/repos.py:211
+#: rhodecode/controllers/admin/repos.py:213
 #, python-format
 msgid "Repository %s updated successfully"
 msgstr "Repositório %s atualizado com sucesso"
 
 #: rhodecode/controllers/settings.py:121
-#: rhodecode/controllers/admin/repos.py:229
+#: rhodecode/controllers/admin/repos.py:231
 #, python-format
 msgid "error occurred during update of repository %s"
 msgstr "ocorreu um erro ao atualizar o repositório %s"
 
 #: rhodecode/controllers/settings.py:139
-#: rhodecode/controllers/admin/repos.py:247
+#: rhodecode/controllers/admin/repos.py:249
 #, python-format
 msgid ""
 "%s repository is not mapped to db perhaps it was moved or renamed  from "
@@ -252,14 +252,14 @@
 "outra vez para varrer novamente por repositórios"
 
 #: rhodecode/controllers/settings.py:151
-#: rhodecode/controllers/admin/repos.py:259
+#: rhodecode/controllers/admin/repos.py:261
 #, python-format
 msgid "deleted repository %s"
 msgstr "excluído o repositório %s"
 
 #: rhodecode/controllers/settings.py:155
-#: rhodecode/controllers/admin/repos.py:269
-#: rhodecode/controllers/admin/repos.py:275
+#: rhodecode/controllers/admin/repos.py:271
+#: rhodecode/controllers/admin/repos.py:277
 #, python-format
 msgid "An error occurred during deletion of %s"
 msgstr "Ocorreu um erro durante a exclusão de %s"
@@ -408,62 +408,62 @@
 msgid "created repository %s"
 msgstr "repositório %s criado"
 
-#: rhodecode/controllers/admin/repos.py:177
+#: rhodecode/controllers/admin/repos.py:179
 #, python-format
 msgid "error occurred during creation of repository %s"
 msgstr "ocorreu um erro ao criar o repositório %s"
 
-#: rhodecode/controllers/admin/repos.py:264
+#: rhodecode/controllers/admin/repos.py:266
 #, python-format
 msgid "Cannot delete %s it still contains attached forks"
 msgstr "Nao é possível excluir %s pois ele ainda contém bifurcações vinculadas"
 
-#: rhodecode/controllers/admin/repos.py:293
+#: rhodecode/controllers/admin/repos.py:295
 msgid "An error occurred during deletion of repository user"
 msgstr "Ocorreu um erro ao excluir usuário de repositório"
 
-#: rhodecode/controllers/admin/repos.py:312
+#: rhodecode/controllers/admin/repos.py:314
 msgid "An error occurred during deletion of repository users groups"
 msgstr "Ocorreu um erro ao excluir grupo de usuário de repositório"
 
-#: rhodecode/controllers/admin/repos.py:329
+#: rhodecode/controllers/admin/repos.py:331
 msgid "An error occurred during deletion of repository stats"
 msgstr "Ocorreu um erro ao excluir estatísticas de repositório"
 
-#: rhodecode/controllers/admin/repos.py:345
+#: rhodecode/controllers/admin/repos.py:347
 msgid "An error occurred during cache invalidation"
 msgstr "Ocorreu um erro ao invalidar o cache"
 
-#: rhodecode/controllers/admin/repos.py:365
+#: rhodecode/controllers/admin/repos.py:367
 msgid "Updated repository visibility in public journal"
 msgstr "Atualizada a visibilidade do repositório no diário público"
 
-#: rhodecode/controllers/admin/repos.py:369
+#: rhodecode/controllers/admin/repos.py:371
 msgid "An error occurred during setting this repository in public journal"
 msgstr "Ocorreu um erro ao ajustar esse repositório no diário público"
 
-#: rhodecode/controllers/admin/repos.py:374 rhodecode/model/forms.py:54
+#: rhodecode/controllers/admin/repos.py:376 rhodecode/model/forms.py:54
 msgid "Token mismatch"
 msgstr "Descompasso de Token"
 
-#: rhodecode/controllers/admin/repos.py:387
+#: rhodecode/controllers/admin/repos.py:389
 msgid "Pulled from remote location"
 msgstr "Realizado pull de localização remota"
 
-#: rhodecode/controllers/admin/repos.py:389
+#: rhodecode/controllers/admin/repos.py:391
 msgid "An error occurred during pull from remote location"
 msgstr "Ocorreu um erro ao realizar pull de localização remota"
 
-#: rhodecode/controllers/admin/repos.py:405
+#: rhodecode/controllers/admin/repos.py:407
 msgid "Nothing"
 msgstr "Nada"
 
-#: rhodecode/controllers/admin/repos.py:407
+#: rhodecode/controllers/admin/repos.py:409
 #, python-format
 msgid "Marked repo %s as fork of %s"
 msgstr "Marcado repositório %s como bifurcação de %s"
 
-#: rhodecode/controllers/admin/repos.py:411
+#: rhodecode/controllers/admin/repos.py:413
 msgid "An error occurred during this operation"
 msgstr "Ocorreu um erro durante essa operação"
 
@@ -557,77 +557,77 @@
 msgid "You can't edit this user since it's crucial for entire application"
 msgstr "Você não pode editar esse usuário pois ele é crucial para toda a aplicação"
 
-#: rhodecode/controllers/admin/settings.py:365
+#: rhodecode/controllers/admin/settings.py:367
 msgid "Your account was updated successfully"
 msgstr "Sua conta foi atualizada com sucesso"
 
-#: rhodecode/controllers/admin/settings.py:384
-#: rhodecode/controllers/admin/users.py:132
+#: rhodecode/controllers/admin/settings.py:387
+#: rhodecode/controllers/admin/users.py:138
 #, python-format
 msgid "error occurred during update of user %s"
 msgstr "ocorreu um erro ao atualizar o usuário %s"
 
-#: rhodecode/controllers/admin/users.py:79
+#: rhodecode/controllers/admin/users.py:83
 #, python-format
 msgid "created user %s"
 msgstr "usuário %s criado"
 
-#: rhodecode/controllers/admin/users.py:92
+#: rhodecode/controllers/admin/users.py:95
 #, python-format
 msgid "error occurred during creation of user %s"
 msgstr "ocorreu um erro ao criar o usuário %s"
 
-#: rhodecode/controllers/admin/users.py:118
+#: rhodecode/controllers/admin/users.py:124
 msgid "User updated successfully"
 msgstr "Usuário atualizado com sucesso"
 
-#: rhodecode/controllers/admin/users.py:149
+#: rhodecode/controllers/admin/users.py:155
 msgid "successfully deleted user"
 msgstr "usuário excluído com sucesso"
 
-#: rhodecode/controllers/admin/users.py:154
+#: rhodecode/controllers/admin/users.py:160
 msgid "An error occurred during deletion of user"
 msgstr "Ocorreu um erro ao excluir o usuário"
 
-#: rhodecode/controllers/admin/users.py:169
+#: rhodecode/controllers/admin/users.py:175
 msgid "You can't edit this user"
 msgstr "Você não pode editar esse usuário"
 
-#: rhodecode/controllers/admin/users.py:199
-#: rhodecode/controllers/admin/users_groups.py:215
+#: rhodecode/controllers/admin/users.py:205
+#: rhodecode/controllers/admin/users_groups.py:219
 msgid "Granted 'repository create' permission to user"
 msgstr "Concedida permissão de 'criar repositório' ao usuário"
 
-#: rhodecode/controllers/admin/users.py:208
-#: rhodecode/controllers/admin/users_groups.py:225
+#: rhodecode/controllers/admin/users.py:214
+#: rhodecode/controllers/admin/users_groups.py:229
 msgid "Revoked 'repository create' permission to user"
 msgstr "Revogada permissão de 'criar repositório' ao usuário"
 
-#: rhodecode/controllers/admin/users_groups.py:79
+#: rhodecode/controllers/admin/users_groups.py:84
 #, python-format
 msgid "created users group %s"
 msgstr "criado grupo de usuários %s"
 
-#: rhodecode/controllers/admin/users_groups.py:92
+#: rhodecode/controllers/admin/users_groups.py:95
 #, python-format
 msgid "error occurred during creation of users group %s"
 msgstr "ocorreu um erro ao criar o grupo de usuários %s"
 
-#: rhodecode/controllers/admin/users_groups.py:128
+#: rhodecode/controllers/admin/users_groups.py:135
 #, python-format
 msgid "updated users group %s"
 msgstr "grupo de usuários %s atualizado"
 
-#: rhodecode/controllers/admin/users_groups.py:148
+#: rhodecode/controllers/admin/users_groups.py:152
 #, python-format
 msgid "error occurred during update of users group %s"
 msgstr "ocorreu um erro ao atualizar o grupo de usuários %s"
 
-#: rhodecode/controllers/admin/users_groups.py:165
+#: rhodecode/controllers/admin/users_groups.py:169
 msgid "successfully deleted users group"
 msgstr "grupo de usuários excluído com sucesso"
 
-#: rhodecode/controllers/admin/users_groups.py:170
+#: rhodecode/controllers/admin/users_groups.py:174
 msgid "An error occurred during deletion of users group"
 msgstr "Ocorreu um erro ao excluir o grupo de usuários"
 
@@ -687,60 +687,94 @@
 msgid "fork name "
 msgstr "nome da bifurcação"
 
-#: rhodecode/lib/helpers.py:540
+#: rhodecode/lib/helpers.py:550
 msgid "[deleted] repository"
 msgstr "repositório [excluído]"
 
-#: rhodecode/lib/helpers.py:541 rhodecode/lib/helpers.py:546
+#: rhodecode/lib/helpers.py:552 rhodecode/lib/helpers.py:562
 msgid "[created] repository"
 msgstr "repositório [criado]"
 
-#: rhodecode/lib/helpers.py:542
+#: rhodecode/lib/helpers.py:554
 msgid "[created] repository as fork"
 msgstr "repositório [criado] como uma bifurcação"
 
-#: rhodecode/lib/helpers.py:543 rhodecode/lib/helpers.py:547
+#: rhodecode/lib/helpers.py:556 rhodecode/lib/helpers.py:564
 msgid "[forked] repository"
 msgstr "repositório [bifurcado]"
 
-#: rhodecode/lib/helpers.py:544 rhodecode/lib/helpers.py:548
+#: rhodecode/lib/helpers.py:558 rhodecode/lib/helpers.py:566
 msgid "[updated] repository"
 msgstr "repositório [atualizado]"
 
-#: rhodecode/lib/helpers.py:545
+#: rhodecode/lib/helpers.py:560
 msgid "[delete] repository"
 msgstr "[excluir] repositório"
 
-#: rhodecode/lib/helpers.py:549
+#: rhodecode/lib/helpers.py:568
+#, fuzzy, python-format
+#| msgid "created user %s"
+msgid "[created] user"
+msgstr "usuário %s criado"
+
+#: rhodecode/lib/helpers.py:570
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] user"
+msgstr "grupo de usuários %s atualizado"
+
+#: rhodecode/lib/helpers.py:572
+#, fuzzy, python-format
+#| msgid "created users group %s"
+msgid "[created] users group"
+msgstr "criado grupo de usuários %s"
+
+#: rhodecode/lib/helpers.py:574
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] users group"
+msgstr "grupo de usuários %s atualizado"
+
+#: rhodecode/lib/helpers.py:576
+#, fuzzy
+#| msgid "[created] repository"
+msgid "[commented] on revision in repository"
+msgstr "repositório [criado]"
+
+#: rhodecode/lib/helpers.py:578
 msgid "[pushed] into"
 msgstr "[realizado push] para"
 
-#: rhodecode/lib/helpers.py:550
-msgid "[committed via RhodeCode] into"
+#: rhodecode/lib/helpers.py:580
+#, fuzzy
+#| msgid "[committed via RhodeCode] into"
+msgid "[committed via RhodeCode] into repository"
 msgstr "[realizado commit via RhodeCode] para"
 
-#: rhodecode/lib/helpers.py:551
-msgid "[pulled from remote] into"
+#: rhodecode/lib/helpers.py:582
+#, fuzzy
+#| msgid "[pulled from remote] into"
+msgid "[pulled from remote] into repository"
 msgstr "[realizado pull remoto] para"
 
-#: rhodecode/lib/helpers.py:552
+#: rhodecode/lib/helpers.py:584
 msgid "[pulled] from"
 msgstr "[realizado pull] a partir de"
 
-#: rhodecode/lib/helpers.py:553
+#: rhodecode/lib/helpers.py:586
 msgid "[started following] repository"
 msgstr "[passou a seguir] o repositório"
 
-#: rhodecode/lib/helpers.py:554
+#: rhodecode/lib/helpers.py:588
 msgid "[stopped following] repository"
 msgstr "[parou de seguir] o repositório"
 
-#: rhodecode/lib/helpers.py:732
+#: rhodecode/lib/helpers.py:752
 #, python-format
 msgid " and %s more"
 msgstr " e mais %s"
 
-#: rhodecode/lib/helpers.py:736
+#: rhodecode/lib/helpers.py:756
 msgid "No Files"
 msgstr "Nenhum Arquivo"
 
@@ -1001,7 +1035,7 @@
 msgstr "Painel de Controle"
 
 #: rhodecode/templates/index_base.html:6
-#: rhodecode/templates/admin/users/user_edit_my_account.html:115
+#: rhodecode/templates/admin/users/user_edit_my_account.html:31
 #: rhodecode/templates/bookmarks/bookmarks.html:10
 #: rhodecode/templates/branches/branches.html:9
 #: rhodecode/templates/journal/journal.html:31
@@ -1056,10 +1090,10 @@
 #: rhodecode/templates/admin/repos/repo_edit.html:32
 #: rhodecode/templates/admin/repos/repos.html:36
 #: rhodecode/templates/admin/repos/repos.html:82
-#: rhodecode/templates/admin/users/user_edit_my_account.html:133
-#: rhodecode/templates/admin/users/user_edit_my_account.html:183
-#: rhodecode/templates/admin/users/user_edit_my_account.html:249
-#: rhodecode/templates/admin/users/user_edit_my_account.html:284
+#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account.html:99
+#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:200
 #: rhodecode/templates/bookmarks/bookmarks.html:36
 #: rhodecode/templates/bookmarks/bookmarks_data.html:6
 #: rhodecode/templates/branches/branches.html:36
@@ -1084,7 +1118,7 @@
 #: rhodecode/templates/index_base.html:161
 #: rhodecode/templates/admin/repos/repos.html:39
 #: rhodecode/templates/admin/repos/repos.html:87
-#: rhodecode/templates/admin/users/user_edit_my_account.html:251
+#: rhodecode/templates/admin/users/user_edit_my_account.html:167
 #: rhodecode/templates/journal/journal.html:179
 msgid "Tip"
 msgstr "Ponta"
@@ -1127,7 +1161,7 @@
 #: rhodecode/templates/index_base.html:148
 #: rhodecode/templates/index_base.html:188
 #: rhodecode/templates/admin/repos/repos.html:112
-#: rhodecode/templates/admin/users/user_edit_my_account.html:270
+#: rhodecode/templates/admin/users/user_edit_my_account.html:186
 #: rhodecode/templates/bookmarks/bookmarks.html:60
 #: rhodecode/templates/branches/branches.html:60
 #: rhodecode/templates/journal/journal.html:202
@@ -1138,7 +1172,7 @@
 #: rhodecode/templates/index_base.html:149
 #: rhodecode/templates/index_base.html:189
 #: rhodecode/templates/admin/repos/repos.html:113
-#: rhodecode/templates/admin/users/user_edit_my_account.html:271
+#: rhodecode/templates/admin/users/user_edit_my_account.html:187
 #: rhodecode/templates/bookmarks/bookmarks.html:61
 #: rhodecode/templates/branches/branches.html:61
 #: rhodecode/templates/journal/journal.html:203
@@ -1153,7 +1187,7 @@
 
 #: rhodecode/templates/index_base.html:190
 #: rhodecode/templates/admin/repos/repos.html:114
-#: rhodecode/templates/admin/users/user_edit_my_account.html:272
+#: rhodecode/templates/admin/users/user_edit_my_account.html:188
 #: rhodecode/templates/bookmarks/bookmarks.html:62
 #: rhodecode/templates/branches/branches.html:62
 #: rhodecode/templates/journal/journal.html:204
@@ -1163,7 +1197,7 @@
 
 #: rhodecode/templates/index_base.html:191
 #: rhodecode/templates/admin/repos/repos.html:115
-#: rhodecode/templates/admin/users/user_edit_my_account.html:273
+#: rhodecode/templates/admin/users/user_edit_my_account.html:189
 #: rhodecode/templates/bookmarks/bookmarks.html:63
 #: rhodecode/templates/branches/branches.html:63
 #: rhodecode/templates/journal/journal.html:205
@@ -1173,7 +1207,7 @@
 
 #: rhodecode/templates/index_base.html:192
 #: rhodecode/templates/admin/repos/repos.html:116
-#: rhodecode/templates/admin/users/user_edit_my_account.html:274
+#: rhodecode/templates/admin/users/user_edit_my_account.html:190
 #: rhodecode/templates/bookmarks/bookmarks.html:64
 #: rhodecode/templates/branches/branches.html:64
 #: rhodecode/templates/journal/journal.html:206
@@ -1193,7 +1227,7 @@
 #: rhodecode/templates/admin/admin_log.html:5
 #: rhodecode/templates/admin/users/user_add.html:32
 #: rhodecode/templates/admin/users/user_edit.html:50
-#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:26
 #: rhodecode/templates/base/base.html:83
 #: rhodecode/templates/summary/summary.html:113
 msgid "Username"
@@ -1255,21 +1289,21 @@
 #: rhodecode/templates/register.html:47
 #: rhodecode/templates/admin/users/user_add.html:59
 #: rhodecode/templates/admin/users/user_edit.html:86
-#: rhodecode/templates/admin/users/user_edit_my_account.html:76
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:53
 msgid "First Name"
 msgstr "Primeiro Nome"
 
 #: rhodecode/templates/register.html:56
 #: rhodecode/templates/admin/users/user_add.html:68
 #: rhodecode/templates/admin/users/user_edit.html:95
-#: rhodecode/templates/admin/users/user_edit_my_account.html:85
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:62
 msgid "Last Name"
 msgstr "Último Nome"
 
 #: rhodecode/templates/register.html:65
 #: rhodecode/templates/admin/users/user_add.html:77
 #: rhodecode/templates/admin/users/user_edit.html:104
-#: rhodecode/templates/admin/users/user_edit_my_account.html:94
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:71
 #: rhodecode/templates/summary/summary.html:115
 msgid "Email"
 msgstr "E-mail"
@@ -1332,8 +1366,8 @@
 #: rhodecode/templates/admin/admin_log.html:6
 #: rhodecode/templates/admin/repos/repos.html:41
 #: rhodecode/templates/admin/repos/repos.html:90
-#: rhodecode/templates/admin/users/user_edit_my_account.html:135
-#: rhodecode/templates/admin/users/user_edit_my_account.html:136
+#: rhodecode/templates/admin/users/user_edit_my_account.html:51
+#: rhodecode/templates/admin/users/user_edit_my_account.html:52
 #: rhodecode/templates/journal/journal.html:52
 #: rhodecode/templates/journal/journal.html:53
 msgid "Action"
@@ -1356,7 +1390,7 @@
 msgid "From IP"
 msgstr "A partir do IP"
 
-#: rhodecode/templates/admin/admin_log.html:52
+#: rhodecode/templates/admin/admin_log.html:53
 msgid "No actions yet"
 msgstr "Ainda não há ações"
 
@@ -1437,7 +1471,7 @@
 #: rhodecode/templates/admin/settings/hooks.html:73
 #: rhodecode/templates/admin/users/user_edit.html:129
 #: rhodecode/templates/admin/users/user_edit.html:154
-#: rhodecode/templates/admin/users/user_edit_my_account.html:102
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:115
 #: rhodecode/templates/settings/repo_settings.html:84
 msgid "Save"
@@ -1596,7 +1630,7 @@
 
 #: rhodecode/templates/admin/repos/repo_edit.html:13
 #: rhodecode/templates/admin/users/user_edit.html:13
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:13
 #: rhodecode/templates/files/files_source.html:32
 #: rhodecode/templates/journal/journal.html:72
@@ -1760,38 +1794,27 @@
 msgstr "repositório privado"
 
 #: rhodecode/templates/admin/repos/repo_edit_perms.html:33
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:53
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:58
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:23
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:42
 msgid "revoke"
 msgstr "revogar"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:75
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:80
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:64
 msgid "Add another member"
 msgstr "Adicionar outro membro"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:89
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:94
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:78
 msgid "Failed to remove user"
 msgstr "Falha ao reomver usuário"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:104
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:109
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:93
 msgid "Failed to remove users group"
 msgstr "Falha ao remover grupo de usuários"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:123
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:112
-msgid "Group"
-msgstr "Grupo"
-
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:124
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:113
-#: rhodecode/templates/admin/users_groups/users_groups.html:33
-msgid "members"
-msgstr "membros"
-
 #: rhodecode/templates/admin/repos/repos.html:5
 msgid "Repositories administration"
 msgstr "Administração de repositórios"
@@ -1809,7 +1832,7 @@
 msgstr "excluir"
 
 #: rhodecode/templates/admin/repos/repos.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:158
+#: rhodecode/templates/admin/users/user_edit_my_account.html:74
 #, python-format
 msgid "Confirm to delete this repository: %s"
 msgstr "Confirma excluir esse repositório: %s"
@@ -1860,7 +1883,7 @@
 #: rhodecode/templates/admin/settings/settings.html:177
 #: rhodecode/templates/admin/users/user_edit.html:130
 #: rhodecode/templates/admin/users/user_edit.html:155
-#: rhodecode/templates/admin/users/user_edit_my_account.html:103
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:80
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:116
 #: rhodecode/templates/files/files_add.html:82
 #: rhodecode/templates/files/files_edit.html:68
@@ -2090,17 +2113,17 @@
 msgstr "Editar usuário"
 
 #: rhodecode/templates/admin/users/user_edit.html:34
-#: rhodecode/templates/admin/users/user_edit_my_account.html:33
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:10
 msgid "Change your avatar at"
 msgstr "Altere o seu avatar em"
 
 #: rhodecode/templates/admin/users/user_edit.html:35
-#: rhodecode/templates/admin/users/user_edit_my_account.html:34
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:11
 msgid "Using"
 msgstr "Usando"
 
 #: rhodecode/templates/admin/users/user_edit.html:43
-#: rhodecode/templates/admin/users/user_edit_my_account.html:43
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:20
 msgid "API key"
 msgstr "Chave de API"
 
@@ -2109,12 +2132,12 @@
 msgstr "DN LDAP"
 
 #: rhodecode/templates/admin/users/user_edit.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:58
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:35
 msgid "New password"
 msgstr "Nova senha"
 
 #: rhodecode/templates/admin/users/user_edit.html:77
-#: rhodecode/templates/admin/users/user_edit_my_account.html:67
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:44
 msgid "New password confirmation"
 msgstr "Confirmação de nova senha"
 
@@ -2132,21 +2155,21 @@
 msgid "My Account"
 msgstr "Minha Conta"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #: rhodecode/templates/journal/journal.html:32
 msgid "My repos"
 msgstr "Meus repositórios"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 msgid "My permissions"
 msgstr "Minhas permissões"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:121
+#: rhodecode/templates/admin/users/user_edit_my_account.html:37
 #: rhodecode/templates/journal/journal.html:37
 msgid "ADD"
 msgstr "ADICIONAR"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:134
+#: rhodecode/templates/admin/users/user_edit_my_account.html:50
 #: rhodecode/templates/bookmarks/bookmarks.html:40
 #: rhodecode/templates/bookmarks/bookmarks_data.html:9
 #: rhodecode/templates/branches/branches.html:40
@@ -2156,23 +2179,23 @@
 msgid "Revision"
 msgstr "Revisão"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/journal/journal.html:72
 msgid "private"
 msgstr "privado"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:81
 #: rhodecode/templates/journal/journal.html:85
 msgid "No repositories yet"
 msgstr "Ainda não há repositórios"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:167
+#: rhodecode/templates/admin/users/user_edit_my_account.html:83
 #: rhodecode/templates/journal/journal.html:87
 msgid "create one now"
 msgstr "criar um agora"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:184
-#: rhodecode/templates/admin/users/user_edit_my_account.html:285
+#: rhodecode/templates/admin/users/user_edit_my_account.html:100
+#: rhodecode/templates/admin/users/user_edit_my_account.html:201
 msgid "Permission"
 msgstr "Permissão"
 
@@ -2273,6 +2296,11 @@
 msgid "group name"
 msgstr "nome do grupo"
 
+#: rhodecode/templates/admin/users_groups/users_groups.html:33
+#: rhodecode/templates/base/root.html:46
+msgid "members"
+msgstr "membros"
+
 #: rhodecode/templates/admin/users_groups/users_groups.html:45
 #, python-format
 msgid "Confirm to delete this users group: %s"
@@ -2432,21 +2460,25 @@
 msgid "Search"
 msgstr "Pesquisar"
 
-#: rhodecode/templates/base/root.html:53
+#: rhodecode/templates/base/root.html:42
 msgid "add another comment"
 msgstr "adicionar outro comentário"
 
-#: rhodecode/templates/base/root.html:54
+#: rhodecode/templates/base/root.html:43
 #: rhodecode/templates/journal/journal.html:111
 #: rhodecode/templates/summary/summary.html:52
 msgid "Stop following this repository"
 msgstr "Parar de seguir este repositório"
 
-#: rhodecode/templates/base/root.html:55
+#: rhodecode/templates/base/root.html:44
 #: rhodecode/templates/summary/summary.html:56
 msgid "Start following this repository"
 msgstr "Passar a seguir este repositório"
 
+#: rhodecode/templates/base/root.html:45
+msgid "Group"
+msgstr "Grupo"
+
 #: rhodecode/templates/bookmarks/bookmarks.html:5
 msgid "Bookmarks"
 msgstr "Marcadores"
@@ -2575,7 +2607,7 @@
 msgstr "descarregar diff"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "%d comment"
 msgid_plural "%d comments"
@@ -2583,7 +2615,7 @@
 msgstr[1] "%d comentários"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "(%d inline)"
 msgid_plural "(%d inline)"
@@ -2608,37 +2640,37 @@
 msgstr "Comentando a linha {1}."
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:39
-#: rhodecode/templates/changeset/changeset_file_comment.html:100
+#: rhodecode/templates/changeset/changeset_file_comment.html:102
 #, python-format
 msgid "Comments parsed using %s syntax with %s support."
 msgstr "Comentários interpretados usando a sintaxe %s com suporte a %s."
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:41
-#: rhodecode/templates/changeset/changeset_file_comment.html:102
+#: rhodecode/templates/changeset/changeset_file_comment.html:104
 msgid "Use @username inside this text to send notification to this RhodeCode user"
 msgstr ""
 "Use @nomedeusuário dentro desse texto para enviar notificação a este "
 "usuário do RhodeCode"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:47
-#: rhodecode/templates/changeset/changeset_file_comment.html:107
+#: rhodecode/templates/changeset/changeset_file_comment.html:49
+#: rhodecode/templates/changeset/changeset_file_comment.html:110
 msgid "Comment"
 msgstr "Comentário"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:48
-#: rhodecode/templates/changeset/changeset_file_comment.html:59
+#: rhodecode/templates/changeset/changeset_file_comment.html:50
+#: rhodecode/templates/changeset/changeset_file_comment.html:61
 msgid "Hide"
 msgstr "Ocultar"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "You need to be logged in to comment."
 msgstr "Você precisa estar logado para comentar."
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "Login now"
 msgstr "Entrar agora"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:97
+#: rhodecode/templates/changeset/changeset_file_comment.html:99
 msgid "Leave a comment"
 msgstr "Deixar um comentário"
 
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/i18n/rhodecode.pot
--- a/rhodecode/i18n/rhodecode.pot	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/i18n/rhodecode.pot	Tue Jun 05 21:22:23 2012 +0200
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: RhodeCode 1.4.0\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2012-05-27 17:41+0200\n"
+"POT-Creation-Date: 2012-06-03 01:06+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME \n"
 "Language-Team: LANGUAGE \n"
@@ -17,24 +17,24 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 0.9.6\n"
 
-#: rhodecode/controllers/changelog.py:96
+#: rhodecode/controllers/changelog.py:95
 msgid "All Branches"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:79
+#: rhodecode/controllers/changeset.py:80
 msgid "show white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:86 rhodecode/controllers/changeset.py:93
+#: rhodecode/controllers/changeset.py:87 rhodecode/controllers/changeset.py:94
 msgid "ignore white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:153
+#: rhodecode/controllers/changeset.py:154
 #, python-format
 msgid "%s line context"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:320 rhodecode/controllers/changeset.py:335
+#: rhodecode/controllers/changeset.py:324 rhodecode/controllers/changeset.py:339
 #: rhodecode/lib/diffs.py:62
 msgid "binary file"
 msgstr ""
@@ -179,7 +179,7 @@
 msgid "%s public journal %s feed"
 msgstr ""
 
-#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:224
+#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:223
 #: rhodecode/templates/admin/repos/repo_edit.html:177
 #: rhodecode/templates/base/base.html:307 rhodecode/templates/base/base.html:309
 #: rhodecode/templates/base/base.html:311
@@ -210,30 +210,30 @@
 msgid "An error occurred during this search operation"
 msgstr ""
 
-#: rhodecode/controllers/settings.py:103 rhodecode/controllers/admin/repos.py:211
+#: rhodecode/controllers/settings.py:103 rhodecode/controllers/admin/repos.py:213
 #, python-format
 msgid "Repository %s updated successfully"
 msgstr ""
 
-#: rhodecode/controllers/settings.py:121 rhodecode/controllers/admin/repos.py:229
+#: rhodecode/controllers/settings.py:121 rhodecode/controllers/admin/repos.py:231
 #, python-format
 msgid "error occurred during update of repository %s"
 msgstr ""
 
-#: rhodecode/controllers/settings.py:139 rhodecode/controllers/admin/repos.py:247
+#: rhodecode/controllers/settings.py:139 rhodecode/controllers/admin/repos.py:249
 #, python-format
 msgid ""
 "%s repository is not mapped to db perhaps it was moved or renamed  from the "
 "filesystem please run the application again in order to rescan repositories"
 msgstr ""
 
-#: rhodecode/controllers/settings.py:151 rhodecode/controllers/admin/repos.py:259
+#: rhodecode/controllers/settings.py:151 rhodecode/controllers/admin/repos.py:261
 #, python-format
 msgid "deleted repository %s"
 msgstr ""
 
-#: rhodecode/controllers/settings.py:155 rhodecode/controllers/admin/repos.py:269
-#: rhodecode/controllers/admin/repos.py:275
+#: rhodecode/controllers/settings.py:155 rhodecode/controllers/admin/repos.py:271
+#: rhodecode/controllers/admin/repos.py:277
 #, python-format
 msgid "An error occurred during deletion of %s"
 msgstr ""
@@ -380,62 +380,62 @@
 msgid "created repository %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:177
+#: rhodecode/controllers/admin/repos.py:179
 #, python-format
 msgid "error occurred during creation of repository %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:264
+#: rhodecode/controllers/admin/repos.py:266
 #, python-format
 msgid "Cannot delete %s it still contains attached forks"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:293
+#: rhodecode/controllers/admin/repos.py:295
 msgid "An error occurred during deletion of repository user"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:312
+#: rhodecode/controllers/admin/repos.py:314
 msgid "An error occurred during deletion of repository users groups"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:329
+#: rhodecode/controllers/admin/repos.py:331
 msgid "An error occurred during deletion of repository stats"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:345
+#: rhodecode/controllers/admin/repos.py:347
 msgid "An error occurred during cache invalidation"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:365
+#: rhodecode/controllers/admin/repos.py:367
 msgid "Updated repository visibility in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:369
+#: rhodecode/controllers/admin/repos.py:371
 msgid "An error occurred during setting this repository in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:374 rhodecode/model/forms.py:54
+#: rhodecode/controllers/admin/repos.py:376 rhodecode/model/forms.py:54
 msgid "Token mismatch"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:387
-msgid "Pulled from remote location"
-msgstr ""
-
 #: rhodecode/controllers/admin/repos.py:389
+msgid "Pulled from remote location"
+msgstr ""
+
+#: rhodecode/controllers/admin/repos.py:391
 msgid "An error occurred during pull from remote location"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:405
-msgid "Nothing"
-msgstr ""
-
 #: rhodecode/controllers/admin/repos.py:407
+msgid "Nothing"
+msgstr ""
+
+#: rhodecode/controllers/admin/repos.py:409
 #, python-format
 msgid "Marked repo %s as fork of %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:411
+#: rhodecode/controllers/admin/repos.py:413
 msgid "An error occurred during this operation"
 msgstr ""
 
@@ -529,77 +529,77 @@
 msgid "You can't edit this user since it's crucial for entire application"
 msgstr ""
 
-#: rhodecode/controllers/admin/settings.py:365
+#: rhodecode/controllers/admin/settings.py:367
 msgid "Your account was updated successfully"
 msgstr ""
 
-#: rhodecode/controllers/admin/settings.py:384
-#: rhodecode/controllers/admin/users.py:132
+#: rhodecode/controllers/admin/settings.py:387
+#: rhodecode/controllers/admin/users.py:138
 #, python-format
 msgid "error occurred during update of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:79
+#: rhodecode/controllers/admin/users.py:83
 #, python-format
 msgid "created user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:92
+#: rhodecode/controllers/admin/users.py:95
 #, python-format
 msgid "error occurred during creation of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:118
+#: rhodecode/controllers/admin/users.py:124
 msgid "User updated successfully"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:149
+#: rhodecode/controllers/admin/users.py:155
 msgid "successfully deleted user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:154
+#: rhodecode/controllers/admin/users.py:160
 msgid "An error occurred during deletion of user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:169
+#: rhodecode/controllers/admin/users.py:175
 msgid "You can't edit this user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:199
-#: rhodecode/controllers/admin/users_groups.py:215
+#: rhodecode/controllers/admin/users.py:205
+#: rhodecode/controllers/admin/users_groups.py:219
 msgid "Granted 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:208
-#: rhodecode/controllers/admin/users_groups.py:225
+#: rhodecode/controllers/admin/users.py:214
+#: rhodecode/controllers/admin/users_groups.py:229
 msgid "Revoked 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:79
+#: rhodecode/controllers/admin/users_groups.py:84
 #, python-format
 msgid "created users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:92
+#: rhodecode/controllers/admin/users_groups.py:95
 #, python-format
 msgid "error occurred during creation of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:128
+#: rhodecode/controllers/admin/users_groups.py:135
 #, python-format
 msgid "updated users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:148
+#: rhodecode/controllers/admin/users_groups.py:152
 #, python-format
 msgid "error occurred during update of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:165
+#: rhodecode/controllers/admin/users_groups.py:169
 msgid "successfully deleted users group"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:170
+#: rhodecode/controllers/admin/users_groups.py:174
 msgid "An error occurred during deletion of users group"
 msgstr ""
 
@@ -657,60 +657,80 @@
 msgid "fork name "
 msgstr ""
 
-#: rhodecode/lib/helpers.py:540
+#: rhodecode/lib/helpers.py:550
 msgid "[deleted] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:541 rhodecode/lib/helpers.py:546
+#: rhodecode/lib/helpers.py:552 rhodecode/lib/helpers.py:562
 msgid "[created] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:542
-msgid "[created] repository as fork"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:543 rhodecode/lib/helpers.py:547
-msgid "[forked] repository"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:544 rhodecode/lib/helpers.py:548
-msgid "[updated] repository"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:545
-msgid "[delete] repository"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:549
-msgid "[pushed] into"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:550
-msgid "[committed via RhodeCode] into"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:551
-msgid "[pulled from remote] into"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:552
-msgid "[pulled] from"
-msgstr ""
-
-#: rhodecode/lib/helpers.py:553
-msgid "[started following] repository"
-msgstr ""
-
 #: rhodecode/lib/helpers.py:554
+msgid "[created] repository as fork"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:556 rhodecode/lib/helpers.py:564
+msgid "[forked] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:558 rhodecode/lib/helpers.py:566
+msgid "[updated] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:560
+msgid "[delete] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:568
+msgid "[created] user"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:570
+msgid "[updated] user"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:572
+msgid "[created] users group"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:574
+msgid "[updated] users group"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:576
+msgid "[commented] on revision in repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:578
+msgid "[pushed] into"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:580
+msgid "[committed via RhodeCode] into repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:582
+msgid "[pulled from remote] into repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:584
+msgid "[pulled] from"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:586
+msgid "[started following] repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:588
 msgid "[stopped following] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:732
+#: rhodecode/lib/helpers.py:752
 #, python-format
 msgid " and %s more"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:736
+#: rhodecode/lib/helpers.py:756
 msgid "No Files"
 msgstr ""
 
@@ -958,7 +978,7 @@
 msgstr ""
 
 #: rhodecode/templates/index_base.html:6
-#: rhodecode/templates/admin/users/user_edit_my_account.html:115
+#: rhodecode/templates/admin/users/user_edit_my_account.html:31
 #: rhodecode/templates/bookmarks/bookmarks.html:10
 #: rhodecode/templates/branches/branches.html:9
 #: rhodecode/templates/journal/journal.html:31
@@ -1009,10 +1029,10 @@
 #: rhodecode/templates/admin/repos/repo_edit.html:32
 #: rhodecode/templates/admin/repos/repos.html:36
 #: rhodecode/templates/admin/repos/repos.html:82
-#: rhodecode/templates/admin/users/user_edit_my_account.html:133
-#: rhodecode/templates/admin/users/user_edit_my_account.html:183
-#: rhodecode/templates/admin/users/user_edit_my_account.html:249
-#: rhodecode/templates/admin/users/user_edit_my_account.html:284
+#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account.html:99
+#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:200
 #: rhodecode/templates/bookmarks/bookmarks.html:36
 #: rhodecode/templates/bookmarks/bookmarks_data.html:6
 #: rhodecode/templates/branches/branches.html:36
@@ -1035,7 +1055,7 @@
 #: rhodecode/templates/index_base.html:69 rhodecode/templates/index_base.html:161
 #: rhodecode/templates/admin/repos/repos.html:39
 #: rhodecode/templates/admin/repos/repos.html:87
-#: rhodecode/templates/admin/users/user_edit_my_account.html:251
+#: rhodecode/templates/admin/users/user_edit_my_account.html:167
 #: rhodecode/templates/journal/journal.html:179
 msgid "Tip"
 msgstr ""
@@ -1074,7 +1094,7 @@
 
 #: rhodecode/templates/index_base.html:148 rhodecode/templates/index_base.html:188
 #: rhodecode/templates/admin/repos/repos.html:112
-#: rhodecode/templates/admin/users/user_edit_my_account.html:270
+#: rhodecode/templates/admin/users/user_edit_my_account.html:186
 #: rhodecode/templates/bookmarks/bookmarks.html:60
 #: rhodecode/templates/branches/branches.html:60
 #: rhodecode/templates/journal/journal.html:202
@@ -1084,7 +1104,7 @@
 
 #: rhodecode/templates/index_base.html:149 rhodecode/templates/index_base.html:189
 #: rhodecode/templates/admin/repos/repos.html:113
-#: rhodecode/templates/admin/users/user_edit_my_account.html:271
+#: rhodecode/templates/admin/users/user_edit_my_account.html:187
 #: rhodecode/templates/bookmarks/bookmarks.html:61
 #: rhodecode/templates/branches/branches.html:61
 #: rhodecode/templates/journal/journal.html:203
@@ -1099,7 +1119,7 @@
 
 #: rhodecode/templates/index_base.html:190
 #: rhodecode/templates/admin/repos/repos.html:114
-#: rhodecode/templates/admin/users/user_edit_my_account.html:272
+#: rhodecode/templates/admin/users/user_edit_my_account.html:188
 #: rhodecode/templates/bookmarks/bookmarks.html:62
 #: rhodecode/templates/branches/branches.html:62
 #: rhodecode/templates/journal/journal.html:204
@@ -1109,7 +1129,7 @@
 
 #: rhodecode/templates/index_base.html:191
 #: rhodecode/templates/admin/repos/repos.html:115
-#: rhodecode/templates/admin/users/user_edit_my_account.html:273
+#: rhodecode/templates/admin/users/user_edit_my_account.html:189
 #: rhodecode/templates/bookmarks/bookmarks.html:63
 #: rhodecode/templates/branches/branches.html:63
 #: rhodecode/templates/journal/journal.html:205
@@ -1119,7 +1139,7 @@
 
 #: rhodecode/templates/index_base.html:192
 #: rhodecode/templates/admin/repos/repos.html:116
-#: rhodecode/templates/admin/users/user_edit_my_account.html:274
+#: rhodecode/templates/admin/users/user_edit_my_account.html:190
 #: rhodecode/templates/bookmarks/bookmarks.html:64
 #: rhodecode/templates/branches/branches.html:64
 #: rhodecode/templates/journal/journal.html:206
@@ -1139,7 +1159,7 @@
 #: rhodecode/templates/admin/admin_log.html:5
 #: rhodecode/templates/admin/users/user_add.html:32
 #: rhodecode/templates/admin/users/user_edit.html:50
-#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:26
 #: rhodecode/templates/base/base.html:83
 #: rhodecode/templates/summary/summary.html:113
 msgid "Username"
@@ -1199,21 +1219,21 @@
 #: rhodecode/templates/register.html:47
 #: rhodecode/templates/admin/users/user_add.html:59
 #: rhodecode/templates/admin/users/user_edit.html:86
-#: rhodecode/templates/admin/users/user_edit_my_account.html:76
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:53
 msgid "First Name"
 msgstr ""
 
 #: rhodecode/templates/register.html:56
 #: rhodecode/templates/admin/users/user_add.html:68
 #: rhodecode/templates/admin/users/user_edit.html:95
-#: rhodecode/templates/admin/users/user_edit_my_account.html:85
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:62
 msgid "Last Name"
 msgstr ""
 
 #: rhodecode/templates/register.html:65
 #: rhodecode/templates/admin/users/user_add.html:77
 #: rhodecode/templates/admin/users/user_edit.html:104
-#: rhodecode/templates/admin/users/user_edit_my_account.html:94
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:71
 #: rhodecode/templates/summary/summary.html:115
 msgid "Email"
 msgstr ""
@@ -1275,8 +1295,8 @@
 #: rhodecode/templates/admin/admin_log.html:6
 #: rhodecode/templates/admin/repos/repos.html:41
 #: rhodecode/templates/admin/repos/repos.html:90
-#: rhodecode/templates/admin/users/user_edit_my_account.html:135
-#: rhodecode/templates/admin/users/user_edit_my_account.html:136
+#: rhodecode/templates/admin/users/user_edit_my_account.html:51
+#: rhodecode/templates/admin/users/user_edit_my_account.html:52
 #: rhodecode/templates/journal/journal.html:52
 #: rhodecode/templates/journal/journal.html:53
 msgid "Action"
@@ -1298,7 +1318,7 @@
 msgid "From IP"
 msgstr ""
 
-#: rhodecode/templates/admin/admin_log.html:52
+#: rhodecode/templates/admin/admin_log.html:53
 msgid "No actions yet"
 msgstr ""
 
@@ -1379,7 +1399,7 @@
 #: rhodecode/templates/admin/settings/hooks.html:73
 #: rhodecode/templates/admin/users/user_edit.html:129
 #: rhodecode/templates/admin/users/user_edit.html:154
-#: rhodecode/templates/admin/users/user_edit_my_account.html:102
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:115
 #: rhodecode/templates/settings/repo_settings.html:84
 msgid "Save"
@@ -1531,7 +1551,7 @@
 
 #: rhodecode/templates/admin/repos/repo_edit.html:13
 #: rhodecode/templates/admin/users/user_edit.html:13
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:13
 #: rhodecode/templates/files/files_source.html:32
 #: rhodecode/templates/journal/journal.html:72
@@ -1689,38 +1709,27 @@
 msgstr ""
 
 #: rhodecode/templates/admin/repos/repo_edit_perms.html:33
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:53
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:58
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:23
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:42
 msgid "revoke"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:75
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:80
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:64
 msgid "Add another member"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:89
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:94
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:78
 msgid "Failed to remove user"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:104
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:109
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:93
 msgid "Failed to remove users group"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:123
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:112
-msgid "Group"
-msgstr ""
-
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:124
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:113
-#: rhodecode/templates/admin/users_groups/users_groups.html:33
-msgid "members"
-msgstr ""
-
 #: rhodecode/templates/admin/repos/repos.html:5
 msgid "Repositories administration"
 msgstr ""
@@ -1738,7 +1747,7 @@
 msgstr ""
 
 #: rhodecode/templates/admin/repos/repos.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:158
+#: rhodecode/templates/admin/users/user_edit_my_account.html:74
 #, python-format
 msgid "Confirm to delete this repository: %s"
 msgstr ""
@@ -1789,7 +1798,7 @@
 #: rhodecode/templates/admin/settings/settings.html:177
 #: rhodecode/templates/admin/users/user_edit.html:130
 #: rhodecode/templates/admin/users/user_edit.html:155
-#: rhodecode/templates/admin/users/user_edit_my_account.html:103
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:80
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:116
 #: rhodecode/templates/files/files_add.html:82
 #: rhodecode/templates/files/files_edit.html:68
@@ -2013,17 +2022,17 @@
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:34
-#: rhodecode/templates/admin/users/user_edit_my_account.html:33
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:10
 msgid "Change your avatar at"
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:35
-#: rhodecode/templates/admin/users/user_edit_my_account.html:34
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:11
 msgid "Using"
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:43
-#: rhodecode/templates/admin/users/user_edit_my_account.html:43
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:20
 msgid "API key"
 msgstr ""
 
@@ -2032,12 +2041,12 @@
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:58
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:35
 msgid "New password"
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:77
-#: rhodecode/templates/admin/users/user_edit_my_account.html:67
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:44
 msgid "New password confirmation"
 msgstr ""
 
@@ -2055,21 +2064,21 @@
 msgid "My Account"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #: rhodecode/templates/journal/journal.html:32
 msgid "My repos"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 msgid "My permissions"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:121
+#: rhodecode/templates/admin/users/user_edit_my_account.html:37
 #: rhodecode/templates/journal/journal.html:37
 msgid "ADD"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:134
+#: rhodecode/templates/admin/users/user_edit_my_account.html:50
 #: rhodecode/templates/bookmarks/bookmarks.html:40
 #: rhodecode/templates/bookmarks/bookmarks_data.html:9
 #: rhodecode/templates/branches/branches.html:40
@@ -2078,23 +2087,23 @@
 msgid "Revision"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/journal/journal.html:72
 msgid "private"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:81
 #: rhodecode/templates/journal/journal.html:85
 msgid "No repositories yet"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:167
+#: rhodecode/templates/admin/users/user_edit_my_account.html:83
 #: rhodecode/templates/journal/journal.html:87
 msgid "create one now"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:184
-#: rhodecode/templates/admin/users/user_edit_my_account.html:285
+#: rhodecode/templates/admin/users/user_edit_my_account.html:100
+#: rhodecode/templates/admin/users/user_edit_my_account.html:201
 msgid "Permission"
 msgstr ""
 
@@ -2195,6 +2204,11 @@
 msgid "group name"
 msgstr ""
 
+#: rhodecode/templates/admin/users_groups/users_groups.html:33
+#: rhodecode/templates/base/root.html:46
+msgid "members"
+msgstr ""
+
 #: rhodecode/templates/admin/users_groups/users_groups.html:45
 #, python-format
 msgid "Confirm to delete this users group: %s"
@@ -2338,21 +2352,25 @@
 msgid "Search"
 msgstr ""
 
-#: rhodecode/templates/base/root.html:53
+#: rhodecode/templates/base/root.html:42
 msgid "add another comment"
 msgstr ""
 
-#: rhodecode/templates/base/root.html:54
+#: rhodecode/templates/base/root.html:43
 #: rhodecode/templates/journal/journal.html:111
 #: rhodecode/templates/summary/summary.html:52
 msgid "Stop following this repository"
 msgstr ""
 
-#: rhodecode/templates/base/root.html:55
+#: rhodecode/templates/base/root.html:44
 #: rhodecode/templates/summary/summary.html:56
 msgid "Start following this repository"
 msgstr ""
 
+#: rhodecode/templates/base/root.html:45
+msgid "Group"
+msgstr ""
+
 #: rhodecode/templates/bookmarks/bookmarks.html:5
 msgid "Bookmarks"
 msgstr ""
@@ -2480,7 +2498,7 @@
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "%d comment"
 msgid_plural "%d comments"
@@ -2488,7 +2506,7 @@
 msgstr[1] ""
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "(%d inline)"
 msgid_plural "(%d inline)"
@@ -2513,35 +2531,35 @@
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:39
-#: rhodecode/templates/changeset/changeset_file_comment.html:100
+#: rhodecode/templates/changeset/changeset_file_comment.html:102
 #, python-format
 msgid "Comments parsed using %s syntax with %s support."
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:41
-#: rhodecode/templates/changeset/changeset_file_comment.html:102
+#: rhodecode/templates/changeset/changeset_file_comment.html:104
 msgid "Use @username inside this text to send notification to this RhodeCode user"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:47
-#: rhodecode/templates/changeset/changeset_file_comment.html:107
+#: rhodecode/templates/changeset/changeset_file_comment.html:49
+#: rhodecode/templates/changeset/changeset_file_comment.html:110
 msgid "Comment"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:48
-#: rhodecode/templates/changeset/changeset_file_comment.html:59
+#: rhodecode/templates/changeset/changeset_file_comment.html:50
+#: rhodecode/templates/changeset/changeset_file_comment.html:61
 msgid "Hide"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "You need to be logged in to comment."
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "Login now"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:97
+#: rhodecode/templates/changeset/changeset_file_comment.html:99
 msgid "Leave a comment"
 msgstr ""
 
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/i18n/zh_CN/LC_MESSAGES/rhodecode.po
--- a/rhodecode/i18n/zh_CN/LC_MESSAGES/rhodecode.po	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/i18n/zh_CN/LC_MESSAGES/rhodecode.po	Tue Jun 05 21:22:23 2012 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: RhodeCode 1.2.0\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2012-05-27 17:41+0200\n"
+"POT-Creation-Date: 2012-06-03 01:06+0200\n"
 "PO-Revision-Date: 2012-04-05 17:37+0800\n"
 "Last-Translator: mikespook \n"
 "Language-Team: mikespook\n"
@@ -17,26 +17,26 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 0.9.6\n"
 
-#: rhodecode/controllers/changelog.py:96
+#: rhodecode/controllers/changelog.py:95
 #, fuzzy
 msgid "All Branches"
 msgstr "分支"
 
-#: rhodecode/controllers/changeset.py:79
+#: rhodecode/controllers/changeset.py:80
 msgid "show white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:86 rhodecode/controllers/changeset.py:93
+#: rhodecode/controllers/changeset.py:87 rhodecode/controllers/changeset.py:94
 msgid "ignore white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:153
+#: rhodecode/controllers/changeset.py:154
 #, fuzzy, python-format
 msgid "%s line context"
 msgstr "文件内容"
 
-#: rhodecode/controllers/changeset.py:320
-#: rhodecode/controllers/changeset.py:335 rhodecode/lib/diffs.py:62
+#: rhodecode/controllers/changeset.py:324
+#: rhodecode/controllers/changeset.py:339 rhodecode/lib/diffs.py:62
 msgid "binary file"
 msgstr "二进制文件"
 
@@ -184,7 +184,7 @@
 msgid "%s public journal %s feed"
 msgstr "公共日志 %s %s 订阅"
 
-#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:224
+#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:223
 #: rhodecode/templates/admin/repos/repo_edit.html:177
 #: rhodecode/templates/base/base.html:307
 #: rhodecode/templates/base/base.html:309
@@ -219,19 +219,19 @@
 msgstr "在搜索操作中发生异常"
 
 #: rhodecode/controllers/settings.py:103
-#: rhodecode/controllers/admin/repos.py:211
+#: rhodecode/controllers/admin/repos.py:213
 #, python-format
 msgid "Repository %s updated successfully"
 msgstr "版本库 %s 成功更新"
 
 #: rhodecode/controllers/settings.py:121
-#: rhodecode/controllers/admin/repos.py:229
+#: rhodecode/controllers/admin/repos.py:231
 #, python-format
 msgid "error occurred during update of repository %s"
 msgstr ""
 
 #: rhodecode/controllers/settings.py:139
-#: rhodecode/controllers/admin/repos.py:247
+#: rhodecode/controllers/admin/repos.py:249
 #, python-format
 msgid ""
 "%s repository is not mapped to db perhaps it was moved or renamed  from "
@@ -240,14 +240,14 @@
 msgstr ""
 
 #: rhodecode/controllers/settings.py:151
-#: rhodecode/controllers/admin/repos.py:259
+#: rhodecode/controllers/admin/repos.py:261
 #, python-format
 msgid "deleted repository %s"
 msgstr "已经删除版本库 %s"
 
 #: rhodecode/controllers/settings.py:155
-#: rhodecode/controllers/admin/repos.py:269
-#: rhodecode/controllers/admin/repos.py:275
+#: rhodecode/controllers/admin/repos.py:271
+#: rhodecode/controllers/admin/repos.py:277
 #, python-format
 msgid "An error occurred during deletion of %s"
 msgstr ""
@@ -396,62 +396,62 @@
 msgid "created repository %s"
 msgstr "建立版本库 %s"
 
-#: rhodecode/controllers/admin/repos.py:177
+#: rhodecode/controllers/admin/repos.py:179
 #, python-format
 msgid "error occurred during creation of repository %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:264
+#: rhodecode/controllers/admin/repos.py:266
 #, python-format
 msgid "Cannot delete %s it still contains attached forks"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:293
+#: rhodecode/controllers/admin/repos.py:295
 msgid "An error occurred during deletion of repository user"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:312
+#: rhodecode/controllers/admin/repos.py:314
 msgid "An error occurred during deletion of repository users groups"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:329
+#: rhodecode/controllers/admin/repos.py:331
 msgid "An error occurred during deletion of repository stats"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:345
+#: rhodecode/controllers/admin/repos.py:347
 msgid "An error occurred during cache invalidation"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:365
+#: rhodecode/controllers/admin/repos.py:367
 msgid "Updated repository visibility in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:369
+#: rhodecode/controllers/admin/repos.py:371
 msgid "An error occurred during setting this repository in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:374 rhodecode/model/forms.py:54
+#: rhodecode/controllers/admin/repos.py:376 rhodecode/model/forms.py:54
 msgid "Token mismatch"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:387
-msgid "Pulled from remote location"
-msgstr ""
-
 #: rhodecode/controllers/admin/repos.py:389
-msgid "An error occurred during pull from remote location"
+msgid "Pulled from remote location"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:405
-msgid "Nothing"
+#: rhodecode/controllers/admin/repos.py:391
+msgid "An error occurred during pull from remote location"
 msgstr ""
 
 #: rhodecode/controllers/admin/repos.py:407
+msgid "Nothing"
+msgstr ""
+
+#: rhodecode/controllers/admin/repos.py:409
 #, fuzzy, python-format
 msgid "Marked repo %s as fork of %s"
 msgstr "新版本库 %s 基于 %s 建立。"
 
-#: rhodecode/controllers/admin/repos.py:411
+#: rhodecode/controllers/admin/repos.py:413
 #, fuzzy
 msgid "An error occurred during this operation"
 msgstr "在搜索操作中发生异常"
@@ -547,77 +547,77 @@
 msgid "You can't edit this user since it's crucial for entire application"
 msgstr ""
 
-#: rhodecode/controllers/admin/settings.py:365
+#: rhodecode/controllers/admin/settings.py:367
 msgid "Your account was updated successfully"
 msgstr "你的帐号已经更新完成"
 
-#: rhodecode/controllers/admin/settings.py:384
-#: rhodecode/controllers/admin/users.py:132
+#: rhodecode/controllers/admin/settings.py:387
+#: rhodecode/controllers/admin/users.py:138
 #, python-format
 msgid "error occurred during update of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:79
+#: rhodecode/controllers/admin/users.py:83
 #, python-format
 msgid "created user %s"
 msgstr "创建用户 %s"
 
-#: rhodecode/controllers/admin/users.py:92
+#: rhodecode/controllers/admin/users.py:95
 #, python-format
 msgid "error occurred during creation of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:118
+#: rhodecode/controllers/admin/users.py:124
 msgid "User updated successfully"
 msgstr "用户更新成功"
 
-#: rhodecode/controllers/admin/users.py:149
+#: rhodecode/controllers/admin/users.py:155
 msgid "successfully deleted user"
 msgstr "用户删除成功"
 
-#: rhodecode/controllers/admin/users.py:154
+#: rhodecode/controllers/admin/users.py:160
 msgid "An error occurred during deletion of user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:169
+#: rhodecode/controllers/admin/users.py:175
 msgid "You can't edit this user"
 msgstr "无法编辑该用户"
 
-#: rhodecode/controllers/admin/users.py:199
-#: rhodecode/controllers/admin/users_groups.py:215
+#: rhodecode/controllers/admin/users.py:205
+#: rhodecode/controllers/admin/users_groups.py:219
 msgid "Granted 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:208
-#: rhodecode/controllers/admin/users_groups.py:225
+#: rhodecode/controllers/admin/users.py:214
+#: rhodecode/controllers/admin/users_groups.py:229
 msgid "Revoked 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:79
+#: rhodecode/controllers/admin/users_groups.py:84
 #, python-format
 msgid "created users group %s"
 msgstr "建立用户组 %s"
 
-#: rhodecode/controllers/admin/users_groups.py:92
+#: rhodecode/controllers/admin/users_groups.py:95
 #, python-format
 msgid "error occurred during creation of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:128
+#: rhodecode/controllers/admin/users_groups.py:135
 #, python-format
 msgid "updated users group %s"
 msgstr "更新用户组 %s"
 
-#: rhodecode/controllers/admin/users_groups.py:148
+#: rhodecode/controllers/admin/users_groups.py:152
 #, python-format
 msgid "error occurred during update of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:165
+#: rhodecode/controllers/admin/users_groups.py:169
 msgid "successfully deleted users group"
 msgstr "删除用户组成功"
 
-#: rhodecode/controllers/admin/users_groups.py:170
+#: rhodecode/controllers/admin/users_groups.py:174
 msgid "An error occurred during deletion of users group"
 msgstr ""
 
@@ -677,61 +677,89 @@
 msgid "fork name "
 msgstr "分支名称"
 
-#: rhodecode/lib/helpers.py:540
+#: rhodecode/lib/helpers.py:550
 msgid "[deleted] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:541 rhodecode/lib/helpers.py:546
+#: rhodecode/lib/helpers.py:552 rhodecode/lib/helpers.py:562
 msgid "[created] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:542
+#: rhodecode/lib/helpers.py:554
 #, fuzzy
 msgid "[created] repository as fork"
 msgstr "建立版本库 %s"
 
-#: rhodecode/lib/helpers.py:543 rhodecode/lib/helpers.py:547
+#: rhodecode/lib/helpers.py:556 rhodecode/lib/helpers.py:564
 msgid "[forked] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:544 rhodecode/lib/helpers.py:548
+#: rhodecode/lib/helpers.py:558 rhodecode/lib/helpers.py:566
 msgid "[updated] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:545
+#: rhodecode/lib/helpers.py:560
 msgid "[delete] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:549
+#: rhodecode/lib/helpers.py:568
+#, fuzzy, python-format
+#| msgid "created user %s"
+msgid "[created] user"
+msgstr "创建用户 %s"
+
+#: rhodecode/lib/helpers.py:570
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] user"
+msgstr "更新用户组 %s"
+
+#: rhodecode/lib/helpers.py:572
+#, fuzzy, python-format
+#| msgid "created users group %s"
+msgid "[created] users group"
+msgstr "建立用户组 %s"
+
+#: rhodecode/lib/helpers.py:574
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] users group"
+msgstr "更新用户组 %s"
+
+#: rhodecode/lib/helpers.py:576
+msgid "[commented] on revision in repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:578
 msgid "[pushed] into"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:550
-msgid "[committed via RhodeCode] into"
+#: rhodecode/lib/helpers.py:580
+msgid "[committed via RhodeCode] into repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:551
-msgid "[pulled from remote] into"
+#: rhodecode/lib/helpers.py:582
+msgid "[pulled from remote] into repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:552
+#: rhodecode/lib/helpers.py:584
 msgid "[pulled] from"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:553
+#: rhodecode/lib/helpers.py:586
 msgid "[started following] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:554
+#: rhodecode/lib/helpers.py:588
 msgid "[stopped following] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:732
+#: rhodecode/lib/helpers.py:752
 #, python-format
 msgid " and %s more"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:736
+#: rhodecode/lib/helpers.py:756
 msgid "No Files"
 msgstr "没有文件"
 
@@ -979,7 +1007,7 @@
 msgstr ""
 
 #: rhodecode/templates/index_base.html:6
-#: rhodecode/templates/admin/users/user_edit_my_account.html:115
+#: rhodecode/templates/admin/users/user_edit_my_account.html:31
 #: rhodecode/templates/bookmarks/bookmarks.html:10
 #: rhodecode/templates/branches/branches.html:9
 #: rhodecode/templates/journal/journal.html:31
@@ -1034,10 +1062,10 @@
 #: rhodecode/templates/admin/repos/repo_edit.html:32
 #: rhodecode/templates/admin/repos/repos.html:36
 #: rhodecode/templates/admin/repos/repos.html:82
-#: rhodecode/templates/admin/users/user_edit_my_account.html:133
-#: rhodecode/templates/admin/users/user_edit_my_account.html:183
-#: rhodecode/templates/admin/users/user_edit_my_account.html:249
-#: rhodecode/templates/admin/users/user_edit_my_account.html:284
+#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account.html:99
+#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:200
 #: rhodecode/templates/bookmarks/bookmarks.html:36
 #: rhodecode/templates/bookmarks/bookmarks_data.html:6
 #: rhodecode/templates/branches/branches.html:36
@@ -1062,7 +1090,7 @@
 #: rhodecode/templates/index_base.html:161
 #: rhodecode/templates/admin/repos/repos.html:39
 #: rhodecode/templates/admin/repos/repos.html:87
-#: rhodecode/templates/admin/users/user_edit_my_account.html:251
+#: rhodecode/templates/admin/users/user_edit_my_account.html:167
 #: rhodecode/templates/journal/journal.html:179
 msgid "Tip"
 msgstr ""
@@ -1106,7 +1134,7 @@
 #: rhodecode/templates/index_base.html:148
 #: rhodecode/templates/index_base.html:188
 #: rhodecode/templates/admin/repos/repos.html:112
-#: rhodecode/templates/admin/users/user_edit_my_account.html:270
+#: rhodecode/templates/admin/users/user_edit_my_account.html:186
 #: rhodecode/templates/bookmarks/bookmarks.html:60
 #: rhodecode/templates/branches/branches.html:60
 #: rhodecode/templates/journal/journal.html:202
@@ -1117,7 +1145,7 @@
 #: rhodecode/templates/index_base.html:149
 #: rhodecode/templates/index_base.html:189
 #: rhodecode/templates/admin/repos/repos.html:113
-#: rhodecode/templates/admin/users/user_edit_my_account.html:271
+#: rhodecode/templates/admin/users/user_edit_my_account.html:187
 #: rhodecode/templates/bookmarks/bookmarks.html:61
 #: rhodecode/templates/branches/branches.html:61
 #: rhodecode/templates/journal/journal.html:203
@@ -1133,7 +1161,7 @@
 
 #: rhodecode/templates/index_base.html:190
 #: rhodecode/templates/admin/repos/repos.html:114
-#: rhodecode/templates/admin/users/user_edit_my_account.html:272
+#: rhodecode/templates/admin/users/user_edit_my_account.html:188
 #: rhodecode/templates/bookmarks/bookmarks.html:62
 #: rhodecode/templates/branches/branches.html:62
 #: rhodecode/templates/journal/journal.html:204
@@ -1143,7 +1171,7 @@
 
 #: rhodecode/templates/index_base.html:191
 #: rhodecode/templates/admin/repos/repos.html:115
-#: rhodecode/templates/admin/users/user_edit_my_account.html:273
+#: rhodecode/templates/admin/users/user_edit_my_account.html:189
 #: rhodecode/templates/bookmarks/bookmarks.html:63
 #: rhodecode/templates/branches/branches.html:63
 #: rhodecode/templates/journal/journal.html:205
@@ -1153,7 +1181,7 @@
 
 #: rhodecode/templates/index_base.html:192
 #: rhodecode/templates/admin/repos/repos.html:116
-#: rhodecode/templates/admin/users/user_edit_my_account.html:274
+#: rhodecode/templates/admin/users/user_edit_my_account.html:190
 #: rhodecode/templates/bookmarks/bookmarks.html:64
 #: rhodecode/templates/branches/branches.html:64
 #: rhodecode/templates/journal/journal.html:206
@@ -1174,7 +1202,7 @@
 #: rhodecode/templates/admin/admin_log.html:5
 #: rhodecode/templates/admin/users/user_add.html:32
 #: rhodecode/templates/admin/users/user_edit.html:50
-#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:26
 #: rhodecode/templates/base/base.html:83
 #: rhodecode/templates/summary/summary.html:113
 msgid "Username"
@@ -1235,21 +1263,21 @@
 #: rhodecode/templates/register.html:47
 #: rhodecode/templates/admin/users/user_add.html:59
 #: rhodecode/templates/admin/users/user_edit.html:86
-#: rhodecode/templates/admin/users/user_edit_my_account.html:76
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:53
 msgid "First Name"
 msgstr "名"
 
 #: rhodecode/templates/register.html:56
 #: rhodecode/templates/admin/users/user_add.html:68
 #: rhodecode/templates/admin/users/user_edit.html:95
-#: rhodecode/templates/admin/users/user_edit_my_account.html:85
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:62
 msgid "Last Name"
 msgstr "姓"
 
 #: rhodecode/templates/register.html:65
 #: rhodecode/templates/admin/users/user_add.html:77
 #: rhodecode/templates/admin/users/user_edit.html:104
-#: rhodecode/templates/admin/users/user_edit_my_account.html:94
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:71
 #: rhodecode/templates/summary/summary.html:115
 msgid "Email"
 msgstr "电子邮件"
@@ -1313,8 +1341,8 @@
 #: rhodecode/templates/admin/admin_log.html:6
 #: rhodecode/templates/admin/repos/repos.html:41
 #: rhodecode/templates/admin/repos/repos.html:90
-#: rhodecode/templates/admin/users/user_edit_my_account.html:135
-#: rhodecode/templates/admin/users/user_edit_my_account.html:136
+#: rhodecode/templates/admin/users/user_edit_my_account.html:51
+#: rhodecode/templates/admin/users/user_edit_my_account.html:52
 #: rhodecode/templates/journal/journal.html:52
 #: rhodecode/templates/journal/journal.html:53
 msgid "Action"
@@ -1337,7 +1365,7 @@
 msgid "From IP"
 msgstr "来源 IP"
 
-#: rhodecode/templates/admin/admin_log.html:52
+#: rhodecode/templates/admin/admin_log.html:53
 msgid "No actions yet"
 msgstr "尚无操作"
 
@@ -1418,7 +1446,7 @@
 #: rhodecode/templates/admin/settings/hooks.html:73
 #: rhodecode/templates/admin/users/user_edit.html:129
 #: rhodecode/templates/admin/users/user_edit.html:154
-#: rhodecode/templates/admin/users/user_edit_my_account.html:102
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:115
 #: rhodecode/templates/settings/repo_settings.html:84
 msgid "Save"
@@ -1574,7 +1602,7 @@
 
 #: rhodecode/templates/admin/repos/repo_edit.html:13
 #: rhodecode/templates/admin/users/user_edit.html:13
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:13
 #: rhodecode/templates/files/files_source.html:32
 #: rhodecode/templates/journal/journal.html:72
@@ -1733,38 +1761,27 @@
 msgstr "私有版本库"
 
 #: rhodecode/templates/admin/repos/repo_edit_perms.html:33
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:53
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:58
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:23
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:42
 msgid "revoke"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:75
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:80
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:64
 msgid "Add another member"
 msgstr "添加成员"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:89
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:94
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:78
 msgid "Failed to remove user"
 msgstr "删除用户失败"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:104
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:109
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:93
 msgid "Failed to remove users group"
 msgstr "删除用户组失败"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:123
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:112
-msgid "Group"
-msgstr "组"
-
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:124
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:113
-#: rhodecode/templates/admin/users_groups/users_groups.html:33
-msgid "members"
-msgstr "成员"
-
 #: rhodecode/templates/admin/repos/repos.html:5
 msgid "Repositories administration"
 msgstr "版本库管理员"
@@ -1782,7 +1799,7 @@
 msgstr "删除"
 
 #: rhodecode/templates/admin/repos/repos.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:158
+#: rhodecode/templates/admin/users/user_edit_my_account.html:74
 #, fuzzy, python-format
 msgid "Confirm to delete this repository: %s"
 msgstr "确认删除版本库"
@@ -1833,7 +1850,7 @@
 #: rhodecode/templates/admin/settings/settings.html:177
 #: rhodecode/templates/admin/users/user_edit.html:130
 #: rhodecode/templates/admin/users/user_edit.html:155
-#: rhodecode/templates/admin/users/user_edit_my_account.html:103
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:80
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:116
 #: rhodecode/templates/files/files_add.html:82
 #: rhodecode/templates/files/files_edit.html:68
@@ -2062,17 +2079,17 @@
 msgstr "编辑用户"
 
 #: rhodecode/templates/admin/users/user_edit.html:34
-#: rhodecode/templates/admin/users/user_edit_my_account.html:33
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:10
 msgid "Change your avatar at"
 msgstr "修改你的头像"
 
 #: rhodecode/templates/admin/users/user_edit.html:35
-#: rhodecode/templates/admin/users/user_edit_my_account.html:34
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:11
 msgid "Using"
 msgstr "使用中"
 
 #: rhodecode/templates/admin/users/user_edit.html:43
-#: rhodecode/templates/admin/users/user_edit_my_account.html:43
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:20
 msgid "API key"
 msgstr ""
 
@@ -2081,12 +2098,12 @@
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:58
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:35
 msgid "New password"
 msgstr "新密码"
 
 #: rhodecode/templates/admin/users/user_edit.html:77
-#: rhodecode/templates/admin/users/user_edit_my_account.html:67
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:44
 msgid "New password confirmation"
 msgstr ""
 
@@ -2104,24 +2121,24 @@
 msgid "My Account"
 msgstr "我的账户"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #: rhodecode/templates/journal/journal.html:32
 #, fuzzy
 msgid "My repos"
 msgstr "空版本库"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #, fuzzy
 msgid "My permissions"
 msgstr "权限"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:121
+#: rhodecode/templates/admin/users/user_edit_my_account.html:37
 #: rhodecode/templates/journal/journal.html:37
 #, fuzzy
 msgid "ADD"
 msgstr "新增"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:134
+#: rhodecode/templates/admin/users/user_edit_my_account.html:50
 #: rhodecode/templates/bookmarks/bookmarks.html:40
 #: rhodecode/templates/bookmarks/bookmarks_data.html:9
 #: rhodecode/templates/branches/branches.html:40
@@ -2131,23 +2148,23 @@
 msgid "Revision"
 msgstr "修订"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/journal/journal.html:72
 msgid "private"
 msgstr "私有"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:81
 #: rhodecode/templates/journal/journal.html:85
 msgid "No repositories yet"
 msgstr "没有任何版本库"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:167
+#: rhodecode/templates/admin/users/user_edit_my_account.html:83
 #: rhodecode/templates/journal/journal.html:87
 msgid "create one now"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:184
-#: rhodecode/templates/admin/users/user_edit_my_account.html:285
+#: rhodecode/templates/admin/users/user_edit_my_account.html:100
+#: rhodecode/templates/admin/users/user_edit_my_account.html:201
 #, fuzzy
 msgid "Permission"
 msgstr "权限"
@@ -2250,6 +2267,11 @@
 msgid "group name"
 msgstr "组名"
 
+#: rhodecode/templates/admin/users_groups/users_groups.html:33
+#: rhodecode/templates/base/root.html:46
+msgid "members"
+msgstr "成员"
+
 #: rhodecode/templates/admin/users_groups/users_groups.html:45
 #, fuzzy, python-format
 msgid "Confirm to delete this users group: %s"
@@ -2410,22 +2432,26 @@
 msgid "Search"
 msgstr "搜索"
 
-#: rhodecode/templates/base/root.html:53
+#: rhodecode/templates/base/root.html:42
 #, fuzzy
 msgid "add another comment"
 msgstr "添加成员"
 
-#: rhodecode/templates/base/root.html:54
+#: rhodecode/templates/base/root.html:43
 #: rhodecode/templates/journal/journal.html:111
 #: rhodecode/templates/summary/summary.html:52
 msgid "Stop following this repository"
 msgstr "停止跟随该版本库"
 
-#: rhodecode/templates/base/root.html:55
+#: rhodecode/templates/base/root.html:44
 #: rhodecode/templates/summary/summary.html:56
 msgid "Start following this repository"
 msgstr "开始跟随该版本库"
 
+#: rhodecode/templates/base/root.html:45
+msgid "Group"
+msgstr "组"
+
 #: rhodecode/templates/bookmarks/bookmarks.html:5
 msgid "Bookmarks"
 msgstr ""
@@ -2554,14 +2580,14 @@
 msgstr "下载 diff"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, fuzzy, python-format
 msgid "%d comment"
 msgid_plural "%d comments"
 msgstr[0] "提交"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "(%d inline)"
 msgid_plural "(%d inline)"
@@ -2585,37 +2611,37 @@
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:39
-#: rhodecode/templates/changeset/changeset_file_comment.html:100
+#: rhodecode/templates/changeset/changeset_file_comment.html:102
 #, python-format
 msgid "Comments parsed using %s syntax with %s support."
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:41
-#: rhodecode/templates/changeset/changeset_file_comment.html:102
+#: rhodecode/templates/changeset/changeset_file_comment.html:104
 msgid "Use @username inside this text to send notification to this RhodeCode user"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:47
-#: rhodecode/templates/changeset/changeset_file_comment.html:107
+#: rhodecode/templates/changeset/changeset_file_comment.html:49
+#: rhodecode/templates/changeset/changeset_file_comment.html:110
 #, fuzzy
 msgid "Comment"
 msgstr "提交"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:48
-#: rhodecode/templates/changeset/changeset_file_comment.html:59
+#: rhodecode/templates/changeset/changeset_file_comment.html:50
+#: rhodecode/templates/changeset/changeset_file_comment.html:61
 msgid "Hide"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 #, fuzzy
 msgid "You need to be logged in to comment."
 msgstr "必须登录才能访问该页面"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "Login now"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:97
+#: rhodecode/templates/changeset/changeset_file_comment.html:99
 msgid "Leave a comment"
 msgstr ""
 
@@ -3119,3 +3145,9 @@
 msgid "file removed"
 msgstr "文件已删除"
 
+#~ msgid "[committed via RhodeCode] into"
+#~ msgstr ""
+
+#~ msgid "[pulled from remote] into"
+#~ msgstr ""
+
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/i18n/zh_TW/LC_MESSAGES/rhodecode.po
--- a/rhodecode/i18n/zh_TW/LC_MESSAGES/rhodecode.po	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/i18n/zh_TW/LC_MESSAGES/rhodecode.po	Tue Jun 05 21:22:23 2012 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: RhodeCode 1.2.0\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2012-05-27 17:41+0200\n"
+"POT-Creation-Date: 2012-06-03 01:06+0200\n"
 "PO-Revision-Date: 2012-05-09 22:23+0800\n"
 "Last-Translator: Nansen \n"
 "Language-Team: zh_TW \n"
@@ -17,26 +17,26 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 0.9.6\n"
 
-#: rhodecode/controllers/changelog.py:96
+#: rhodecode/controllers/changelog.py:95
 #, fuzzy
 msgid "All Branches"
 msgstr "分支"
 
-#: rhodecode/controllers/changeset.py:79
+#: rhodecode/controllers/changeset.py:80
 msgid "show white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:86 rhodecode/controllers/changeset.py:93
+#: rhodecode/controllers/changeset.py:87 rhodecode/controllers/changeset.py:94
 msgid "ignore white space"
 msgstr ""
 
-#: rhodecode/controllers/changeset.py:153
+#: rhodecode/controllers/changeset.py:154
 #, fuzzy, python-format
 msgid "%s line context"
 msgstr "文件內容"
 
-#: rhodecode/controllers/changeset.py:320
-#: rhodecode/controllers/changeset.py:335 rhodecode/lib/diffs.py:62
+#: rhodecode/controllers/changeset.py:324
+#: rhodecode/controllers/changeset.py:339 rhodecode/lib/diffs.py:62
 msgid "binary file"
 msgstr "二進位檔"
 
@@ -184,7 +184,7 @@
 msgid "%s public journal %s feed"
 msgstr "%s 公開日誌 %s feed"
 
-#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:224
+#: rhodecode/controllers/journal.py:190 rhodecode/controllers/journal.py:223
 #: rhodecode/templates/admin/repos/repo_edit.html:177
 #: rhodecode/templates/base/base.html:307
 #: rhodecode/templates/base/base.html:309
@@ -219,19 +219,19 @@
 msgstr ""
 
 #: rhodecode/controllers/settings.py:103
-#: rhodecode/controllers/admin/repos.py:211
+#: rhodecode/controllers/admin/repos.py:213
 #, python-format
 msgid "Repository %s updated successfully"
 msgstr "版本庫 %s 更新完成"
 
 #: rhodecode/controllers/settings.py:121
-#: rhodecode/controllers/admin/repos.py:229
+#: rhodecode/controllers/admin/repos.py:231
 #, python-format
 msgid "error occurred during update of repository %s"
 msgstr ""
 
 #: rhodecode/controllers/settings.py:139
-#: rhodecode/controllers/admin/repos.py:247
+#: rhodecode/controllers/admin/repos.py:249
 #, python-format
 msgid ""
 "%s repository is not mapped to db perhaps it was moved or renamed  from "
@@ -240,14 +240,14 @@
 msgstr ""
 
 #: rhodecode/controllers/settings.py:151
-#: rhodecode/controllers/admin/repos.py:259
+#: rhodecode/controllers/admin/repos.py:261
 #, python-format
 msgid "deleted repository %s"
 msgstr "刪除版本庫 %s"
 
 #: rhodecode/controllers/settings.py:155
-#: rhodecode/controllers/admin/repos.py:269
-#: rhodecode/controllers/admin/repos.py:275
+#: rhodecode/controllers/admin/repos.py:271
+#: rhodecode/controllers/admin/repos.py:277
 #, python-format
 msgid "An error occurred during deletion of %s"
 msgstr ""
@@ -396,62 +396,62 @@
 msgid "created repository %s"
 msgstr "建立版本庫 %s"
 
-#: rhodecode/controllers/admin/repos.py:177
+#: rhodecode/controllers/admin/repos.py:179
 #, python-format
 msgid "error occurred during creation of repository %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:264
+#: rhodecode/controllers/admin/repos.py:266
 #, python-format
 msgid "Cannot delete %s it still contains attached forks"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:293
+#: rhodecode/controllers/admin/repos.py:295
 msgid "An error occurred during deletion of repository user"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:312
+#: rhodecode/controllers/admin/repos.py:314
 msgid "An error occurred during deletion of repository users groups"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:329
+#: rhodecode/controllers/admin/repos.py:331
 msgid "An error occurred during deletion of repository stats"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:345
+#: rhodecode/controllers/admin/repos.py:347
 msgid "An error occurred during cache invalidation"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:365
+#: rhodecode/controllers/admin/repos.py:367
 msgid "Updated repository visibility in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:369
+#: rhodecode/controllers/admin/repos.py:371
 msgid "An error occurred during setting this repository in public journal"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:374 rhodecode/model/forms.py:54
+#: rhodecode/controllers/admin/repos.py:376 rhodecode/model/forms.py:54
 msgid "Token mismatch"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:387
-msgid "Pulled from remote location"
-msgstr ""
-
 #: rhodecode/controllers/admin/repos.py:389
-msgid "An error occurred during pull from remote location"
+msgid "Pulled from remote location"
 msgstr ""
 
-#: rhodecode/controllers/admin/repos.py:405
-msgid "Nothing"
+#: rhodecode/controllers/admin/repos.py:391
+msgid "An error occurred during pull from remote location"
 msgstr ""
 
 #: rhodecode/controllers/admin/repos.py:407
+msgid "Nothing"
+msgstr ""
+
+#: rhodecode/controllers/admin/repos.py:409
 #, fuzzy, python-format
 msgid "Marked repo %s as fork of %s"
 msgstr "建立版本庫 %s 到 %s"
 
-#: rhodecode/controllers/admin/repos.py:411
+#: rhodecode/controllers/admin/repos.py:413
 msgid "An error occurred during this operation"
 msgstr ""
 
@@ -545,77 +545,77 @@
 msgid "You can't edit this user since it's crucial for entire application"
 msgstr ""
 
-#: rhodecode/controllers/admin/settings.py:365
+#: rhodecode/controllers/admin/settings.py:367
 msgid "Your account was updated successfully"
 msgstr "您的帳號已更新完成"
 
-#: rhodecode/controllers/admin/settings.py:384
-#: rhodecode/controllers/admin/users.py:132
+#: rhodecode/controllers/admin/settings.py:387
+#: rhodecode/controllers/admin/users.py:138
 #, python-format
 msgid "error occurred during update of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:79
+#: rhodecode/controllers/admin/users.py:83
 #, python-format
 msgid "created user %s"
 msgstr "建立使用者 %s"
 
-#: rhodecode/controllers/admin/users.py:92
+#: rhodecode/controllers/admin/users.py:95
 #, python-format
 msgid "error occurred during creation of user %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:118
+#: rhodecode/controllers/admin/users.py:124
 msgid "User updated successfully"
 msgstr "使用者更新完成"
 
-#: rhodecode/controllers/admin/users.py:149
+#: rhodecode/controllers/admin/users.py:155
 msgid "successfully deleted user"
 msgstr "成功刪除使用者"
 
-#: rhodecode/controllers/admin/users.py:154
+#: rhodecode/controllers/admin/users.py:160
 msgid "An error occurred during deletion of user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:169
+#: rhodecode/controllers/admin/users.py:175
 msgid "You can't edit this user"
 msgstr "您無法編輯這位使用者"
 
-#: rhodecode/controllers/admin/users.py:199
-#: rhodecode/controllers/admin/users_groups.py:215
+#: rhodecode/controllers/admin/users.py:205
+#: rhodecode/controllers/admin/users_groups.py:219
 msgid "Granted 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users.py:208
-#: rhodecode/controllers/admin/users_groups.py:225
+#: rhodecode/controllers/admin/users.py:214
+#: rhodecode/controllers/admin/users_groups.py:229
 msgid "Revoked 'repository create' permission to user"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:79
+#: rhodecode/controllers/admin/users_groups.py:84
 #, python-format
 msgid "created users group %s"
 msgstr "建立使用者群組 %s"
 
-#: rhodecode/controllers/admin/users_groups.py:92
+#: rhodecode/controllers/admin/users_groups.py:95
 #, python-format
 msgid "error occurred during creation of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:128
+#: rhodecode/controllers/admin/users_groups.py:135
 #, python-format
 msgid "updated users group %s"
 msgstr "更新使用者群組 %s"
 
-#: rhodecode/controllers/admin/users_groups.py:148
+#: rhodecode/controllers/admin/users_groups.py:152
 #, python-format
 msgid "error occurred during update of users group %s"
 msgstr ""
 
-#: rhodecode/controllers/admin/users_groups.py:165
+#: rhodecode/controllers/admin/users_groups.py:169
 msgid "successfully deleted users group"
 msgstr "成功移除使用者群組"
 
-#: rhodecode/controllers/admin/users_groups.py:170
+#: rhodecode/controllers/admin/users_groups.py:174
 msgid "An error occurred during deletion of users group"
 msgstr ""
 
@@ -674,61 +674,89 @@
 msgid "fork name "
 msgstr "fork 名稱"
 
-#: rhodecode/lib/helpers.py:540
+#: rhodecode/lib/helpers.py:550
 msgid "[deleted] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:541 rhodecode/lib/helpers.py:546
+#: rhodecode/lib/helpers.py:552 rhodecode/lib/helpers.py:562
 msgid "[created] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:542
+#: rhodecode/lib/helpers.py:554
 #, fuzzy
 msgid "[created] repository as fork"
 msgstr "建立版本庫 %s"
 
-#: rhodecode/lib/helpers.py:543 rhodecode/lib/helpers.py:547
+#: rhodecode/lib/helpers.py:556 rhodecode/lib/helpers.py:564
 msgid "[forked] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:544 rhodecode/lib/helpers.py:548
+#: rhodecode/lib/helpers.py:558 rhodecode/lib/helpers.py:566
 msgid "[updated] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:545
+#: rhodecode/lib/helpers.py:560
 msgid "[delete] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:549
+#: rhodecode/lib/helpers.py:568
+#, fuzzy, python-format
+#| msgid "created user %s"
+msgid "[created] user"
+msgstr "建立使用者 %s"
+
+#: rhodecode/lib/helpers.py:570
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] user"
+msgstr "更新使用者群組 %s"
+
+#: rhodecode/lib/helpers.py:572
+#, fuzzy, python-format
+#| msgid "created users group %s"
+msgid "[created] users group"
+msgstr "建立使用者群組 %s"
+
+#: rhodecode/lib/helpers.py:574
+#, fuzzy, python-format
+#| msgid "updated users group %s"
+msgid "[updated] users group"
+msgstr "更新使用者群組 %s"
+
+#: rhodecode/lib/helpers.py:576
+msgid "[commented] on revision in repository"
+msgstr ""
+
+#: rhodecode/lib/helpers.py:578
 msgid "[pushed] into"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:550
-msgid "[committed via RhodeCode] into"
+#: rhodecode/lib/helpers.py:580
+msgid "[committed via RhodeCode] into repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:551
-msgid "[pulled from remote] into"
+#: rhodecode/lib/helpers.py:582
+msgid "[pulled from remote] into repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:552
+#: rhodecode/lib/helpers.py:584
 msgid "[pulled] from"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:553
+#: rhodecode/lib/helpers.py:586
 msgid "[started following] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:554
+#: rhodecode/lib/helpers.py:588
 msgid "[stopped following] repository"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:732
+#: rhodecode/lib/helpers.py:752
 #, python-format
 msgid " and %s more"
 msgstr ""
 
-#: rhodecode/lib/helpers.py:736
+#: rhodecode/lib/helpers.py:756
 msgid "No Files"
 msgstr "沒有檔案"
 
@@ -976,7 +1004,7 @@
 msgstr "儀表板"
 
 #: rhodecode/templates/index_base.html:6
-#: rhodecode/templates/admin/users/user_edit_my_account.html:115
+#: rhodecode/templates/admin/users/user_edit_my_account.html:31
 #: rhodecode/templates/bookmarks/bookmarks.html:10
 #: rhodecode/templates/branches/branches.html:9
 #: rhodecode/templates/journal/journal.html:31
@@ -1031,10 +1059,10 @@
 #: rhodecode/templates/admin/repos/repo_edit.html:32
 #: rhodecode/templates/admin/repos/repos.html:36
 #: rhodecode/templates/admin/repos/repos.html:82
-#: rhodecode/templates/admin/users/user_edit_my_account.html:133
-#: rhodecode/templates/admin/users/user_edit_my_account.html:183
-#: rhodecode/templates/admin/users/user_edit_my_account.html:249
-#: rhodecode/templates/admin/users/user_edit_my_account.html:284
+#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account.html:99
+#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:200
 #: rhodecode/templates/bookmarks/bookmarks.html:36
 #: rhodecode/templates/bookmarks/bookmarks_data.html:6
 #: rhodecode/templates/branches/branches.html:36
@@ -1059,7 +1087,7 @@
 #: rhodecode/templates/index_base.html:161
 #: rhodecode/templates/admin/repos/repos.html:39
 #: rhodecode/templates/admin/repos/repos.html:87
-#: rhodecode/templates/admin/users/user_edit_my_account.html:251
+#: rhodecode/templates/admin/users/user_edit_my_account.html:167
 #: rhodecode/templates/journal/journal.html:179
 msgid "Tip"
 msgstr ""
@@ -1103,7 +1131,7 @@
 #: rhodecode/templates/index_base.html:148
 #: rhodecode/templates/index_base.html:188
 #: rhodecode/templates/admin/repos/repos.html:112
-#: rhodecode/templates/admin/users/user_edit_my_account.html:270
+#: rhodecode/templates/admin/users/user_edit_my_account.html:186
 #: rhodecode/templates/bookmarks/bookmarks.html:60
 #: rhodecode/templates/branches/branches.html:60
 #: rhodecode/templates/journal/journal.html:202
@@ -1114,7 +1142,7 @@
 #: rhodecode/templates/index_base.html:149
 #: rhodecode/templates/index_base.html:189
 #: rhodecode/templates/admin/repos/repos.html:113
-#: rhodecode/templates/admin/users/user_edit_my_account.html:271
+#: rhodecode/templates/admin/users/user_edit_my_account.html:187
 #: rhodecode/templates/bookmarks/bookmarks.html:61
 #: rhodecode/templates/branches/branches.html:61
 #: rhodecode/templates/journal/journal.html:203
@@ -1130,7 +1158,7 @@
 
 #: rhodecode/templates/index_base.html:190
 #: rhodecode/templates/admin/repos/repos.html:114
-#: rhodecode/templates/admin/users/user_edit_my_account.html:272
+#: rhodecode/templates/admin/users/user_edit_my_account.html:188
 #: rhodecode/templates/bookmarks/bookmarks.html:62
 #: rhodecode/templates/branches/branches.html:62
 #: rhodecode/templates/journal/journal.html:204
@@ -1140,7 +1168,7 @@
 
 #: rhodecode/templates/index_base.html:191
 #: rhodecode/templates/admin/repos/repos.html:115
-#: rhodecode/templates/admin/users/user_edit_my_account.html:273
+#: rhodecode/templates/admin/users/user_edit_my_account.html:189
 #: rhodecode/templates/bookmarks/bookmarks.html:63
 #: rhodecode/templates/branches/branches.html:63
 #: rhodecode/templates/journal/journal.html:205
@@ -1150,7 +1178,7 @@
 
 #: rhodecode/templates/index_base.html:192
 #: rhodecode/templates/admin/repos/repos.html:116
-#: rhodecode/templates/admin/users/user_edit_my_account.html:274
+#: rhodecode/templates/admin/users/user_edit_my_account.html:190
 #: rhodecode/templates/bookmarks/bookmarks.html:64
 #: rhodecode/templates/branches/branches.html:64
 #: rhodecode/templates/journal/journal.html:206
@@ -1171,7 +1199,7 @@
 #: rhodecode/templates/admin/admin_log.html:5
 #: rhodecode/templates/admin/users/user_add.html:32
 #: rhodecode/templates/admin/users/user_edit.html:50
-#: rhodecode/templates/admin/users/user_edit_my_account.html:49
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:26
 #: rhodecode/templates/base/base.html:83
 #: rhodecode/templates/summary/summary.html:113
 msgid "Username"
@@ -1232,21 +1260,21 @@
 #: rhodecode/templates/register.html:47
 #: rhodecode/templates/admin/users/user_add.html:59
 #: rhodecode/templates/admin/users/user_edit.html:86
-#: rhodecode/templates/admin/users/user_edit_my_account.html:76
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:53
 msgid "First Name"
 msgstr "名"
 
 #: rhodecode/templates/register.html:56
 #: rhodecode/templates/admin/users/user_add.html:68
 #: rhodecode/templates/admin/users/user_edit.html:95
-#: rhodecode/templates/admin/users/user_edit_my_account.html:85
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:62
 msgid "Last Name"
 msgstr "姓"
 
 #: rhodecode/templates/register.html:65
 #: rhodecode/templates/admin/users/user_add.html:77
 #: rhodecode/templates/admin/users/user_edit.html:104
-#: rhodecode/templates/admin/users/user_edit_my_account.html:94
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:71
 #: rhodecode/templates/summary/summary.html:115
 msgid "Email"
 msgstr "電子郵件"
@@ -1310,8 +1338,8 @@
 #: rhodecode/templates/admin/admin_log.html:6
 #: rhodecode/templates/admin/repos/repos.html:41
 #: rhodecode/templates/admin/repos/repos.html:90
-#: rhodecode/templates/admin/users/user_edit_my_account.html:135
-#: rhodecode/templates/admin/users/user_edit_my_account.html:136
+#: rhodecode/templates/admin/users/user_edit_my_account.html:51
+#: rhodecode/templates/admin/users/user_edit_my_account.html:52
 #: rhodecode/templates/journal/journal.html:52
 #: rhodecode/templates/journal/journal.html:53
 msgid "Action"
@@ -1334,7 +1362,7 @@
 msgid "From IP"
 msgstr "來源IP"
 
-#: rhodecode/templates/admin/admin_log.html:52
+#: rhodecode/templates/admin/admin_log.html:53
 msgid "No actions yet"
 msgstr ""
 
@@ -1415,7 +1443,7 @@
 #: rhodecode/templates/admin/settings/hooks.html:73
 #: rhodecode/templates/admin/users/user_edit.html:129
 #: rhodecode/templates/admin/users/user_edit.html:154
-#: rhodecode/templates/admin/users/user_edit_my_account.html:102
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:115
 #: rhodecode/templates/settings/repo_settings.html:84
 msgid "Save"
@@ -1570,7 +1598,7 @@
 
 #: rhodecode/templates/admin/repos/repo_edit.html:13
 #: rhodecode/templates/admin/users/user_edit.html:13
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:13
 #: rhodecode/templates/files/files_source.html:32
 #: rhodecode/templates/journal/journal.html:72
@@ -1729,38 +1757,27 @@
 msgstr "私有版本庫"
 
 #: rhodecode/templates/admin/repos/repo_edit_perms.html:33
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:53
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:58
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:23
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:42
 msgid "revoke"
 msgstr ""
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:75
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:80
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:64
 msgid "Add another member"
 msgstr "新增另ㄧ位成員"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:89
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:94
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:78
 msgid "Failed to remove user"
 msgstr "移除使用者失敗"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:104
+#: rhodecode/templates/admin/repos/repo_edit_perms.html:109
 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:93
 msgid "Failed to remove users group"
 msgstr "移除使用者群組失敗"
 
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:123
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:112
-msgid "Group"
-msgstr "群組"
-
-#: rhodecode/templates/admin/repos/repo_edit_perms.html:124
-#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:113
-#: rhodecode/templates/admin/users_groups/users_groups.html:33
-msgid "members"
-msgstr "成員"
-
 #: rhodecode/templates/admin/repos/repos.html:5
 msgid "Repositories administration"
 msgstr "版本庫管理員"
@@ -1778,7 +1795,7 @@
 msgstr "刪除"
 
 #: rhodecode/templates/admin/repos/repos.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:158
+#: rhodecode/templates/admin/users/user_edit_my_account.html:74
 #, fuzzy, python-format
 msgid "Confirm to delete this repository: %s"
 msgstr "確認移除這個版本庫"
@@ -1829,7 +1846,7 @@
 #: rhodecode/templates/admin/settings/settings.html:177
 #: rhodecode/templates/admin/users/user_edit.html:130
 #: rhodecode/templates/admin/users/user_edit.html:155
-#: rhodecode/templates/admin/users/user_edit_my_account.html:103
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:80
 #: rhodecode/templates/admin/users_groups/users_group_edit.html:116
 #: rhodecode/templates/files/files_add.html:82
 #: rhodecode/templates/files/files_edit.html:68
@@ -2058,17 +2075,17 @@
 msgstr "編輯使用者"
 
 #: rhodecode/templates/admin/users/user_edit.html:34
-#: rhodecode/templates/admin/users/user_edit_my_account.html:33
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:10
 msgid "Change your avatar at"
 msgstr "修改您的頭像於"
 
 #: rhodecode/templates/admin/users/user_edit.html:35
-#: rhodecode/templates/admin/users/user_edit_my_account.html:34
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:11
 msgid "Using"
 msgstr "使用中"
 
 #: rhodecode/templates/admin/users/user_edit.html:43
-#: rhodecode/templates/admin/users/user_edit_my_account.html:43
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:20
 msgid "API key"
 msgstr ""
 
@@ -2077,12 +2094,12 @@
 msgstr ""
 
 #: rhodecode/templates/admin/users/user_edit.html:68
-#: rhodecode/templates/admin/users/user_edit_my_account.html:58
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:35
 msgid "New password"
 msgstr "新密碼"
 
 #: rhodecode/templates/admin/users/user_edit.html:77
-#: rhodecode/templates/admin/users/user_edit_my_account.html:67
+#: rhodecode/templates/admin/users/user_edit_my_account_form.html:44
 msgid "New password confirmation"
 msgstr ""
 
@@ -2100,24 +2117,24 @@
 msgid "My Account"
 msgstr "我的帳號"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #: rhodecode/templates/journal/journal.html:32
 #, fuzzy
 msgid "My repos"
 msgstr "空的版本庫"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:116
+#: rhodecode/templates/admin/users/user_edit_my_account.html:32
 #, fuzzy
 msgid "My permissions"
 msgstr "權限"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:121
+#: rhodecode/templates/admin/users/user_edit_my_account.html:37
 #: rhodecode/templates/journal/journal.html:37
 #, fuzzy
 msgid "ADD"
 msgstr "新增"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:134
+#: rhodecode/templates/admin/users/user_edit_my_account.html:50
 #: rhodecode/templates/bookmarks/bookmarks.html:40
 #: rhodecode/templates/bookmarks/bookmarks_data.html:9
 #: rhodecode/templates/branches/branches.html:40
@@ -2127,23 +2144,23 @@
 msgid "Revision"
 msgstr "修訂"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:155
+#: rhodecode/templates/admin/users/user_edit_my_account.html:71
 #: rhodecode/templates/journal/journal.html:72
 msgid "private"
 msgstr "私有"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:165
+#: rhodecode/templates/admin/users/user_edit_my_account.html:81
 #: rhodecode/templates/journal/journal.html:85
 msgid "No repositories yet"
 msgstr "沒有任何版本庫"
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:167
+#: rhodecode/templates/admin/users/user_edit_my_account.html:83
 #: rhodecode/templates/journal/journal.html:87
 msgid "create one now"
 msgstr ""
 
-#: rhodecode/templates/admin/users/user_edit_my_account.html:184
-#: rhodecode/templates/admin/users/user_edit_my_account.html:285
+#: rhodecode/templates/admin/users/user_edit_my_account.html:100
+#: rhodecode/templates/admin/users/user_edit_my_account.html:201
 #, fuzzy
 msgid "Permission"
 msgstr "權限"
@@ -2246,6 +2263,11 @@
 msgid "group name"
 msgstr "群組名稱"
 
+#: rhodecode/templates/admin/users_groups/users_groups.html:33
+#: rhodecode/templates/base/root.html:46
+msgid "members"
+msgstr "成員"
+
 #: rhodecode/templates/admin/users_groups/users_groups.html:45
 #, fuzzy, python-format
 msgid "Confirm to delete this users group: %s"
@@ -2406,22 +2428,26 @@
 msgid "Search"
 msgstr "搜尋"
 
-#: rhodecode/templates/base/root.html:53
+#: rhodecode/templates/base/root.html:42
 #, fuzzy
 msgid "add another comment"
 msgstr "新增另ㄧ位成員"
 
-#: rhodecode/templates/base/root.html:54
+#: rhodecode/templates/base/root.html:43
 #: rhodecode/templates/journal/journal.html:111
 #: rhodecode/templates/summary/summary.html:52
 msgid "Stop following this repository"
 msgstr "停止追蹤這個版本庫"
 
-#: rhodecode/templates/base/root.html:55
+#: rhodecode/templates/base/root.html:44
 #: rhodecode/templates/summary/summary.html:56
 msgid "Start following this repository"
 msgstr "開始追蹤這個版本庫"
 
+#: rhodecode/templates/base/root.html:45
+msgid "Group"
+msgstr "群組"
+
 #: rhodecode/templates/bookmarks/bookmarks.html:5
 msgid "Bookmarks"
 msgstr ""
@@ -2550,14 +2576,14 @@
 msgstr "下載差異"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, fuzzy, python-format
 msgid "%d comment"
 msgid_plural "%d comments"
 msgstr[0] "遞交"
 
 #: rhodecode/templates/changeset/changeset.html:42
-#: rhodecode/templates/changeset/changeset_file_comment.html:69
+#: rhodecode/templates/changeset/changeset_file_comment.html:71
 #, python-format
 msgid "(%d inline)"
 msgid_plural "(%d inline)"
@@ -2581,37 +2607,37 @@
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:39
-#: rhodecode/templates/changeset/changeset_file_comment.html:100
+#: rhodecode/templates/changeset/changeset_file_comment.html:102
 #, python-format
 msgid "Comments parsed using %s syntax with %s support."
 msgstr ""
 
 #: rhodecode/templates/changeset/changeset_file_comment.html:41
-#: rhodecode/templates/changeset/changeset_file_comment.html:102
+#: rhodecode/templates/changeset/changeset_file_comment.html:104
 msgid "Use @username inside this text to send notification to this RhodeCode user"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:47
-#: rhodecode/templates/changeset/changeset_file_comment.html:107
+#: rhodecode/templates/changeset/changeset_file_comment.html:49
+#: rhodecode/templates/changeset/changeset_file_comment.html:110
 #, fuzzy
 msgid "Comment"
 msgstr "遞交"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:48
-#: rhodecode/templates/changeset/changeset_file_comment.html:59
+#: rhodecode/templates/changeset/changeset_file_comment.html:50
+#: rhodecode/templates/changeset/changeset_file_comment.html:61
 msgid "Hide"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 #, fuzzy
 msgid "You need to be logged in to comment."
 msgstr "您必須登入後才能瀏覽這個頁面"
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:55
+#: rhodecode/templates/changeset/changeset_file_comment.html:57
 msgid "Login now"
 msgstr ""
 
-#: rhodecode/templates/changeset/changeset_file_comment.html:97
+#: rhodecode/templates/changeset/changeset_file_comment.html:99
 msgid "Leave a comment"
 msgstr ""
 
@@ -3116,9 +3142,9 @@
 msgid "file removed"
 msgstr "移除檔案"
 
-#~ msgid ""
-#~ "Changeset was to big and was cut"
-#~ " off, use diff menu to display "
-#~ "this diff"
+#~ msgid "[committed via RhodeCode] into"
 #~ msgstr ""
 
+#~ msgid "[pulled from remote] into"
+#~ msgstr ""
+
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/backup_manager.py
--- a/rhodecode/lib/backup_manager.py	Wed May 30 23:12:24 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    rhodecode.lib.backup_manager
-    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    Mercurial repositories backup manager, it allows to backups all
-    repositories and send it to backup server using RSA key via ssh.
-
-    :created_on: Feb 28, 2010
-    :author: marcink
-    :copyright: (C) 2010-2012 Marcin Kuzminski 
-    :license: GPLv3, see COPYING for more details.
-"""
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see .
-
-import os
-import sys
-
-import logging
-import tarfile
-import datetime
-import subprocess
-
-logging.basicConfig(level=logging.DEBUG,
-                    format="%(asctime)s %(levelname)-5.5s %(message)s")
-
-
-class BackupManager(object):
-    def __init__(self, repos_location, rsa_key, backup_server):
-        today = datetime.datetime.now().weekday() + 1
-        self.backup_file_name = "mercurial_repos.%s.tar.gz" % today
-
-        self.id_rsa_path = self.get_id_rsa(rsa_key)
-        self.repos_path = self.get_repos_path(repos_location)
-        self.backup_server = backup_server
-
-        self.backup_file_path = '/tmp'
-
-        logging.info('starting backup for %s', self.repos_path)
-        logging.info('backup target %s', self.backup_file_path)
-
-    def get_id_rsa(self, rsa_key):
-        if not os.path.isfile(rsa_key):
-            logging.error('Could not load id_rsa key file in %s', rsa_key)
-            sys.exit()
-        return rsa_key
-
-    def get_repos_path(self, path):
-        if not os.path.isdir(path):
-            logging.error('Wrong location for repositories in %s', path)
-            sys.exit()
-        return path
-
-    def backup_repos(self):
-        bckp_file = os.path.join(self.backup_file_path, self.backup_file_name)
-        tar = tarfile.open(bckp_file, "w:gz")
-
-        for dir_name in os.listdir(self.repos_path):
-            logging.info('backing up %s', dir_name)
-            tar.add(os.path.join(self.repos_path, dir_name), dir_name)
-        tar.close()
-        logging.info('finished backup of mercurial repositories')
-
-    def transfer_files(self):
-        params = {
-                  'id_rsa_key': self.id_rsa_path,
-                  'backup_file': os.path.join(self.backup_file_path,
-                                             self.backup_file_name),
-                  'backup_server': self.backup_server
-                  }
-        cmd = ['scp', '-l', '40000', '-i', '%(id_rsa_key)s' % params,
-               '%(backup_file)s' % params,
-               '%(backup_server)s' % params]
-
-        subprocess.call(cmd)
-        logging.info('Transfered file %s to %s', self.backup_file_name, cmd[4])
-
-    def rm_file(self):
-        logging.info('Removing file %s', self.backup_file_name)
-        os.remove(os.path.join(self.backup_file_path, self.backup_file_name))
-
-if __name__ == "__main__":
-
-    repo_location = '/home/repo_path'
-    backup_server = 'root@192.168.1.100:/backups/mercurial'
-    rsa_key = '/home/id_rsa'
-
-    B_MANAGER = BackupManager(repo_location, rsa_key, backup_server)
-    B_MANAGER.backup_repos()
-    B_MANAGER.transfer_files()
-    B_MANAGER.rm_file()
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/base.py
--- a/rhodecode/lib/base.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/base.py	Tue Jun 05 21:22:23 2012 +0200
@@ -30,6 +30,16 @@
 log = logging.getLogger(__name__)
 
 
+def _get_ip_addr(environ):
+    proxy_key = 'HTTP_X_REAL_IP'
+    proxy_key2 = 'HTTP_X_FORWARDED_FOR'
+    def_key = 'REMOTE_ADDR'
+
+    return environ.get(proxy_key2,
+                       environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
+                       )
+
+
 class BasicAuth(AuthBasicAuthenticator):
 
     def __init__(self, realm, authfunc, auth_http_code=None):
@@ -117,15 +127,7 @@
         return True
 
     def _get_ip_addr(self, environ):
-        proxy_key = 'HTTP_X_REAL_IP'
-        proxy_key2 = 'HTTP_X_FORWARDED_FOR'
-        def_key = 'REMOTE_ADDR'
-
-        return environ.get(proxy_key2,
-                           environ.get(proxy_key,
-                                       environ.get(def_key, '0.0.0.0')
-                            )
-                        )
+        return _get_ip_addr(environ)
 
     def __call__(self, environ, start_response):
         start = time.time()
@@ -153,6 +155,7 @@
 
         self.sa = meta.Session
         self.scm_model = ScmModel(self.sa)
+        self.ip_addr = ''
 
     def __call__(self, environ, start_response):
         """Invoke the Controller"""
@@ -161,6 +164,7 @@
         # available in environ['pylons.routes_dict']
         start = time.time()
         try:
+            self.ip_addr = _get_ip_addr(environ)
             # make sure that we update permissions each time we call controller
             api_key = request.GET.get('api_key')
             cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/diffs.py
--- a/rhodecode/lib/diffs.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/diffs.py	Tue Jun 05 21:22:23 2012 +0200
@@ -135,7 +135,7 @@
     """
     _chunk_re = re.compile(r'@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)')
 
-    def __init__(self, diff, differ='diff', format='udiff'):
+    def __init__(self, diff, differ='diff', format='gitdiff'):
         """
         :param diff:   a text in diff format or generator
         :param format: format of diff passed, `udiff` or `gitdiff`
@@ -289,7 +289,7 @@
             do(line)
             do(next_)
 
-    def _parse_udiff(self):
+    def _parse_udiff(self, inline_diff=True):
         """
         Parse the diff an return data for the template.
         """
@@ -386,9 +386,14 @@
                             })
 
                         line = lineiter.next()
+
         except StopIteration:
             pass
 
+        sorter = lambda info: {'A': 0, 'M': 1, 'D': 2}.get(info['operation'])
+        if inline_diff is False:
+            return sorted(files, key=sorter)
+
         # highlight inline changes
         for diff_data in files:
             for chunk in diff_data['chunks']:
@@ -404,14 +409,15 @@
                             self.differ(line, nextline)
                 except StopIteration:
                     pass
-        return files
 
-    def prepare(self):
+        return sorted(files, key=sorter)
+
+    def prepare(self, inline_diff=True):
         """
         Prepare the passed udiff for HTML rendering. It'l return a list
         of dicts
         """
-        return self._parse_udiff()
+        return self._parse_udiff(inline_diff=inline_diff)
 
     def _safe_id(self, idstring):
         """Make a string safe for including in an id attribute.
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/graphmod.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/lib/graphmod.py	Tue Jun 05 21:22:23 2012 +0200
@@ -0,0 +1,127 @@
+"""
+Modified mercurial DAG graph functions that re-uses VCS structure
+
+It allows to have a shared codebase for DAG generation for hg and git repos
+"""
+
+nullrev = -1
+
+
+def grandparent(parentrev_func, lowestrev, roots, head):
+    """
+    Return all ancestors of head in roots which revision is
+    greater or equal to lowestrev.
+    """
+    pending = set([head])
+    seen = set()
+    kept = set()
+    llowestrev = max(nullrev, lowestrev)
+    while pending:
+        r = pending.pop()
+        if r >= llowestrev and r not in seen:
+            if r in roots:
+                kept.add(r)
+            else:
+                pending.update([p for p in parentrev_func(r)])
+            seen.add(r)
+    return sorted(kept)
+
+
+def _dagwalker(repo, revs, alias):
+    if not revs:
+        return
+
+    if alias == 'hg':
+        cl = repo._repo.changelog.parentrevs
+        repo = repo
+    elif alias == 'git':
+        def cl(rev):
+            return [x.revision for x in repo[rev].parents()]
+        repo = repo
+
+    lowestrev = min(revs)
+    gpcache = {}
+
+    knownrevs = set(revs)
+    for rev in revs:
+        ctx = repo[rev]
+        parents = sorted(set([p.revision for p in ctx.parents
+                              if p.revision in knownrevs]))
+        mpars = [p.revision for p in ctx.parents if
+                 p.revision != nullrev and p.revision not in parents]
+
+        for mpar in mpars:
+            gp = gpcache.get(mpar)
+            if gp is None:
+                gp = gpcache[mpar] = grandparent(cl, lowestrev, revs, mpar)
+            if not gp:
+                parents.append(mpar)
+            else:
+                parents.extend(g for g in gp if g not in parents)
+
+        yield (ctx.revision, 'C', ctx, parents)
+
+
+def _colored(dag):
+    """annotates a DAG with colored edge information
+
+    For each DAG node this function emits tuples::
+
+      (id, type, data, (col, color), [(col, nextcol, color)])
+
+    with the following new elements:
+
+      - Tuple (col, color) with column and color index for the current node
+      - A list of tuples indicating the edges between the current node and its
+        parents.
+    """
+    seen = []
+    colors = {}
+    newcolor = 1
+
+    getconf = lambda rev: {}
+
+    for (cur, type, data, parents) in dag:
+
+        # Compute seen and next
+        if cur not in seen:
+            seen.append(cur)  # new head
+            colors[cur] = newcolor
+            newcolor += 1
+
+        col = seen.index(cur)
+        color = colors.pop(cur)
+        next = seen[:]
+
+        # Add parents to next
+        addparents = [p for p in parents if p not in next]
+        next[col:col + 1] = addparents
+
+        # Set colors for the parents
+        for i, p in enumerate(addparents):
+            if not i:
+                colors[p] = color
+            else:
+                colors[p] = newcolor
+                newcolor += 1
+
+        # Add edges to the graph
+        edges = []
+        for ecol, eid in enumerate(seen):
+            if eid in next:
+                bconf = getconf(eid)
+                edges.append((
+                    ecol, next.index(eid), colors[eid],
+                    bconf.get('width', -1),
+                    bconf.get('color', '')))
+            elif eid == cur:
+                for p in parents:
+                    bconf = getconf(p)
+                    edges.append((
+                        ecol, next.index(p), color,
+                        bconf.get('width', -1),
+                        bconf.get('color', '')))
+
+        # Yield and move on
+        yield (cur, type, data, (col, color), edges)
+        seen = next
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/helpers.py
--- a/rhodecode/lib/helpers.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/helpers.py	Tue Jun 05 21:22:23 2012 +0200
@@ -455,7 +455,7 @@
 
             if isinstance(rev, BaseChangeset):
                 lbl = 'r%s:%s' % (rev.revision, rev.short_id)
-                _url = url('changeset_home', repo_name=repo_name, 
+                _url = url('changeset_home', repo_name=repo_name,
                            revision=rev.raw_id)
                 title = tooltip(rev.message)
             else:
@@ -538,22 +538,57 @@
         return _('fork name ') + str(link_to(action_params, url('summary_home',
                                           repo_name=repo_name,)))
 
-    action_map = {'user_deleted_repo': (_('[deleted] repository'), None),
-           'user_created_repo': (_('[created] repository'), None),
-           'user_created_fork': (_('[created] repository as fork'), None),
-           'user_forked_repo': (_('[forked] repository'), get_fork_name),
-           'user_updated_repo': (_('[updated] repository'), None),
-           'admin_deleted_repo': (_('[delete] repository'), None),
-           'admin_created_repo': (_('[created] repository'), None),
-           'admin_forked_repo': (_('[forked] repository'), None),
-           'admin_updated_repo': (_('[updated] repository'), None),
-           'push': (_('[pushed] into'), get_cs_links),
-           'push_local': (_('[committed via RhodeCode] into'), get_cs_links),
-           'push_remote': (_('[pulled from remote] into'), get_cs_links),
-           'pull': (_('[pulled] from'), None),
-           'started_following_repo': (_('[started following] repository'), None),
-           'stopped_following_repo': (_('[stopped following] repository'), None),
-            }
+    def get_user_name():
+        user_name = action_params
+        return user_name
+
+    def get_users_group():
+        group_name = action_params
+        return group_name
+
+    # action : translated str, callback(extractor), icon
+    action_map = {
+    'user_deleted_repo':         (_('[deleted] repository'),
+                                  None, 'database_delete.png'),
+    'user_created_repo':         (_('[created] repository'),
+                                  None, 'database_add.png'),
+    'user_created_fork':         (_('[created] repository as fork'),
+                                  None, 'arrow_divide.png'),
+    'user_forked_repo':          (_('[forked] repository'),
+                                  get_fork_name, 'arrow_divide.png'),
+    'user_updated_repo':         (_('[updated] repository'),
+                                  None, 'database_edit.png'),
+    'admin_deleted_repo':        (_('[delete] repository'),
+                                  None, 'database_delete.png'),
+    'admin_created_repo':        (_('[created] repository'),
+                                  None, 'database_add.png'),
+    'admin_forked_repo':         (_('[forked] repository'),
+                                  None, 'arrow_divide.png'),
+    'admin_updated_repo':        (_('[updated] repository'),
+                                  None, 'database_edit.png'),
+    'admin_created_user':        (_('[created] user'),
+                                  get_user_name, 'user_add.png'),
+    'admin_updated_user':        (_('[updated] user'),
+                                  get_user_name, 'user_edit.png'),
+    'admin_created_users_group': (_('[created] users group'),
+                                  get_users_group, 'group_add.png'),
+    'admin_updated_users_group': (_('[updated] users group'),
+                                  get_users_group, 'group_edit.png'),
+    'user_commented_revision':   (_('[commented] on revision in repository'),
+                                  get_cs_links, 'comment_add.png'),
+    'push':                      (_('[pushed] into'),
+                                  get_cs_links, 'script_add.png'),
+    'push_local':                (_('[committed via RhodeCode] into repository'),
+                                  get_cs_links, 'script_edit.png'),
+    'push_remote':               (_('[pulled from remote] into repository'),
+                                  get_cs_links, 'connect.png'),
+    'pull':                      (_('[pulled] from'),
+                                  None, 'down_16.png'),
+    'started_following_repo':    (_('[started following] repository'),
+                                  None, 'heart_add.png'),
+    'stopped_following_repo':    (_('[stopped following] repository'),
+                                  None, 'heart_delete.png'),
+    }
 
     action_str = action_map.get(action, action)
     if feed:
@@ -568,36 +603,21 @@
     if callable(action_str[1]):
         action_params_func = action_str[1]
 
-    return [literal(action), action_params_func]
-
+    def action_parser_icon():
+        action = user_log.action
+        action_params = None
+        x = action.split(':')
 
-def action_parser_icon(user_log):
-    action = user_log.action
-    action_params = None
-    x = action.split(':')
-
-    if len(x) > 1:
-        action, action_params = x
+        if len(x) > 1:
+            action, action_params = x
 
-    tmpl = """%s"""
-    map = {'user_deleted_repo':'database_delete.png',
-           'user_created_repo':'database_add.png',
-           'user_created_fork':'arrow_divide.png',
-           'user_forked_repo':'arrow_divide.png',
-           'user_updated_repo':'database_edit.png',
-           'admin_deleted_repo':'database_delete.png',
-           'admin_created_repo':'database_add.png',
-           'admin_forked_repo':'arrow_divide.png',
-           'admin_updated_repo':'database_edit.png',
-           'push':'script_add.png',
-           'push_local':'script_edit.png',
-           'push_remote':'connect.png',
-           'pull':'down_16.png',
-           'started_following_repo':'heart_add.png',
-           'stopped_following_repo':'heart_delete.png',
-            }
-    return literal(tmpl % ((url('/images/icons/')),
-                           map.get(action, action), action))
+        tmpl = """%s"""
+        ico = action_map.get(action, ['', '', ''])[2]
+        return literal(tmpl % ((url('/images/icons/')), ico, action))
+
+    # returned callbacks we need to call to get
+    return [lambda: literal(action), action_params_func, action_parser_icon]
+
 
 
 #==============================================================================
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/indexers/__init__.py
--- a/rhodecode/lib/indexers/__init__.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/indexers/__init__.py	Tue Jun 05 21:22:23 2012 +0200
@@ -40,7 +40,7 @@
 from whoosh.formats import Characters
 from whoosh.highlight import highlight, HtmlFormatter, ContextFragmenter
 
-from webhelpers.html.builder import escape
+from webhelpers.html.builder import escape, literal
 from sqlalchemy import engine_from_config
 
 from rhodecode.model import init_model
@@ -57,6 +57,7 @@
 
 #INDEX SCHEMA DEFINITION
 SCHEMA = Schema(
+    fileid=ID(unique=True),
     owner=TEXT(),
     repository=TEXT(stored=True),
     path=TEXT(stored=True),
@@ -93,6 +94,8 @@
             if self.options.repo_location else RepoModel().repos_path
         repo_list = map(strip, self.options.repo_list.split(',')) \
             if self.options.repo_list else None
+        repo_update_list = map(strip, self.options.repo_update_list.split(',')) \
+            if self.options.repo_update_list else None
         load_rcextensions(config['here'])
         #======================================================================
         # WHOOSH DAEMON
@@ -103,7 +106,8 @@
             l = DaemonLock(file_=jn(dn(dn(index_location)), 'make_index.lock'))
             WhooshIndexingDaemon(index_location=index_location,
                                  repo_location=repo_location,
-                                 repo_list=repo_list,)\
+                                 repo_list=repo_list,
+                                 repo_update_list=repo_update_list)\
                 .run(full_index=self.options.full_index)
             l.release()
         except LockHeld:
@@ -119,7 +123,14 @@
                           action='store',
                           dest='repo_list',
                           help="Specifies a comma separated list of repositores "
-                                "to build index on OPTIONAL",
+                                "to build index on. If not given all repositories "
+                                "are scanned for indexing. OPTIONAL",
+                          )
+        self.parser.add_option('--update-only',
+                          action='store',
+                          dest='repo_update_list',
+                          help="Specifies a comma separated list of repositores "
+                                "to re-build index on. OPTIONAL",
                           )
         self.parser.add_option('-f',
                           action='store_true',
@@ -220,7 +231,7 @@
         if self.search_type != 'content':
             return ''
         hl = highlight(
-            text=escape(content),
+            text=content,
             terms=self.highlight_items,
             analyzer=ANALYZER,
             fragmenter=FRAGMENTER,
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/indexers/daemon.py
--- a/rhodecode/lib/indexers/daemon.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/indexers/daemon.py	Tue Jun 05 21:22:23 2012 +0200
@@ -53,11 +53,12 @@
 
 class WhooshIndexingDaemon(object):
     """
-    Daemon for atomic jobs
+    Daemon for atomic indexing jobs
     """
 
     def __init__(self, indexname=IDX_NAME, index_location=None,
-                 repo_location=None, sa=None, repo_list=None):
+                 repo_location=None, sa=None, repo_list=None,
+                 repo_update_list=None):
         self.indexname = indexname
 
         self.index_location = index_location
@@ -70,13 +71,23 @@
 
         self.repo_paths = ScmModel(sa).repo_scan(self.repo_location)
 
+        #filter repo list
         if repo_list:
-            filtered_repo_paths = {}
+            self.filtered_repo_paths = {}
             for repo_name, repo in self.repo_paths.items():
                 if repo_name in repo_list:
-                    filtered_repo_paths[repo_name] = repo
+                    self.filtered_repo_paths[repo_name] = repo
+
+            self.repo_paths = self.filtered_repo_paths
 
-            self.repo_paths = filtered_repo_paths
+        #filter update repo list
+        self.filtered_repo_update_paths = {}
+        if repo_update_list:
+            self.filtered_repo_update_paths = {}
+            for repo_name, repo in self.repo_paths.items():
+                if repo_name in repo_update_list:
+                    self.filtered_repo_update_paths[repo_name] = repo
+            self.repo_paths = self.filtered_repo_update_paths
 
         self.initial = False
         if not os.path.isdir(self.index_location):
@@ -135,10 +146,12 @@
             u_content = u''
             indexed += 1
 
+        p = safe_unicode(path)
         writer.add_document(
+            fileid=p,
             owner=unicode(repo.contact),
             repository=safe_unicode(repo_name),
-            path=safe_unicode(path),
+            path=p,
             content=u_content,
             modtime=self.get_node_mtime(node),
             extension=node.extension
@@ -172,8 +185,8 @@
         log.debug('>>> FINISHED BUILDING INDEX <<<')
 
     def update_index(self):
-        log.debug('STARTING INCREMENTAL INDEXING UPDATE FOR EXTENSIONS %s' %
-                  INDEX_EXTENSIONS)
+        log.debug((u'STARTING INCREMENTAL INDEXING UPDATE FOR EXTENSIONS %s '
+                   'AND REPOS %s') % (INDEX_EXTENSIONS, self.repo_paths.keys()))
 
         idx = open_dir(self.index_location, indexname=self.indexname)
         # The set of all paths in the index
@@ -187,27 +200,32 @@
         # Loop over the stored fields in the index
         for fields in reader.all_stored_fields():
             indexed_path = fields['path']
+            indexed_repo_path = fields['repository']
             indexed_paths.add(indexed_path)
 
-            repo = self.repo_paths[fields['repository']]
+            if not indexed_repo_path in self.filtered_repo_update_paths:
+                continue
+
+            repo = self.repo_paths[indexed_repo_path]
 
             try:
                 node = self.get_node(repo, indexed_path)
-            except (ChangesetError, NodeDoesNotExistError):
-                # This file was deleted since it was indexed
-                log.debug('removing from index %s' % indexed_path)
-                writer.delete_by_term('path', indexed_path)
-
-            else:
                 # Check if this file was changed since it was indexed
                 indexed_time = fields['modtime']
                 mtime = self.get_node_mtime(node)
                 if mtime > indexed_time:
                     # The file has changed, delete it and add it to the list of
                     # files to reindex
-                    log.debug('adding to reindex list %s' % indexed_path)
-                    writer.delete_by_term('path', indexed_path)
+                    log.debug('adding to reindex list %s mtime: %s vs %s' % (
+                                    indexed_path, mtime, indexed_time)
+                    )
+                    writer.delete_by_term('fileid', indexed_path)
+
                     to_index.add(indexed_path)
+            except (ChangesetError, NodeDoesNotExistError):
+                # This file was deleted since it was indexed
+                log.debug('removing from index %s' % indexed_path)
+                writer.delete_by_term('path', indexed_path)
 
         # Loop over the files in the filesystem
         # Assume we have a function that gathers the filenames of the
@@ -215,7 +233,9 @@
         ri_cnt = riwc_cnt = 0
         for repo_name, repo in self.repo_paths.items():
             for path in self.get_paths(repo):
+                path = safe_unicode(path)
                 if path in to_index or path not in indexed_paths:
+
                     # This is either a file that's changed, or a new file
                     # that wasn't indexed before. So index it!
                     i, iwc = self.add_doc(writer, path, repo, repo_name)
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/middleware/pygrack.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/lib/middleware/pygrack.py	Tue Jun 05 21:22:23 2012 +0200
@@ -0,0 +1,181 @@
+import os
+import socket
+import logging
+import subprocess
+
+from webob import Request, Response, exc
+
+from rhodecode.lib import subprocessio
+
+log = logging.getLogger(__name__)
+
+
+class FileWrapper(object):
+
+    def __init__(self, fd, content_length):
+        self.fd = fd
+        self.content_length = content_length
+        self.remain = content_length
+
+    def read(self, size):
+        if size <= self.remain:
+            try:
+                data = self.fd.read(size)
+            except socket.error:
+                raise IOError(self)
+            self.remain -= size
+        elif self.remain:
+            data = self.fd.read(self.remain)
+            self.remain = 0
+        else:
+            data = None
+        return data
+
+    def __repr__(self):
+        return '' % (
+            self.fd, self.content_length, self.content_length - self.remain
+        )
+
+
+class GitRepository(object):
+    git_folder_signature = set(['config', 'head', 'info', 'objects', 'refs'])
+    commands = ['git-upload-pack', 'git-receive-pack']
+
+    def __init__(self, repo_name, content_path):
+        files = set([f.lower() for f in os.listdir(content_path)])
+        if  not (self.git_folder_signature.intersection(files)
+                == self.git_folder_signature):
+            raise OSError('%s missing git signature' % content_path)
+        self.content_path = content_path
+        self.valid_accepts = ['application/x-%s-result' %
+                              c for c in self.commands]
+        self.repo_name = repo_name
+
+    def _get_fixedpath(self, path):
+        """
+        Small fix for repo_path
+
+        :param path:
+        :type path:
+        """
+        return path.split(self.repo_name, 1)[-1].strip('/')
+
+    def inforefs(self, request, environ):
+        """
+        WSGI Response producer for HTTP GET Git Smart
+        HTTP /info/refs request.
+        """
+
+        git_command = request.GET['service']
+        if git_command not in self.commands:
+            log.debug('command %s not allowed' % git_command)
+            return exc.HTTPMethodNotAllowed()
+
+        # note to self:
+        # please, resist the urge to add '\n' to git capture and increment
+        # line count by 1.
+        # The code in Git client not only does NOT need '\n', but actually
+        # blows up if you sprinkle "flush" (0000) as "0001\n".
+        # It reads binary, per number of bytes specified.
+        # if you do add '\n' as part of data, count it.
+        smart_server_advert = '# service=%s' % git_command
+        try:
+            out = subprocessio.SubprocessIOChunker(
+                r'git %s --stateless-rpc --advertise-refs "%s"' % (
+                                git_command[4:], self.content_path),
+                starting_values=[
+                    str(hex(len(smart_server_advert) + 4)[2:]
+                        .rjust(4, '0') + smart_server_advert + '0000')
+                ]
+            )
+        except EnvironmentError, e:
+            log.exception(e)
+            raise exc.HTTPExpectationFailed()
+        resp = Response()
+        resp.content_type = 'application/x-%s-advertisement' % str(git_command)
+        resp.app_iter = out
+        return resp
+
+    def backend(self, request, environ):
+        """
+        WSGI Response producer for HTTP POST Git Smart HTTP requests.
+        Reads commands and data from HTTP POST's body.
+        returns an iterator obj with contents of git command's
+        response to stdout
+        """
+        git_command = self._get_fixedpath(request.path_info)
+        if git_command not in self.commands:
+            log.debug('command %s not allowed' % git_command)
+            return exc.HTTPMethodNotAllowed()
+
+        if 'CONTENT_LENGTH' in environ:
+            inputstream = FileWrapper(environ['wsgi.input'],
+                                      request.content_length)
+        else:
+            inputstream = environ['wsgi.input']
+
+        try:
+            out = subprocessio.SubprocessIOChunker(
+                r'git %s --stateless-rpc "%s"' % (git_command[4:],
+                                                  self.content_path),
+                inputstream=inputstream
+                )
+        except EnvironmentError, e:
+            log.exception(e)
+            raise exc.HTTPExpectationFailed()
+
+        if git_command in [u'git-receive-pack']:
+            # updating refs manually after each push.
+            # Needed for pre-1.7.0.4 git clients using regular HTTP mode.
+            subprocess.call(u'git --git-dir "%s" '
+                            'update-server-info' % self.content_path,
+                            shell=True)
+
+        resp = Response()
+        resp.content_type = 'application/x-%s-result' % git_command.encode('utf8')
+        resp.app_iter = out
+        return resp
+
+    def __call__(self, environ, start_response):
+        request = Request(environ)
+        _path = self._get_fixedpath(request.path_info)
+        if _path.startswith('info/refs'):
+            app = self.inforefs
+        elif [a for a in self.valid_accepts if a in request.accept]:
+            app = self.backend
+        try:
+            resp = app(request, environ)
+        except exc.HTTPException, e:
+            resp = e
+            log.exception(e)
+        except Exception, e:
+            log.exception(e)
+            resp = exc.HTTPInternalServerError()
+        return resp(environ, start_response)
+
+
+class GitDirectory(object):
+
+    def __init__(self, repo_root, repo_name):
+        repo_location = os.path.join(repo_root, repo_name)
+        if not os.path.isdir(repo_location):
+            raise OSError(repo_location)
+
+        self.content_path = repo_location
+        self.repo_name = repo_name
+        self.repo_location = repo_location
+
+    def __call__(self, environ, start_response):
+        content_path = self.content_path
+        try:
+            app = GitRepository(self.repo_name, content_path)
+        except (AssertionError, OSError):
+            if os.path.isdir(os.path.join(content_path, '.git')):
+                app = GitRepository(os.path.join(content_path, '.git'))
+            else:
+                return exc.HTTPNotFound()(environ, start_response)
+        return app(environ, start_response)
+
+
+def make_wsgi_app(repo_name, repo_root):
+    return GitDirectory(repo_root, repo_name)
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/middleware/simplegit.py
--- a/rhodecode/lib/middleware/simplegit.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/middleware/simplegit.py	Tue Jun 05 21:22:23 2012 +0200
@@ -218,11 +218,13 @@
         :param repo_name: name of the repository
         :param repo_path: full path to the repository
         """
-        _d = {'/' + repo_name: Repo(repo_path)}
-        backend = dulserver.DictBackend(_d)
-        gitserve = make_wsgi_chain(backend)
 
-        return gitserve
+        from rhodecode.lib.middleware.pygrack import make_wsgi_app
+        app = make_wsgi_app(
+            repo_root=os.path.dirname(repo_path),
+            repo_name=repo_name,
+        )
+        return app
 
     def __get_repository(self, environ):
         """
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/subprocessio.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/lib/subprocessio.py	Tue Jun 05 21:22:23 2012 +0200
@@ -0,0 +1,401 @@
+'''
+Module provides a class allowing to wrap communication over subprocess.Popen
+input, output, error streams into a meaningfull, non-blocking, concurrent
+stream processor exposing the output data as an iterator fitting to be a
+return value passed by a WSGI applicaiton to a WSGI server per PEP 3333.
+
+Copyright (c) 2011  Daniel Dotsenko 
+
+This file is part of git_http_backend.py Project.
+
+git_http_backend.py Project is free software: you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 2.1 of the License,
+or (at your option) any later version.
+
+git_http_backend.py Project is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with git_http_backend.py Project.
+If not, see .
+'''
+import os
+import subprocess
+import threading
+from collections import deque
+
+
+class StreamFeeder(threading.Thread):
+    """
+    Normal writing into pipe-like is blocking once the buffer is filled.
+    This thread allows a thread to seep data from a file-like into a pipe
+    without blocking the main thread.
+    We close inpipe once the end of the source stream is reached.
+    """
+    def __init__(self, source):
+        super(StreamFeeder, self).__init__()
+        self.daemon = True
+        filelike = False
+        self.bytes = b''
+        if type(source) in (type(''), bytes, bytearray): # string-like
+            self.bytes = bytes(source)
+        else: # can be either file pointer or file-like
+            if type(source) in (int, long): # file pointer it is
+                ## converting file descriptor (int) stdin into file-like
+                try:
+                    source = os.fdopen(source, 'rb', 16384)
+                except:
+                    pass
+            # let's see if source is file-like by now
+            try:
+                filelike = source.read
+            except:
+                pass
+        if not filelike and not self.bytes:
+            raise TypeError("StreamFeeder's source object must be a readable file-like, a file descriptor, or a string-like.")
+        self.source = source
+        self.readiface, self.writeiface = os.pipe()
+
+    def run(self):
+        t = self.writeiface
+        if self.bytes:
+            os.write(t, self.bytes)
+        else:
+            s = self.source
+            b = s.read(4096)
+            while b:
+                os.write(t, b)
+                b = s.read(4096)
+        os.close(t)
+
+    @property
+    def output(self):
+        return self.readiface
+
+
+class InputStreamChunker(threading.Thread):
+    def __init__(self, source, target, buffer_size, chunk_size):
+
+        super(InputStreamChunker, self).__init__()
+
+        self.daemon = True  # die die die.
+
+        self.source = source
+        self.target = target
+        self.chunk_count_max = int(buffer_size / chunk_size) + 1
+        self.chunk_size = chunk_size
+
+        self.data_added = threading.Event()
+        self.data_added.clear()
+
+        self.keep_reading = threading.Event()
+        self.keep_reading.set()
+
+        self.EOF = threading.Event()
+        self.EOF.clear()
+
+        self.go = threading.Event()
+        self.go.set()
+
+    def stop(self):
+        self.go.clear()
+        self.EOF.set()
+        try:
+            # this is not proper, but is done to force the reader thread let
+            # go of the input because, if successful, .close() will send EOF
+            # down the pipe.
+            self.source.close()
+        except:
+            pass
+
+    def run(self):
+        s = self.source
+        t = self.target
+        cs = self.chunk_size
+        ccm = self.chunk_count_max
+        kr = self.keep_reading
+        da = self.data_added
+        go = self.go
+        b = s.read(cs)
+        while b and go.is_set():
+            if len(t) > ccm:
+                kr.clear()
+                kr.wait(2)
+#                # this only works on 2.7.x and up
+#                if not kr.wait(10):
+#                    raise Exception("Timed out while waiting for input to be read.")
+                # instead we'll use this
+                if len(t) > ccm + 3:
+                    raise IOError("Timed out while waiting for input from subprocess.")
+            t.append(b)
+            da.set()
+            b = s.read(cs)
+        self.EOF.set()
+        da.set()  # for cases when done but there was no input.
+
+
+class BufferedGenerator():
+    '''
+    Class behaves as a non-blocking, buffered pipe reader.
+    Reads chunks of data (through a thread)
+    from a blocking pipe, and attaches these to an array (Deque) of chunks.
+    Reading is halted in the thread when max chunks is internally buffered.
+    The .next() may operate in blocking or non-blocking fashion by yielding
+    '' if no data is ready
+    to be sent or by not returning until there is some data to send
+    When we get EOF from underlying source pipe we raise the marker to raise
+    StopIteration after the last chunk of data is yielded.
+    '''
+
+    def __init__(self, source, buffer_size=65536, chunk_size=4096,
+                 starting_values=[], bottomless=False):
+
+        if bottomless:
+            maxlen = int(buffer_size / chunk_size)
+        else:
+            maxlen = None
+
+        self.data = deque(starting_values, maxlen)
+
+        self.worker = InputStreamChunker(source, self.data, buffer_size,
+                                         chunk_size)
+        if starting_values:
+            self.worker.data_added.set()
+        self.worker.start()
+
+    ####################
+    # Generator's methods
+    ####################
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        while not len(self.data) and not self.worker.EOF.is_set():
+            self.worker.data_added.clear()
+            self.worker.data_added.wait(0.2)
+        if len(self.data):
+            self.worker.keep_reading.set()
+            return bytes(self.data.popleft())
+        elif self.worker.EOF.is_set():
+            raise StopIteration
+
+    def throw(self, type, value=None, traceback=None):
+        if not self.worker.EOF.is_set():
+            raise type(value)
+
+    def start(self):
+        self.worker.start()
+
+    def stop(self):
+        self.worker.stop()
+
+    def close(self):
+        try:
+            self.worker.stop()
+            self.throw(GeneratorExit)
+        except (GeneratorExit, StopIteration):
+            pass
+
+    def __del__(self):
+        self.close()
+
+    ####################
+    # Threaded reader's infrastructure.
+    ####################
+    @property
+    def input(self):
+        return self.worker.w
+
+    @property
+    def data_added_event(self):
+        return self.worker.data_added
+
+    @property
+    def data_added(self):
+        return self.worker.data_added.is_set()
+
+    @property
+    def reading_paused(self):
+        return not self.worker.keep_reading.is_set()
+
+    @property
+    def done_reading_event(self):
+        '''
+        Done_reding does not mean that the iterator's buffer is empty.
+        Iterator might have done reading from underlying source, but the read
+        chunks might still be available for serving through .next() method.
+
+        @return An Event class instance.
+        '''
+        return self.worker.EOF
+
+    @property
+    def done_reading(self):
+        '''
+        Done_reding does not mean that the iterator's buffer is empty.
+        Iterator might have done reading from underlying source, but the read
+        chunks might still be available for serving through .next() method.
+
+        @return An Bool value.
+        '''
+        return self.worker.EOF.is_set()
+
+    @property
+    def length(self):
+        '''
+        returns int.
+
+        This is the lenght of the que of chunks, not the length of
+        the combined contents in those chunks.
+
+        __len__() cannot be meaningfully implemented because this
+        reader is just flying throuh a bottomless pit content and
+        can only know the lenght of what it already saw.
+
+        If __len__() on WSGI server per PEP 3333 returns a value,
+        the responce's length will be set to that. In order not to
+        confuse WSGI PEP3333 servers, we will not implement __len__
+        at all.
+        '''
+        return len(self.data)
+
+    def prepend(self, x):
+        self.data.appendleft(x)
+
+    def append(self, x):
+        self.data.append(x)
+
+    def extend(self, o):
+        self.data.extend(o)
+
+    def __getitem__(self, i):
+        return self.data[i]
+
+
+class SubprocessIOChunker():
+    '''
+    Processor class wrapping handling of subprocess IO.
+
+    In a way, this is a "communicate()" replacement with a twist.
+
+    - We are multithreaded. Writing in and reading out, err are all sep threads.
+    - We support concurrent (in and out) stream processing.
+    - The output is not a stream. It's a queue of read string (bytes, not unicode)
+      chunks. The object behaves as an iterable. You can "for chunk in obj:" us.
+    - We are non-blocking in more respects than communicate()
+      (reading from subprocess out pauses when internal buffer is full, but
+       does not block the parent calling code. On the flip side, reading from
+       slow-yielding subprocess may block the iteration until data shows up. This
+       does not block the parallel inpipe reading occurring parallel thread.)
+
+    The purpose of the object is to allow us to wrap subprocess interactions into
+    and interable that can be passed to a WSGI server as the application's return
+    value. Because of stream-processing-ability, WSGI does not have to read ALL
+    of the subprocess's output and buffer it, before handing it to WSGI server for
+    HTTP response. Instead, the class initializer reads just a bit of the stream
+    to figure out if error ocurred or likely to occur and if not, just hands the
+    further iteration over subprocess output to the server for completion of HTTP
+    response.
+
+    The real or perceived subprocess error is trapped and raised as one of
+    EnvironmentError family of exceptions
+
+    Example usage:
+    #    try:
+    #        answer = SubprocessIOChunker(
+    #            cmd,
+    #            input,
+    #            buffer_size = 65536,
+    #            chunk_size = 4096
+    #            )
+    #    except (EnvironmentError) as e:
+    #        print str(e)
+    #        raise e
+    #
+    #    return answer
+
+
+    '''
+    def __init__(self, cmd, inputstream=None, buffer_size=65536,
+                 chunk_size=4096, starting_values=[]):
+        '''
+        Initializes SubprocessIOChunker
+
+        @param cmd A Subprocess.Popen style "cmd". Can be string or array of strings
+        @param inputstream (Default: None) A file-like, string, or file pointer.
+        @param buffer_size (Default: 65536) A size of total buffer per stream in bytes.
+        @param chunk_size (Default: 4096) A max size of a chunk. Actual chunk may be smaller.
+        @param starting_values (Default: []) An array of strings to put in front of output que.
+        '''
+
+        if inputstream:
+            input_streamer = StreamFeeder(inputstream)
+            input_streamer.start()
+            inputstream = input_streamer.output
+
+        _p = subprocess.Popen(cmd,
+            bufsize=-1,
+            shell=True,
+            stdin=inputstream,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE
+            )
+
+        bg_out = BufferedGenerator(_p.stdout, buffer_size, chunk_size, starting_values)
+        bg_err = BufferedGenerator(_p.stderr, 16000, 1, bottomless=True)
+
+        while not bg_out.done_reading and not bg_out.reading_paused and not bg_err.length:
+            # doing this until we reach either end of file, or end of buffer.
+            bg_out.data_added_event.wait(1)
+            bg_out.data_added_event.clear()
+
+        # at this point it's still ambiguous if we are done reading or just full buffer.
+        # Either way, if error (returned by ended process, or implied based on
+        # presence of stuff in stderr output) we error out.
+        # Else, we are happy.
+        _returncode = _p.poll()
+        if _returncode or (_returncode == None and bg_err.length):
+            try:
+                _p.terminate()
+            except:
+                pass
+            bg_out.stop()
+            bg_err.stop()
+            raise EnvironmentError("Subprocess exited due to an error.\n" + "".join(bg_err))
+
+        self.process = _p
+        self.output = bg_out
+        self.error = bg_err
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        if self.process.poll():
+            raise EnvironmentError("Subprocess exited due to an error:\n" + ''.join(self.error))
+        return self.output.next()
+
+    def throw(self, type, value=None, traceback=None):
+        if self.output.length or not self.output.done_reading:
+            raise type(value)
+
+    def close(self):
+        try:
+            self.process.terminate()
+        except:
+            pass
+        try:
+            self.output.close()
+        except:
+            pass
+        try:
+            self.error.close()
+        except:
+            pass
+
+    def __del__(self):
+        self.close()
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/utils.py
--- a/rhodecode/lib/utils.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/utils.py	Tue Jun 05 21:22:23 2012 +0200
@@ -146,13 +146,14 @@
             repo_name = repo.lstrip('/')
             repo_obj = Repository.get_by_repo_name(repo_name)
         else:
-            raise Exception('You have to provide repository to action logger')
+            repo_obj = None
+            repo_name = ''
 
         user_log = UserLog()
         user_log.user_id = user_obj.user_id
         user_log.action = safe_unicode(action)
 
-        user_log.repository_id = repo_obj.repo_id
+        user_log.repository = repo_obj
         user_log.repository_name = repo_name
 
         user_log.action_date = datetime.datetime.now()
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/utils2.py
--- a/rhodecode/lib/utils2.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/utils2.py	Tue Jun 05 21:22:23 2012 +0200
@@ -309,7 +309,7 @@
     for num, length in [(5, 60), (4, 60), (3, 24)]:  # seconds, minutes, hours
         part = order[num]
         carry_part = order[num - 1]
-        
+
         if deltas[part] < 0:
             deltas[part] += length
             deltas[carry_part] -= 1
@@ -323,13 +323,13 @@
             deltas['day'] += 29
         else:
             deltas['day'] += month_lengths[prevdate.month - 1]
-        
+
         deltas['month'] -= 1
-    
+
     if deltas['month'] < 0:
         deltas['month'] += 12
         deltas['year'] -= 1
-    
+
     # Format the result
     fmt_funcs = {
         'year': lambda d: ungettext(u'%d year', '%d years', d) % d,
@@ -339,21 +339,21 @@
         'minute': lambda d: ungettext(u'%d minute', '%d minutes', d) % d,
         'second': lambda d: ungettext(u'%d second', '%d seconds', d) % d,
     }
-    
+
     for i, part in enumerate(order):
         value = deltas[part]
         if value == 0:
             continue
-        
+
         if i < 5:
             sub_part = order[i + 1]
             sub_value = deltas[sub_part]
         else:
             sub_value = 0
-        
+
         if sub_value == 0:
             return _(u'%s ago') % fmt_funcs[part](value)
-        
+
         return _(u'%s and %s ago') % (fmt_funcs[part](value),
             fmt_funcs[sub_part](sub_value))
 
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/vcs/backends/git/changeset.py
--- a/rhodecode/lib/vcs/backends/git/changeset.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/vcs/backends/git/changeset.py	Tue Jun 05 21:22:23 2012 +0200
@@ -194,6 +194,11 @@
 
         return _prev(self, branch)
 
+    def diff(self, ignore_whitespace=True, context=3):
+        return ''.join(self.repository.get_diff(self, self.parents[0],
+                                    ignore_whitespace=ignore_whitespace,
+                                    context=context))
+
     def get_file_mode(self, path):
         """
         Returns stat mode of the file at the given ``path``.
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/vcs/backends/git/repository.py
--- a/rhodecode/lib/vcs/backends/git/repository.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/vcs/backends/git/repository.py	Tue Jun 05 21:22:23 2012 +0200
@@ -94,7 +94,7 @@
         if isinstance(cmd, basestring):
             cmd = [cmd]
             _str_cmd = True
- 
+
         gitenv = os.environ
         gitenv['GIT_CONFIG_NOGLOBAL'] = '1'
 
@@ -437,6 +437,12 @@
         if ignore_whitespace:
             flags.append('-w')
 
+        if hasattr(rev1, 'raw_id'):
+            rev1 = getattr(rev1, 'raw_id')
+
+        if hasattr(rev2, 'raw_id'):
+            rev2 = getattr(rev2, 'raw_id')
+
         if rev1 == self.EMPTY_CHANGESET:
             rev2 = self.get_changeset(rev2).raw_id
             cmd = ' '.join(['show'] + flags + [rev2])
@@ -500,6 +506,17 @@
         # If error occurs run_git_command raises RepositoryError already
         self.run_git_command(cmd)
 
+    def fetch(self, url):
+        """
+        Tries to pull changes from external location.
+        """
+        url = self._get_url(url)
+        cmd = ['fetch']
+        cmd.append(url)
+        cmd = ' '.join(cmd)
+        # If error occurs run_git_command raises RepositoryError already
+        self.run_git_command(cmd)
+
     @LazyProperty
     def workdir(self):
         """
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/vcs/backends/hg/changeset.py
--- a/rhodecode/lib/vcs/backends/hg/changeset.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/vcs/backends/hg/changeset.py	Tue Jun 05 21:22:23 2012 +0200
@@ -136,6 +136,11 @@
 
         return _prev(self, branch)
 
+    def diff(self, ignore_whitespace=True, context=3):
+        return ''.join(self._ctx.diff(git=True,
+                                      ignore_whitespace=ignore_whitespace,
+                                      context=context))
+
     def _fix_path(self, path):
         """
         Paths are stored without trailing slash so we need to get rid off it if
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/lib/vcs/backends/hg/repository.py
--- a/rhodecode/lib/vcs/backends/hg/repository.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/lib/vcs/backends/hg/repository.py	Tue Jun 05 21:22:23 2012 +0200
@@ -231,6 +231,12 @@
         :param context: How many lines before/after changed lines should be
           shown. Defaults to ``3``.
         """
+        if hasattr(rev1, 'raw_id'):
+            rev1 = getattr(rev1, 'raw_id')
+
+        if hasattr(rev2, 'raw_id'):
+            rev2 = getattr(rev2, 'raw_id')
+
         # Check if given revisions are present at repository (may raise
         # ChangesetDoesNotExistError)
         if rev1 != self.EMPTY_CHANGESET:
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/model/comment.py
--- a/rhodecode/model/comment.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/model/comment.py	Tue Jun 05 21:22:23 2012 +0200
@@ -104,6 +104,7 @@
             # add changeset author if it's in rhodecode system
             recipients += [User.get_by_email(author_email)]
 
+            # create notification objects, and emails
             NotificationModel().create(
               created_by=user_id, subject=subj, body=body,
               recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT,
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/model/notification.py
--- a/rhodecode/model/notification.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/model/notification.py	Tue Jun 05 21:22:23 2012 +0200
@@ -103,8 +103,11 @@
         if with_email is False:
             return notif
 
-        # send email with notification
-        for rec in recipients_objs:
+        #don't send email to person who created this comment
+        rec_objs = set(recipients_objs).difference(set([created_by_obj]))
+
+        # send email with notification to all other participants
+        for rec in rec_objs:
             email_subject = NotificationModel().make_description(notif, False)
             type_ = type_
             email_body = body
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/model/scm.py
--- a/rhodecode/model/scm.py	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/model/scm.py	Tue Jun 05 21:22:23 2012 +0200
@@ -360,8 +360,10 @@
             # inject ui extra param to log this action via push logger
             for k, v in extras.items():
                 repo._repo.ui.setconfig('rhodecode_extras', k, v)
-
-            repo.pull(clone_uri)
+            if repo.alias == 'git':
+                repo.fetch(clone_uri)
+            else:
+                repo.pull(clone_uri)
             self.mark_for_invalidation(repo_name)
         except:
             log.error(traceback.format_exc())
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/public/css/style.css
--- a/rhodecode/public/css/style.css	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/public/css/style.css	Tue Jun 05 21:22:23 2012 +0200
@@ -330,6 +330,11 @@
     z-index: auto !important;
 }
 
+.header-pos-fix{
+	margin-top: -44px;
+	padding-top: 44px;
+}
+
 #header #header-inner #home a {
 	height: 40px;
 	width: 46px;
@@ -2840,6 +2845,13 @@
 	box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
 }
 
+.mentions-container{
+	width: 90% !important;
+}
+.mentions-container .yui-ac-content{
+	width: 100% !important;
+}
+
 .ac {
 	vertical-align: top;
 }
diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/public/js/rhodecode.js
--- a/rhodecode/public/js/rhodecode.js	Wed May 30 23:12:24 2012 +0200
+++ b/rhodecode/public/js/rhodecode.js	Tue Jun 05 21:22:23 2012 +0200
@@ -44,6 +44,24 @@
 
 }();
 
+String.prototype.strip = function(char) {
+	if(char === undefined){
+	    char = '\\s';
+	}
+	return this.replace(new RegExp('^'+char+'+|'+char+'+$','g'), '');
+}
+String.prototype.lstrip = function(char) {
+	if(char === undefined){
+	    char = '\\s';
+	}
+	return this.replace(new RegExp('^'+char+'+'),'');
+}
+String.prototype.rstrip = function(char) {
+	if(char === undefined){
+	    char = '\\s';
+	}
+	return this.replace(new RegExp(''+char+'+$'),'');
+}
 
 /**
  * SmartColorGenerator
@@ -447,7 +465,7 @@
 		  
 		  ajaxPOST(submit_url, postData, success);
 	  });
-	  
+	  // callbacks
 	  tooltip_activate();
 };
 
@@ -819,7 +837,7 @@
 
 /** MEMBERS AUTOCOMPLETE WIDGET **/
 
-var MembersAutoComplete = function (users_list, groups_list, group_lbl, members_lbl) {
+var MembersAutoComplete = function (users_list, groups_list) {
     var myUsers = users_list;
     var myGroups = groups_list;
 
@@ -834,9 +852,11 @@
             // Match against each name of each contact
             for (; i < l; i++) {
                 contact = myUsers[i];
-                if ((contact.fname.toLowerCase().indexOf(query) > -1) || (contact.lname.toLowerCase().indexOf(query) > -1) || (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
-                    matches[matches.length] = contact;
-                }
+                if (((contact.fname+"").toLowerCase().indexOf(query) > -1) || 
+                   	 ((contact.lname+"").toLowerCase().indexOf(query) > -1) || 
+                   	 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
+                       matches[matches.length] = contact;
+                   }
             }
             return matches;
         };
@@ -912,21 +932,22 @@
                 var grname = oResultData.grname;
                 var grmembers = oResultData.grmembers;
                 var grnameMatchIndex = grname.toLowerCase().indexOf(query);
-                var grprefix = "{0}: ".format(group_lbl);
+                var grprefix = "{0}: ".format(_TM['Group']);
                 var grsuffix = " (" + grmembers + "  )";
-                var grsuffix = " ({0}  {1})".format(grmembers, members_lbl);
+                var grsuffix = " ({0}  {1})".format(grmembers, _TM['members']);
 
                 if (grnameMatchIndex > -1) {
                     return _gravatar(grprefix + highlightMatch(grname, query, grnameMatchIndex) + grsuffix,null,true);
                 }
 			    return _gravatar(grprefix + oResultData.grname + grsuffix, null,true);
             // Users
-            } else if (oResultData.fname != undefined) {
-                var fname = oResultData.fname,
-                    lname = oResultData.lname,
-                    nname = oResultData.nname || "",
-                    // Guard against null value
-                    fnameMatchIndex = fname.toLowerCase().indexOf(query),
+            } else if (oResultData.nname != undefined) {
+                var fname = oResultData.fname || "";
+                var lname = oResultData.lname || "";
+                var nname = oResultData.nname;
+                
+                // Guard against null value
+                var fnameMatchIndex = fname.toLowerCase().indexOf(query),
                     lnameMatchIndex = lname.toLowerCase().indexOf(query),
                     nnameMatchIndex = nname.toLowerCase().indexOf(query),
                     displayfname, displaylname, displaynname;
@@ -988,6 +1009,191 @@
 }
 
 
+var MentionsAutoComplete = function (divid, cont, users_list, groups_list) {
+    var myUsers = users_list;
+    var myGroups = groups_list;
+
+    // Define a custom search function for the DataSource of users
+    var matchUsers = function (sQuery) {
+    	    var org_sQuery = sQuery;
+    	    if(this.mentionQuery == null){
+    	    	return []    	    	
+    	    }
+    	    sQuery = this.mentionQuery;
+            // Case insensitive matching
+            var query = sQuery.toLowerCase();
+            var i = 0;
+            var l = myUsers.length;
+            var matches = [];
+
+            // Match against each name of each contact
+            for (; i < l; i++) {
+                contact = myUsers[i];
+                if (((contact.fname+"").toLowerCase().indexOf(query) > -1) || 
+                	 ((contact.lname+"").toLowerCase().indexOf(query) > -1) || 
+                	 ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
+                    matches[matches.length] = contact;
+                }
+            }
+            return matches
+        };
+
+    //match all
+    var matchAll = function (sQuery) {
+            u = matchUsers(sQuery);
+            return u
+        };
+
+    // DataScheme for owner
+    var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
+
+    ownerDS.responseSchema = {
+        fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
+    };
+
+    // Instantiate AutoComplete for mentions
+    var ownerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
+    ownerAC.useShadow = false;
+    ownerAC.resultTypeList = false;
+    ownerAC.suppressInputUpdate = true;
+
+    // Helper highlight function for the formatter
+    var highlightMatch = function (full, snippet, matchindex) {
+            return full.substring(0, matchindex) 
+            + "" 
+            + full.substr(matchindex, snippet.length) 
+            + "" + full.substring(matchindex + snippet.length);
+        };
+
+    // Custom formatter to highlight the matching letters
+    ownerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
+		    var org_sQuery = sQuery;
+		    if(this.dataSource.mentionQuery != null){
+		    	sQuery = this.dataSource.mentionQuery;		    	
+		    }
+
+            var query = sQuery.toLowerCase();
+            var _gravatar = function(res, em, group){
+            	if (group !== undefined){
+            		em = '/images/icons/group.png'
+            	}
+            	tmpl = '
{1}
' + return tmpl.format(em,res) + } + if (oResultData.nname != undefined) { + var fname = oResultData.fname || ""; + var lname = oResultData.lname || ""; + var nname = oResultData.nname; + + // Guard against null value + var fnameMatchIndex = fname.toLowerCase().indexOf(query), + lnameMatchIndex = lname.toLowerCase().indexOf(query), + nnameMatchIndex = nname.toLowerCase().indexOf(query), + displayfname, displaylname, displaynname; + + if (fnameMatchIndex > -1) { + displayfname = highlightMatch(fname, query, fnameMatchIndex); + } else { + displayfname = fname; + } + + if (lnameMatchIndex > -1) { + displaylname = highlightMatch(lname, query, lnameMatchIndex); + } else { + displaylname = lname; + } + + if (nnameMatchIndex > -1) { + displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")"; + } else { + displaynname = nname ? "(" + nname + ")" : ""; + } + + return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk); + } else { + return ''; + } + }; + + if(ownerAC.itemSelectEvent){ + ownerAC.itemSelectEvent.subscribe(function (sType, aArgs) { + + var myAC = aArgs[0]; // reference back to the AC instance + var elLI = aArgs[1]; // reference to the selected LI element + var oData = aArgs[2]; // object literal of selected item's result data + //fill the autocomplete with value + if (oData.nname != undefined) { + //users + //Replace the mention name with replaced + var re = new RegExp(); + var org = myAC.getInputEl().value; + var chunks = myAC.dataSource.chunks + // replace middle chunk(the search term) with actuall match + chunks[1] = chunks[1].replace('@'+myAC.dataSource.mentionQuery, + '@'+oData.nname+' '); + myAC.getInputEl().value = chunks.join('') + YUD.get(myAC.getInputEl()).focus(); // Y U NO WORK !? + } else { + //groups + myAC.getInputEl().value = oData.grname; + YUD.get('perm_new_member_type').value = 'users_group'; + } + }); + } + + // in this keybuffer we will gather current value of search ! + // since we need to get this just when someone does `@` then we do the + // search + ownerAC.dataSource.chunks = []; + ownerAC.dataSource.mentionQuery = null; + + ownerAC.get_mention = function(msg, max_pos) { + var org = msg; + var re = new RegExp('(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)$') + var chunks = []; + + + // cut first chunk until curret pos + var to_max = msg.substr(0, max_pos); + var at_pos = Math.max(0,to_max.lastIndexOf('@')-1); + var msg2 = to_max.substr(at_pos); + + chunks.push(org.substr(0,at_pos))// prefix chunk + chunks.push(msg2) // search chunk + chunks.push(org.substr(max_pos)) // postfix chunk + + // clean up msg2 for filtering and regex match + var msg2 = msg2.lstrip(' ').lstrip('\n'); + + if(re.test(msg2)){ + var unam = re.exec(msg2)[1]; + return [unam, chunks]; + } + return [null, null]; + }; + ownerAC.textboxKeyUpEvent.subscribe(function(type, args){ + + var ac_obj = args[0]; + var currentMessage = args[1]; + var currentCaretPosition = args[0]._elTextbox.selectionStart; + + var unam = ownerAC.get_mention(currentMessage, currentCaretPosition); + var curr_search = null; + if(unam[0]){ + curr_search = unam[0]; + } + + ownerAC.dataSource.chunks = unam[1]; + ownerAC.dataSource.mentionQuery = curr_search; + + }) + + return { + ownerDS: ownerDS, + ownerAC: ownerAC, + }; +} + /** * QUICK REPO MENU diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/public/js/yui.2.9.js --- a/rhodecode/public/js/yui.2.9.js Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/public/js/yui.2.9.js Tue Jun 05 21:22:23 2012 +0200 @@ -1,150 +1,866 @@ -/* -Copyright (c) 2011, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.com/yui/license.html -version: 2.9.0 -*/ -if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var b=arguments,g=null,e,c,f;for(e=0;e":">",'"':""","'":"'","/":"/","`":"`"},d=["toString","valueOf"],e={isArray:function(j){return a.toString.apply(j)===c;},isBoolean:function(j){return typeof j==="boolean";},isFunction:function(j){return(typeof j==="function")||a.toString.apply(j)===h;},isNull:function(j){return j===null;},isNumber:function(j){return typeof j==="number"&&isFinite(j);},isObject:function(j){return(j&&(typeof j==="object"||f.isFunction(j)))||false;},isString:function(j){return typeof j==="string";},isUndefined:function(j){return typeof j==="undefined";},_IEEnumFix:(YAHOO.env.ua.ie)?function(l,k){var j,n,m;for(j=0;j"'\/`]/g,function(k){return g[k];});},extend:function(m,n,l){if(!n||!m){throw new Error("extend failed, please check that "+"all dependencies are included.");}var k=function(){},j;k.prototype=n.prototype;m.prototype=new k();m.prototype.constructor=m;m.superclass=n.prototype;if(n.prototype.constructor==a.constructor){n.prototype.constructor=n;}if(l){for(j in l){if(f.hasOwnProperty(l,j)){m.prototype[j]=l[j];}}f._IEEnumFix(m.prototype,l);}},augmentObject:function(n,m){if(!m||!n){throw new Error("Absorb failed, verify dependencies.");}var j=arguments,l,o,k=j[2];if(k&&k!==true){for(l=2;l0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}if(r.length>1){r.pop();}r.push("]");}else{r.push("{");for(l in j){if(f.hasOwnProperty(j,l)){r.push(l+m);if(f.isObject(j[l])){r.push((p>0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}}if(r.length>1){r.pop();}r.push("}");}return r.join("");},substitute:function(x,y,E,l){var D,C,B,G,t,u,F=[],p,z=x.length,A="dump",r=" ",q="{",m="}",n,w;for(;;){D=x.lastIndexOf(q,z);if(D<0){break;}C=x.indexOf(m,D);if(D+1>C){break;}p=x.substring(D+1,C);G=p;u=null;B=G.indexOf(r);if(B>-1){u=G.substring(B+1);G=G.substring(0,B);}t=y[G];if(E){t=E(G,t,u);}if(f.isObject(t)){if(f.isArray(t)){t=f.dump(t,parseInt(u,10));}else{u=u||"";n=u.indexOf(A);if(n>-1){u=u.substring(4);}w=t.toString();if(w===i||n>-1){t=f.dump(t,parseInt(u,10));}else{t=w;}}}else{if(!f.isString(t)&&!f.isNumber(t)){t="~-"+F.length+"-~";F[F.length]=p;}}x=x.substring(0,D)+t+x.substring(C+1);if(l===false){z=D-1;}}for(D=F.length-1;D>=0;D=D-1){x=x.replace(new RegExp("~-"+D+"-~"),"{"+F[D]+"}","g");}return x;},trim:function(j){try{return j.replace(/^\s+|\s+$/g,"");}catch(k){return j; -}},merge:function(){var n={},k=arguments,j=k.length,m;for(m=0;m=420){z.addEventListener("load",function(){YAHOO.log(x+" DOM2 onload "+u,"info","Get");F(x,u);});}else{t=m[x];if(t.varName){v=YAHOO.util.Get.POLL_FREQ;YAHOO.log("Polling for "+t.varName[0]);t.maxattempts=YAHOO.util.Get.TIMEOUT/v;t.attempts=0;t._cache=t.varName[0].split(".");t.timer=s.later(v,t,function(w){I=this._cache;A=I.length;J=this.win;for(C=0;Cthis.maxattempts){y="Over retry limit, giving up";t.timer.cancel();q(x,y);}else{YAHOO.log(I[C]+" failed, retrying");}return;}}YAHOO.log("Safari poll complete");t.timer.cancel();F(x,u);},null,true);}else{s.later(YAHOO.util.Get.POLL_FREQ,null,F,[x,u]);}}}}else{z.onload=function(){YAHOO.log(x+" onload "+u,"info","Get");F(x,u);};}}};q=function(w,v){YAHOO.log("get failure: "+v,"warn","Get");var u=m[w],t;if(u.onFailure){t=u.scope||u.win;u.onFailure.call(t,a(u,v));}};d=function(z){if(m[z]){var t=m[z],u=t.nodes,x=u.length,C=t.win.document,A=C.getElementsByTagName("head")[0],v,y,w,B;if(t.insertBefore){v=b(t.insertBefore,z);if(v){A=v.parentNode;}}for(y=0;y=m.rollup);if(roll){break;}}}}}else{for(j=0;j=m.rollup);if(roll){break;}}}}}if(roll){r[i]=true;rolled=true;this.getRequires(m);}}}if(!rolled){break;}}},_reduce:function(){var i,j,s,m,r=this.required;for(i in r){if(i in this.loaded){delete r[i];}else{var skinDef=this.parseSkin(i);if(skinDef){if(!skinDef.module){var skin_pre=this.SKIN_PREFIX+skinDef.skin;for(j in r){if(lang.hasOwnProperty(r,j)){m=this.moduleInfo[j];var ext=m&&m.ext;if(!ext&&j!==i&&j.indexOf(skin_pre)>-1){delete r[j];}}}}}else{m=this.moduleInfo[i];s=m&&m.supersedes;if(s){for(j=0;j-1){return true;}if(after&&YUI.ArrayUtil.indexOf(after,bb)>-1){return true;}if(checkOptional&&optional&&YUI.ArrayUtil.indexOf(optional,bb)>-1){return true;}var ss=info[bb]&&info[bb].supersedes;if(ss){for(ii=0;iistartLen){YAHOO.util.Get.script(self._filter(js),{data:self._loading,onSuccess:callback,onFailure:self._onFailure,onTimeout:self._onTimeout,insertBefore:self.insertBefore,charset:self.charset,timeout:self.timeout,scope:self});}else{this.loadNext();}};if(css.length>startLen){YAHOO.util.Get.css(this._filter(css),{data:this._loading,onSuccess:loadScript,onFailure:this._onFailure,onTimeout:this._onTimeout,insertBefore:this.insertBefore,charset:this.charset,timeout:this.timeout,scope:self});}else{loadScript();}return;}else{this.loadNext(this._loading);}},insert:function(o,type){this.calculate(o);this._loading=true;this.loadType=type;if(this.combine){return this._combine();}if(!type){var self=this;this._internalCallback=function(){self._internalCallback=null;self.insert(null,"js");};this.insert(null,"css");return;}this.loadNext();},sandbox:function(o,type){var self=this,success=function(o){var idx=o.argument[0],name=o.argument[2];self._scriptText[idx]=o.responseText;if(self.onProgress){self.onProgress.call(self.scope,{name:name,scriptText:o.responseText,xhrResponse:o,data:self.data});}self._loadCount++;if(self._loadCount>=self._stopCount){var v=self.varName||"YAHOO";var t="(function() {\n";var b="\nreturn "+v+";\n})();";var ref=eval(t+self._scriptText.join("\n")+b);self._pushEvents(ref);if(ref){self.onSuccess.call(self.scope,{reference:ref,data:self.data});}else{self._onFailure.call(self.varName+" reference failure");}}},failure=function(o){self.onFailure.call(self.scope,{msg:"XHR failure",xhrResponse:o,data:self.data});};self._config(o);if(!self.onSuccess){throw new Error("You must supply an onSuccess handler for your sandbox");}self._sandbox=true;if(!type||type!=="js"){self._internalCallback=function(){self._internalCallback=null;self.sandbox(null,"js");};self.insert(null,"css");return;}if(!util.Connect){var ld=new YAHOO.util.YUILoader();ld.insert({base:self.base,filter:self.filter,require:"connection",insertBefore:self.insertBefore,charset:self.charset,onSuccess:function(){self.sandbox(null,"js");},scope:self},"js");return;}self._scriptText=[];self._loadCount=0;self._stopCount=self.sorted.length;self._xhr=[];self.calculate();var s=self.sorted,l=s.length,i,m,url;for(i=0;i-1;}}else{}return G;},addClass:function(W,G){return e.Dom.batch(W,e.Dom._addClass,G);},_addClass:function(X,W){var G=false,Y;if(X&&W){Y=e.Dom._getAttribute(X,f)||i;if(!e.Dom._hasClass(X,W)){e.Dom.setAttribute(X,f,a(Y+b+W));G=true;}}else{}return G;},removeClass:function(W,G){return e.Dom.batch(W,e.Dom._removeClass,G);},_removeClass:function(Y,X){var W=false,aa,Z,G;if(Y&&X){aa=e.Dom._getAttribute(Y,f)||i;e.Dom.setAttribute(Y,f,aa.replace(e.Dom._getClassRegex(X),i));Z=e.Dom._getAttribute(Y,f);if(aa!==Z){e.Dom.setAttribute(Y,f,a(Z));W=true;if(e.Dom._getAttribute(Y,f)===""){G=(Y.hasAttribute&&Y.hasAttribute(E))?E:f;Y.removeAttribute(G);}}}else{}return W;},replaceClass:function(X,W,G){return e.Dom.batch(X,e.Dom._replaceClass,{from:W,to:G});},_replaceClass:function(Y,X){var W,ab,aa,G=false,Z;if(Y&&X){ab=X.from;aa=X.to;if(!aa){G=false;}else{if(!ab){G=e.Dom._addClass(Y,X.to);}else{if(ab!==aa){Z=e.Dom._getAttribute(Y,f)||i;W=(b+Z.replace(e.Dom._getClassRegex(ab),b+aa).replace(/\s+/g,b)).split(e.Dom._getClassRegex(aa));W.splice(1,0,b+aa);e.Dom.setAttribute(Y,f,a(W.join(i)));G=true;}}}}else{}return G;},generateId:function(G,X){X=X||"yui-gen";var W=function(Y){if(Y&&Y.id){return Y.id;}var Z=X+YAHOO.env._id_counter++; -if(Y){if(Y[C]&&Y[C].getElementById(Z)){return e.Dom.generateId(Y,Z+X);}Y.id=Z;}return Z;};return e.Dom.batch(G,W,e.Dom,true)||W.apply(e.Dom,arguments);},isAncestor:function(W,X){W=e.Dom.get(W);X=e.Dom.get(X);var G=false;if((W&&X)&&(W[K]&&X[K])){if(W.contains&&W!==X){G=W.contains(X);}else{if(W.compareDocumentPosition){G=!!(W.compareDocumentPosition(X)&16);}}}else{}return G;},inDocument:function(G,W){return e.Dom._inDoc(e.Dom.get(G),W);},_inDoc:function(W,X){var G=false;if(W&&W[c]){X=X||W[C];G=e.Dom.isAncestor(X[U],W);}else{}return G;},getElementsBy:function(W,af,ab,ad,X,ac,ae){af=af||"*";ab=(ab)?e.Dom.get(ab):null||j;var aa=(ae)?null:[],G;if(ab){G=ab.getElementsByTagName(af);for(var Y=0,Z=G.length;Y=8){e.Dom.DOT_ATTRIBUTES.type=true;}})();YAHOO.util.Region=function(d,e,a,c){this.top=d;this.y=d;this[1]=d;this.right=e;this.bottom=a;this.left=c;this.x=c;this[0]=c;this.width=this.right-this.left;this.height=this.bottom-this.top;};YAHOO.util.Region.prototype.contains=function(a){return(a.left>=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(f){var d=Math.max(this.top,f.top),e=Math.min(this.right,f.right),a=Math.min(this.bottom,f.bottom),c=Math.max(this.left,f.left); -if(a>=d&&e>=c){return new YAHOO.util.Region(d,e,a,c);}else{return null;}};YAHOO.util.Region.prototype.union=function(f){var d=Math.min(this.top,f.top),e=Math.max(this.right,f.right),a=Math.max(this.bottom,f.bottom),c=Math.min(this.left,f.left);return new YAHOO.util.Region(d,e,a,c);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+", height: "+this.height+", width: "+this.width+"}");};YAHOO.util.Region.getRegion=function(e){var g=YAHOO.util.Dom.getXY(e),d=g[1],f=g[0]+e.offsetWidth,a=g[1]+e.offsetHeight,c=g[0];return new YAHOO.util.Region(d,f,a,c);};YAHOO.util.Point=function(a,b){if(YAHOO.lang.isArray(a)){b=a[1];a=a[0];}YAHOO.util.Point.superclass.constructor.call(this,b,a,b,a);};YAHOO.extend(YAHOO.util.Point,YAHOO.util.Region);(function(){var b=YAHOO.util,a="clientTop",f="clientLeft",j="parentNode",k="right",w="hasLayout",i="px",u="opacity",l="auto",d="borderLeftWidth",g="borderTopWidth",p="borderRightWidth",v="borderBottomWidth",s="visible",q="transparent",n="height",e="width",h="style",t="currentStyle",r=/^width|height$/,o=/^(\d[.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz|%){1}?/i,m={get:function(x,z){var y="",A=x[t][z];if(z===u){y=b.Dom.getStyle(x,u);}else{if(!A||(A.indexOf&&A.indexOf(i)>-1)){y=A;}else{if(b.Dom.IE_COMPUTED[z]){y=b.Dom.IE_COMPUTED[z](x,z);}else{if(o.test(A)){y=b.Dom.IE.ComputedStyle.getPixel(x,z);}else{y=A;}}}}return y;},getOffset:function(z,E){var B=z[t][E],x=E.charAt(0).toUpperCase()+E.substr(1),C="offset"+x,y="pixel"+x,A="",D;if(B==l){D=z[C];if(D===undefined){A=0;}A=D;if(r.test(E)){z[h][E]=D;if(z[C]>D){A=D-(z[C]-D);}z[h][E]=l;}}else{if(!z[h][y]&&!z[h][E]){z[h][E]=B;}A=z[h][y];}return A+i;},getBorderWidth:function(x,z){var y=null;if(!x[t][w]){x[h].zoom=1;}switch(z){case g:y=x[a];break;case v:y=x.offsetHeight-x.clientHeight-x[a];break;case d:y=x[f];break;case p:y=x.offsetWidth-x.clientWidth-x[f];break;}return y+i;},getPixel:function(y,x){var A=null,B=y[t][k],z=y[t][x];y[h][k]=z;A=y[h].pixelRight;y[h][k]=B;return A+i;},getMargin:function(y,x){var z;if(y[t][x]==l){z=0+i;}else{z=b.Dom.IE.ComputedStyle.getPixel(y,x);}return z;},getVisibility:function(y,x){var z;while((z=y[t])&&z[x]=="inherit"){y=y[j];}return(z)?z[x]:s;},getColor:function(y,x){return b.Dom.Color.toRGB(y[t][x])||q;},getBorderColor:function(y,x){var z=y[t],A=z[x]||z.color;return b.Dom.Color.toRGB(b.Dom.Color.toHex(A));}},c={};c.top=c.right=c.bottom=c.left=c[e]=c[n]=m.getOffset;c.color=m.getColor;c[g]=c[p]=c[v]=c[d]=m.getBorderWidth;c.marginTop=c.marginRight=c.marginBottom=c.marginLeft=m.getMargin;c.visibility=m.getVisibility;c.borderColor=c.borderTopColor=c.borderRightColor=c.borderBottomColor=c.borderLeftColor=m.getBorderColor;b.Dom.IE_COMPUTED=c;b.Dom.IE_ComputedStyle=m;})();(function(){var c="toString",a=parseInt,b=RegExp,d=YAHOO.util;d.Dom.Color={KEYWORDS:{black:"000",silver:"c0c0c0",gray:"808080",white:"fff",maroon:"800000",red:"f00",purple:"800080",fuchsia:"f0f",green:"008000",lime:"0f0",olive:"808000",yellow:"ff0",navy:"000080",blue:"00f",teal:"008080",aqua:"0ff"},re_RGB:/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,re_hex:/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,re_hex3:/([0-9A-F])/gi,toRGB:function(e){if(!d.Dom.Color.re_RGB.test(e)){e=d.Dom.Color.toHex(e);}if(d.Dom.Color.re_hex.exec(e)){e="rgb("+[a(b.$1,16),a(b.$2,16),a(b.$3,16)].join(", ")+")";}return e;},toHex:function(f){f=d.Dom.Color.KEYWORDS[f]||f;if(d.Dom.Color.re_RGB.exec(f)){f=[Number(b.$1).toString(16),Number(b.$2).toString(16),Number(b.$3).toString(16)];for(var e=0;e0){i=c[0];}try{b=g.fn.call(f,i,g.obj);}catch(h){this.lastError=h;if(a){throw h;}}}else{try{b=g.fn.call(f,this.type,c,g.obj);}catch(d){this.lastError=d;if(a){throw d;}}}return b;},unsubscribeAll:function(){var a=this.subscribers.length,b;for(b=a-1;b>-1;b--){this._delete(b);}this.subscribers=[];return a;},_delete:function(a){var b=this.subscribers[a];if(b){delete b.fn;delete b.obj;}this.subscribers.splice(a,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"context: "+this.scope;}};YAHOO.util.Subscriber=function(a,b,c){this.fn=a;this.obj=YAHOO.lang.isUndefined(b)?null:b;this.overrideContext=c;};YAHOO.util.Subscriber.prototype.getScope=function(a){if(this.overrideContext){if(this.overrideContext===true){return this.obj;}else{return this.overrideContext;}}return a;};YAHOO.util.Subscriber.prototype.contains=function(a,b){if(b){return(this.fn==a&&this.obj==b);}else{return(this.fn==a);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", overrideContext: "+(this.overrideContext||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var g=false,h=[],j=[],a=0,e=[],b=0,c={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9},d=YAHOO.env.ua.ie,f="focusin",i="focusout";return{POLL_RETRYS:500,POLL_INTERVAL:40,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,CAPTURE:7,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:d,_interval:null,_dri:null,_specialTypes:{focusin:(d?"focusin":"focus"),focusout:(d?"focusout":"blur")},DOMReady:false,throwErrors:false,startInterval:function(){if(!this._interval){this._interval=YAHOO.lang.later(this.POLL_INTERVAL,this,this._tryPreloadAttach,null,true);}},onAvailable:function(q,m,o,p,n){var k=(YAHOO.lang.isString(q))?[q]:q;for(var l=0;l-1;m--){s=(this.removeListener(l[m],k,r)&&s);}return s;}}if(!r||!r.call){return this.purgeElement(l,false,k);}if("unload"==k){for(m=j.length-1;m>-1;m--){u=j[m];if(u&&u[0]==l&&u[1]==k&&u[2]==r){j.splice(m,1);return true;}}return false;}var n=null;var o=arguments[3];if("undefined"===typeof o){o=this._getCacheIndex(h,l,k,r);}if(o>=0){n=h[o];}if(!l||!n){return false;}var t=n[this.CAPTURE]===true?true:false;try{this._simpleRemove(l,k,n[this.WFN],t);}catch(q){this.lastError=q;return false;}delete h[o][this.WFN];delete h[o][this.FN];h.splice(o,1);return true;},getTarget:function(m,l){var k=m.target||m.srcElement;return this.resolveTextNode(k);},resolveTextNode:function(l){try{if(l&&3==l.nodeType){return l.parentNode;}}catch(k){return null;}return l;},getPageX:function(l){var k=l.pageX;if(!k&&0!==k){k=l.clientX||0;if(this.isIE){k+=this._getScrollLeft();}}return k;},getPageY:function(k){var l=k.pageY;if(!l&&0!==l){l=k.clientY||0;if(this.isIE){l+=this._getScrollTop();}}return l;},getXY:function(k){return[this.getPageX(k),this.getPageY(k)];},getRelatedTarget:function(l){var k=l.relatedTarget; -if(!k){if(l.type=="mouseout"){k=l.toElement;}else{if(l.type=="mouseover"){k=l.fromElement;}}}return this.resolveTextNode(k);},getTime:function(m){if(!m.time){var l=new Date().getTime();try{m.time=l;}catch(k){this.lastError=k;return l;}}return m.time;},stopEvent:function(k){this.stopPropagation(k);this.preventDefault(k);},stopPropagation:function(k){if(k.stopPropagation){k.stopPropagation();}else{k.cancelBubble=true;}},preventDefault:function(k){if(k.preventDefault){k.preventDefault();}else{k.returnValue=false;}},getEvent:function(m,k){var l=m||window.event;if(!l){var n=this.getEvent.caller;while(n){l=n.arguments[0];if(l&&Event==l.constructor){break;}n=n.caller;}}return l;},getCharCode:function(l){var k=l.keyCode||l.charCode||0;if(YAHOO.env.ua.webkit&&(k in c)){k=c[k];}return k;},_getCacheIndex:function(n,q,r,p){for(var o=0,m=n.length;o0&&e.length>0);}var p=[];var r=function(t,u){var s=t;if(u.overrideContext){if(u.overrideContext===true){s=u.obj;}else{s=u.overrideContext;}}u.fn.call(s,u.obj);};var l,k,o,n,m=[];for(l=0,k=e.length;l-1;l--){o=e[l];if(!o||!o.id){e.splice(l,1);}}this.startInterval();}else{if(this._interval){this._interval.cancel();this._interval=null;}}this.locked=false;},purgeElement:function(p,q,s){var n=(YAHOO.lang.isString(p))?this.getEl(p):p;var r=this.getListeners(n,s),o,k;if(r){for(o=r.length-1;o>-1;o--){var m=r[o];this.removeListener(n,m.type,m.fn);}}if(q&&n&&n.childNodes){for(o=0,k=n.childNodes.length;o-1;o--){n=h[o];if(n){try{m.removeListener(n[m.EL],n[m.TYPE],n[m.FN],o);}catch(v){}}}n=null;}try{m._simpleRemove(window,"unload",m._unload);m._simpleRemove(window,"load",m._load);}catch(u){}},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var k=document.documentElement,l=document.body;if(k&&(k.scrollTop||k.scrollLeft)){return[k.scrollTop,k.scrollLeft];}else{if(l){return[l.scrollTop,l.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(m,n,l,k){m.addEventListener(n,l,(k));};}else{if(window.attachEvent){return function(m,n,l,k){m.attachEvent("on"+n,l);};}else{return function(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(m,n,l,k){m.removeEventListener(n,l,(k));};}else{if(window.detachEvent){return function(l,m,k){l.detachEvent("on"+m,k);};}else{return function(){};}}}()};}();(function(){var a=YAHOO.util.Event;a.on=a.addListener;a.onFocus=a.addFocusListener;a.onBlur=a.addBlurListener; -/*! DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller/Diego Perini */ -if(a.isIE){if(self!==self.top){document.onreadystatechange=function(){if(document.readyState=="complete"){document.onreadystatechange=null;a._ready();}};}else{YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var b=document.createElement("p");a._dri=setInterval(function(){try{b.doScroll("left");clearInterval(a._dri);a._dri=null;a._ready();b=null;}catch(c){}},a.POLL_INTERVAL);}}else{if(a.webkit&&a.webkit<525){a._dri=setInterval(function(){var c=document.readyState;if("loaded"==c||"complete"==c){clearInterval(a._dri);a._dri=null;a._ready();}},a.POLL_INTERVAL);}else{a._simpleAdd(document,"DOMContentLoaded",a._ready);}}a._simpleAdd(window,"load",a._load);a._simpleAdd(window,"unload",a._unload);a._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(a,c,f,e){this.__yui_events=this.__yui_events||{};var d=this.__yui_events[a];if(d){d.subscribe(c,f,e);}else{this.__yui_subscribers=this.__yui_subscribers||{};var b=this.__yui_subscribers;if(!b[a]){b[a]=[];}b[a].push({fn:c,obj:f,overrideContext:e});}},unsubscribe:function(c,e,g){this.__yui_events=this.__yui_events||{};var a=this.__yui_events;if(c){var f=a[c];if(f){return f.unsubscribe(e,g);}}else{var b=true;for(var d in a){if(YAHOO.lang.hasOwnProperty(a,d)){b=b&&a[d].unsubscribe(e,g); -}}return b;}return false;},unsubscribeAll:function(a){return this.unsubscribe(a);},createEvent:function(b,g){this.__yui_events=this.__yui_events||{};var e=g||{},d=this.__yui_events,f;if(d[b]){}else{f=new YAHOO.util.CustomEvent(b,e.scope||this,e.silent,YAHOO.util.CustomEvent.FLAT,e.fireOnce);d[b]=f;if(e.onSubscribeCallback){f.subscribeEvent.subscribe(e.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var a=this.__yui_subscribers[b];if(a){for(var c=0;c=200&&f<300)||f===1223||c){a=b.xdr?b.r:this.createResponseObject(b,h);if(j&&j.success){if(!j.scope){j.success(a);}else{j.success.apply(j.scope,[a]);}}this.successEvent.fire(a);if(b.successEvent){b.successEvent.fire(a);}}else{switch(f){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:a=this.createExceptionObject(b.tId,h,(d?d:false));if(j&&j.failure){if(!j.scope){j.failure(a);}else{j.failure.apply(j.scope,[a]);}}break;default:a=(b.xdr)?b.response:this.createResponseObject(b,h);if(j&&j.failure){if(!j.scope){j.failure(a);}else{j.failure.apply(j.scope,[a]);}}}this.failureEvent.fire(a);if(b.failureEvent){b.failureEvent.fire(a);}}this.releaseObject(b);a=null;},createResponseObject:function(a,h){var d={},k={},f,c,g,b;try{c=a.conn.getAllResponseHeaders();g=c.split("\n");for(f=0;f'+''+''+"",k=document.createElement("div");document.body.appendChild(k);k.innerHTML=j;}function b(l,i,j,n,k){h[parseInt(l.tId)]={"o":l,"c":n};if(k){n.method=i;n.data=k;}l.conn.send(j,n,l.tId);}function e(i){d(i);g._transport=document.getElementById("YUIConnectionSwf");}function c(){g.xdrReadyEvent.fire();}function a(j,i){if(j){g.startEvent.fire(j,i.argument);if(j.startEvent){j.startEvent.fire(j,i.argument);}}}function f(j){var k=h[j.tId].o,i=h[j.tId].c;if(j.statusText==="xdr:start"){a(k,i);return;}j.responseText=decodeURI(j.responseText);k.r=j;if(i.argument){k.r.argument=i.argument;}this.handleTransactionResponse(k,i,j.statusText==="xdr:abort"?true:false);delete h[j.tId];}g.xdr=b;g.swf=d;g.transport=e;g.xdrReadyEvent=new YAHOO.util.CustomEvent("xdrReady");g.xdrReady=c;g.handleXdrResponse=f;})();(function(){var e=YAHOO.util.Connect,g=YAHOO.util.Event,a=document.documentMode?document.documentMode:false;e._isFileUpload=false;e._formNode=null;e._sFormData=null;e._submitElementValue=null;e.uploadEvent=new YAHOO.util.CustomEvent("upload");e._hasSubmitListener=function(){if(g){g.addListener(document,"click",function(k){var j=g.getTarget(k),i=j.nodeName.toLowerCase();if((i==="input"||i==="button")&&(j.type&&j.type.toLowerCase()=="submit")){e._submitElementValue=encodeURIComponent(j.name)+"="+encodeURIComponent(j.value);}});return true;}return false;}();function h(w,r,m){var v,l,u,s,z,t=false,p=[],y=0,o,q,n,x,k;this.resetFormState();if(typeof w=="string"){v=(document.getElementById(w)||document.forms[w]);}else{if(typeof w=="object"){v=w;}else{return;}}if(r){this.createFrame(m?m:null);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=v;return;}for(o=0,q=v.elements.length;o-1){k=l.options[l.selectedIndex];p[y++]=u+encodeURIComponent((k.attributes.value&&k.attributes.value.specified)?k.value:k.text);}break;case"select-multiple":if(l.selectedIndex>-1){for(n=l.selectedIndex,x=l.options.length;n');if(typeof i=="boolean"){k.src="javascript:false";}}else{k=document.createElement("iframe");k.id=j;k.name=j;}k.style.position="absolute";k.style.top="-1000px";k.style.left="-1000px";document.body.appendChild(k);}function f(j){var m=[],k=j.split("&"),l,n;for(l=0;l=8)?true:false,z=this,v=(y&&y.argument)?y.argument:null,x,s,k,r,j,q;j={action:this._formNode.getAttribute("action"),method:this._formNode.getAttribute("method"),target:this._formNode.getAttribute("target")};this._formNode.setAttribute("action",n);this._formNode.setAttribute("method","POST");this._formNode.setAttribute("target",t);if(YAHOO.env.ua.ie&&!p){this._formNode.setAttribute("encoding",u);}else{this._formNode.setAttribute("enctype",u);}if(l){x=this.appendPostData(l);}this._formNode.submit();this.startEvent.fire(m,v);if(m.startEvent){m.startEvent.fire(m,v);}if(y&&y.timeout){this._timeOut[m.tId]=window.setTimeout(function(){z.abort(m,y,true);},y.timeout);}if(x&&x.length>0){for(s=0;s0)?f:0;}if(c in d&&!("style" in d&&c in d.style)){d[c]=f;}else{b.Dom.setStyle(d,c,f+e);}},getAttribute:function(c){var e=this.getEl();var g=b.Dom.getStyle(e,c);if(g!=="auto"&&!this.patterns.offsetUnit.test(g)){return parseFloat(g);}var d=this.patterns.offsetAttribute.exec(c)||[];var h=!!(d[3]);var f=!!(d[2]);if("style" in e){if(f||(b.Dom.getStyle(e,"position")=="absolute"&&h)){g=e["offset"+d[0].charAt(0).toUpperCase()+d[0].substr(1)];}else{g=0;}}else{if(c in e){g=e[c];}}return g;},getDefaultUnit:function(c){if(this.patterns.defaultUnit.test(c)){return"px";}return"";},setRuntimeAttribute:function(d){var j;var e;var f=this.attributes;this.runtimeAttributes[d]={};var h=function(i){return(typeof i!=="undefined");};if(!h(f[d]["to"])&&!h(f[d]["by"])){return false;}j=(h(f[d]["from"]))?f[d]["from"]:this.getAttribute(d);if(h(f[d]["to"])){e=f[d]["to"];}else{if(h(f[d]["by"])){if(j.constructor==Array){e=[];for(var g=0,c=j.length;g0&&isFinite(o)){if(k.currentFrame+o>=n){o=n-(m+1);}k.currentFrame+=o;}};this._queue=c;this._getIndex=a;};YAHOO.util.Bezier=new function(){this.getPosition=function(e,d){var f=e.length;var c=[];for(var b=0;b0&&!(m[0] instanceof Array)){m=[m];}else{var l=[];for(n=0,p=m.length;n0){this.runtimeAttributes[q]=this.runtimeAttributes[q].concat(m);}this.runtimeAttributes[q][this.runtimeAttributes[q].length]=j;}else{f.setRuntimeAttribute.call(this,q);}};var b=function(g,i){var h=e.Dom.getXY(this.getEl());g=[g[0]-h[0]+i[0],g[1]-h[1]+i[1]];return g;};var d=function(g){return(typeof g!=="undefined");};e.Motion=a;})();(function(){var d=function(f,e,g,h){if(f){d.superclass.constructor.call(this,f,e,g,h);}};d.NAME="Scroll";var b=YAHOO.util;YAHOO.extend(d,b.ColorAnim);var c=d.superclass;var a=d.prototype;a.doMethod=function(e,h,f){var g=null;if(e=="scroll"){g=[this.method(this.currentFrame,h[0],f[0]-h[0],this.totalFrames),this.method(this.currentFrame,h[1],f[1]-h[1],this.totalFrames)];}else{g=c.doMethod.call(this,e,h,f);}return g;};a.getAttribute=function(e){var g=null;var f=this.getEl();if(e=="scroll"){g=[f.scrollLeft,f.scrollTop];}else{g=c.getAttribute.call(this,e);}return g;};a.setAttribute=function(e,h,g){var f=this.getEl();if(e=="scroll"){f.scrollLeft=h[0];f.scrollTop=h[1];}else{c.setAttribute.call(this,e,h,g);}};b.Scroll=d;})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.9.0",build:"2800"});if(!YAHOO.util.DragDropMgr){YAHOO.util.DragDropMgr=function(){var A=YAHOO.util.Event,B=YAHOO.util.Dom;return{useShim:false,_shimActive:false,_shimState:false,_debugShim:false,_createShim:function(){var C=document.createElement("div");C.id="yui-ddm-shim";if(document.body.firstChild){document.body.insertBefore(C,document.body.firstChild);}else{document.body.appendChild(C);}C.style.display="none";C.style.backgroundColor="red";C.style.position="absolute";C.style.zIndex="99999";B.setStyle(C,"opacity","0");this._shim=C;A.on(C,"mouseup",this.handleMouseUp,this,true);A.on(C,"mousemove",this.handleMouseMove,this,true);A.on(window,"scroll",this._sizeShim,this,true);},_sizeShim:function(){if(this._shimActive){var C=this._shim;C.style.height=B.getDocumentHeight()+"px";C.style.width=B.getDocumentWidth()+"px";C.style.top="0";C.style.left="0";}},_activateShim:function(){if(this.useShim){if(!this._shim){this._createShim();}this._shimActive=true;var C=this._shim,D="0";if(this._debugShim){D=".5";}B.setStyle(C,"opacity",D);this._sizeShim();C.style.display="block";}},_deactivateShim:function(){this._shim.style.display="none";this._shimActive=false;},_shim:null,ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,interactionInfo:null,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,STRICT_INTERSECT:2,mode:0,_execOnAll:function(E,D){for(var F in this.ids){for(var C in this.ids[F]){var G=this.ids[F][C];if(!this.isTypeOfDD(G)){continue;}G[E].apply(G,D);}}},_onLoad:function(){this.init();A.on(document,"mouseup",this.handleMouseUp,this,true);A.on(document,"mousemove",this.handleMouseMove,this,true);A.on(window,"unload",this._onUnload,this,true);A.on(window,"resize",this._onResize,this,true);},_onResize:function(C){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:1000,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,fromTimeout:false,regDragDrop:function(D,C){if(!this.initialized){this.init();}if(!this.ids[C]){this.ids[C]={};}this.ids[C][D.id]=D;},removeDDFromGroup:function(E,C){if(!this.ids[C]){this.ids[C]={};}var D=this.ids[C];if(D&&D[E.id]){delete D[E.id];}},_remove:function(E){for(var D in E.groups){if(D){var C=this.ids[D];if(C&&C[E.id]){delete C[E.id];}}}delete this.handleIds[E.id];},regHandle:function(D,C){if(!this.handleIds[D]){this.handleIds[D]={};}this.handleIds[D][C]=C;},isDragDrop:function(C){return(this.getDDById(C))?true:false;},getRelated:function(H,D){var G=[];for(var F in H.groups){for(var E in this.ids[F]){var C=this.ids[F][E];if(!this.isTypeOfDD(C)){continue;}if(!D||C.isTarget){G[G.length]=C;}}}return G;},isLegalTarget:function(G,F){var D=this.getRelated(G,true);for(var E=0,C=D.length;Ethis.clickPixelThresh||D>this.clickPixelThresh){this.startDrag(this.startX,this.startY);}}if(this.dragThreshMet){if(C&&C.events.b4Drag){C.b4Drag(F);C.fireEvent("b4DragEvent",{e:F});}if(C&&C.events.drag){C.onDrag(F);C.fireEvent("dragEvent",{e:F});}if(C){this.fireEvents(F,false);}}this.stopEvent(F);}},fireEvents:function(W,M){var c=this.dragCurrent;if(!c||c.isLocked()||c.dragOnly){return;}var O=YAHOO.util.Event.getPageX(W),N=YAHOO.util.Event.getPageY(W),Q=new YAHOO.util.Point(O,N),K=c.getTargetCoord(Q.x,Q.y),F=c.getDragEl(),E=["out","over","drop","enter"],V=new YAHOO.util.Region(K.y,K.x+F.offsetWidth,K.y+F.offsetHeight,K.x),I=[],D={},L={},R=[],d={outEvts:[],overEvts:[],dropEvts:[],enterEvts:[]};for(var T in this.dragOvers){var f=this.dragOvers[T];if(!this.isTypeOfDD(f)){continue; -}if(!this.isOverTarget(Q,f,this.mode,V)){d.outEvts.push(f);}I[T]=true;delete this.dragOvers[T];}for(var S in c.groups){if("string"!=typeof S){continue;}for(T in this.ids[S]){var G=this.ids[S][T];if(!this.isTypeOfDD(G)){continue;}if(G.isTarget&&!G.isLocked()&&G!=c){if(this.isOverTarget(Q,G,this.mode,V)){D[S]=true;if(M){d.dropEvts.push(G);}else{if(!I[G.id]){d.enterEvts.push(G);}else{d.overEvts.push(G);}this.dragOvers[G.id]=G;}}}}}this.interactionInfo={out:d.outEvts,enter:d.enterEvts,over:d.overEvts,drop:d.dropEvts,point:Q,draggedRegion:V,sourceRegion:this.locationCache[c.id],validDrop:M};for(var C in D){R.push(C);}if(M&&!d.dropEvts.length){this.interactionInfo.validDrop=false;if(c.events.invalidDrop){c.onInvalidDrop(W);c.fireEvent("invalidDropEvent",{e:W});}}for(T=0;T2000){}else{setTimeout(C._addListeners,10);if(document&&document.body){C._timeoutCount+=1;}}}},handleWasClicked:function(C,E){if(this.isHandle(E,C.id)){return true;}else{var D=C.parentNode;while(D){if(this.isHandle(E,D.id)){return true;}else{D=D.parentNode;}}}return false;}};}();YAHOO.util.DDM=YAHOO.util.DragDropMgr;YAHOO.util.DDM._addListeners();}(function(){var A=YAHOO.util.Event;var B=YAHOO.util.Dom;YAHOO.util.DragDrop=function(E,C,D){if(E){this.init(E,C,D);}};YAHOO.util.DragDrop.prototype={events:null,on:function(){this.subscribe.apply(this,arguments);},id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,dragOnly:false,useShim:false,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,deltaX:0,deltaY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,cursorIsOver:false,overlap:null,b4StartDrag:function(C,D){},startDrag:function(C,D){},b4Drag:function(C){},onDrag:function(C){},onDragEnter:function(C,D){},b4DragOver:function(C){},onDragOver:function(C,D){},b4DragOut:function(C){},onDragOut:function(C,D){},b4DragDrop:function(C){},onDragDrop:function(C,D){},onInvalidDrop:function(C){},b4EndDrag:function(C){},endDrag:function(C){},b4MouseDown:function(C){},onMouseDown:function(C){},onMouseUp:function(C){},onAvailable:function(){},getEl:function(){if(!this._domRef){this._domRef=B.get(this.id); -}return this._domRef;},getDragEl:function(){return B.get(this.dragElId);},init:function(F,C,D){this.initTarget(F,C,D);A.on(this._domRef||this.id,"mousedown",this.handleMouseDown,this,true);for(var E in this.events){this.createEvent(E+"Event");}},initTarget:function(E,C,D){this.config=D||{};this.events={};this.DDM=YAHOO.util.DDM;this.groups={};if(typeof E!=="string"){this._domRef=E;E=B.generateId(E);}this.id=E;this.addToGroup((C)?C:"default");this.handleElId=E;A.onAvailable(E,this.handleOnAvailable,this,true);this.setDragElId(E);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();},applyConfig:function(){this.events={mouseDown:true,b4MouseDown:true,mouseUp:true,b4StartDrag:true,startDrag:true,b4EndDrag:true,endDrag:true,drag:true,b4Drag:true,invalidDrop:true,b4DragOut:true,dragOut:true,dragEnter:true,b4DragOver:true,dragOver:true,b4DragDrop:true,dragDrop:true};if(this.config.events){for(var C in this.config.events){if(this.config.events[C]===false){this.events[C]=false;}}}this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);this.dragOnly=((this.config.dragOnly===true)?true:false);this.useShim=((this.config.useShim===true)?true:false);},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable();},setPadding:function(E,C,F,D){if(!C&&0!==C){this.padding=[E,E,E,E];}else{if(!F&&0!==F){this.padding=[E,C,E,C];}else{this.padding=[E,C,F,D];}}},setInitPosition:function(F,E){var G=this.getEl();if(!this.DDM.verifyEl(G)){if(G&&G.style&&(G.style.display=="none")){}else{}return;}var D=F||0;var C=E||0;var H=B.getXY(G);this.initPageX=H[0]-D;this.initPageY=H[1]-C;this.lastPageX=H[0];this.lastPageY=H[1];this.setStartPosition(H);},setStartPosition:function(D){var C=D||B.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=C[0];this.startPageY=C[1];},addToGroup:function(C){this.groups[C]=true;this.DDM.regDragDrop(this,C);},removeFromGroup:function(C){if(this.groups[C]){delete this.groups[C];}this.DDM.removeDDFromGroup(this,C);},setDragElId:function(C){this.dragElId=C;},setHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.handleElId=C;this.DDM.regHandle(this.id,C);},setOuterHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}A.on(C,"mousedown",this.handleMouseDown,this,true);this.setHandleElId(C);this.hasOuterHandles=true;},unreg:function(){A.removeListener(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return(this.DDM.isLocked()||this.locked);},handleMouseDown:function(J,I){var D=J.which||J.button;if(this.primaryButtonOnly&&D>1){return;}if(this.isLocked()){return;}var C=this.b4MouseDown(J),F=true;if(this.events.b4MouseDown){F=this.fireEvent("b4MouseDownEvent",J);}var E=this.onMouseDown(J),H=true;if(this.events.mouseDown){if(E===false){H=false;}else{H=this.fireEvent("mouseDownEvent",J);}}if((C===false)||(E===false)||(F===false)||(H===false)){return;}this.DDM.refreshCache(this.groups);var G=new YAHOO.util.Point(A.getPageX(J),A.getPageY(J));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(G,this)){}else{if(this.clickValidator(J)){this.setStartPosition();this.DDM.handleMouseDown(J,this);this.DDM.stopEvent(J);}else{}}},clickValidator:function(D){var C=YAHOO.util.Event.getTarget(D);return(this.isValidHandleChild(C)&&(this.id==this.handleElId||this.DDM.handleWasClicked(C,this.id)));},getTargetCoord:function(E,D){var C=E-this.deltaX;var F=D-this.deltaY;if(this.constrainX){if(Cthis.maxX){C=this.maxX;}}if(this.constrainY){if(Fthis.maxY){F=this.maxY;}}C=this.getTick(C,this.xTicks);F=this.getTick(F,this.yTicks);return{x:C,y:F};},addInvalidHandleType:function(C){var D=C.toUpperCase();this.invalidHandleTypes[D]=D;},addInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.invalidHandleIds[C]=C;},addInvalidHandleClass:function(C){this.invalidHandleClasses.push(C);},removeInvalidHandleType:function(C){var D=C.toUpperCase();delete this.invalidHandleTypes[D];},removeInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}delete this.invalidHandleIds[C];},removeInvalidHandleClass:function(D){for(var E=0,C=this.invalidHandleClasses.length;E=this.minX;D=D-C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}for(D=this.initPageX;D<=this.maxX;D=D+C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(F,C){this.yTicks=[];this.yTickSize=C;var E={};for(var D=this.initPageY;D>=this.minY;D=D-C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}for(D=this.initPageY;D<=this.maxY;D=D+C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(E,D,C){this.leftConstraint=parseInt(E,10);this.rightConstraint=parseInt(D,10);this.minX=this.initPageX-this.leftConstraint;this.maxX=this.initPageX+this.rightConstraint;if(C){this.setXTicks(this.initPageX,C);}this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(C,E,D){this.topConstraint=parseInt(C,10);this.bottomConstraint=parseInt(E,10);this.minY=this.initPageY-this.topConstraint;this.maxY=this.initPageY+this.bottomConstraint; -if(D){this.setYTicks(this.initPageY,D);}this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var D=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var C=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(D,C);}else{this.setInitPosition();}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(I,F){if(!F){return I;}else{if(F[0]>=I){return F[0];}else{for(var D=0,C=F.length;D=I){var H=I-F[D];var G=F[E]-I;return(G>H)?F[D]:F[E];}}return F[F.length-1];}}},toString:function(){return("DragDrop "+this.id);}};YAHOO.augment(YAHOO.util.DragDrop,YAHOO.util.EventProvider);})();YAHOO.util.DD=function(C,A,B){if(C){this.init(C,A,B);}};YAHOO.extend(YAHOO.util.DD,YAHOO.util.DragDrop,{scroll:true,autoOffset:function(C,B){var A=C-this.startPageX;var D=B-this.startPageY;this.setDelta(A,D);},setDelta:function(B,A){this.deltaX=B;this.deltaY=A;},setDragElPos:function(C,B){var A=this.getDragEl();this.alignElWithMouse(A,C,B);},alignElWithMouse:function(C,G,F){var E=this.getTargetCoord(G,F);if(!this.deltaSetXY){var H=[E.x,E.y];YAHOO.util.Dom.setXY(C,H);var D=parseInt(YAHOO.util.Dom.getStyle(C,"left"),10);var B=parseInt(YAHOO.util.Dom.getStyle(C,"top"),10);this.deltaSetXY=[D-E.x,B-E.y];}else{YAHOO.util.Dom.setStyle(C,"left",(E.x+this.deltaSetXY[0])+"px");YAHOO.util.Dom.setStyle(C,"top",(E.y+this.deltaSetXY[1])+"px");}this.cachePosition(E.x,E.y);var A=this;setTimeout(function(){A.autoScroll.call(A,E.x,E.y,C.offsetHeight,C.offsetWidth);},0);},cachePosition:function(B,A){if(B){this.lastPageX=B;this.lastPageY=A;}else{var C=YAHOO.util.Dom.getXY(this.getEl());this.lastPageX=C[0];this.lastPageY=C[1];}},autoScroll:function(J,I,E,K){if(this.scroll){var L=this.DDM.getClientHeight();var B=this.DDM.getClientWidth();var N=this.DDM.getScrollTop();var D=this.DDM.getScrollLeft();var H=E+I;var M=K+J;var G=(L+N-I-this.deltaY);var F=(B+D-J-this.deltaX);var C=40;var A=(document.all)?80:30;if(H>L&&G0&&I-NB&&F0&&J-D0){if(!aCache){this._aCache=[];}else{var nCacheLength=aCache.length;if(nCacheLength>0){var oResponse=null;this.fireEvent("cacheRequestEvent",{request:oRequest,callback:oCallback,caller:oCaller});for(var i=nCacheLength-1;i>=0;i--){var oCacheElem=aCache[i];if(this.isCacheHit(oRequest,oCacheElem.request)){oResponse=oCacheElem.response;this.fireEvent("cacheResponseEvent",{request:oRequest,response:oResponse,callback:oCallback,caller:oCaller});if(i=this.maxCacheEntries){aCache.shift();}oResponse=(this.cloneBeforeCaching)?DS._cloneObject(oResponse):oResponse;var oCacheElem={request:oRequest,response:oResponse};aCache[aCache.length]=oCacheElem;this.fireEvent("responseCacheEvent",{request:oRequest,response:oResponse});},flushCache:function(){if(this._aCache){this._aCache=[];this.fireEvent("cacheFlushEvent");}},setInterval:function(nMsec,oRequest,oCallback,oCaller){if(lang.isNumber(nMsec)&&(nMsec>=0)){var oSelf=this;var nId=setInterval(function(){oSelf.makeConnection(oRequest,oCallback,oCaller);},nMsec);this._aIntervals.push(nId);return nId;}else{}},clearInterval:function(nId){var tracker=this._aIntervals||[];for(var i=tracker.length-1;i>-1;i--){if(tracker[i]===nId){tracker.splice(i,1);clearInterval(nId);}}},clearAllIntervals:function(){var tracker=this._aIntervals||[];for(var i=tracker.length-1;i>-1;i--){clearInterval(tracker[i]);}tracker=[];},sendRequest:function(oRequest,oCallback,oCaller){var oCachedResponse=this.getCachedResponse(oRequest,oCallback,oCaller);if(oCachedResponse){DS.issueCallback(oCallback,[oRequest,oCachedResponse],false,oCaller);return null;}return this.makeConnection(oRequest,oCallback,oCaller);},makeConnection:function(oRequest,oCallback,oCaller){var tId=DS._nTransactionId++;this.fireEvent("requestEvent",{tId:tId,request:oRequest,callback:oCallback,caller:oCaller});var oRawResponse=this.liveData;this.handleResponse(oRequest,oRawResponse,oCallback,oCaller,tId);return tId;},handleResponse:function(oRequest,oRawResponse,oCallback,oCaller,tId){this.fireEvent("responseEvent",{tId:tId,request:oRequest,response:oRawResponse,callback:oCallback,caller:oCaller}); -var xhr=(this.dataType==DS.TYPE_XHR)?true:false;var oParsedResponse=null;var oFullResponse=oRawResponse;if(this.responseType===DS.TYPE_UNKNOWN){var ctype=(oRawResponse&&oRawResponse.getResponseHeader)?oRawResponse.getResponseHeader["Content-Type"]:null;if(ctype){if(ctype.indexOf("text/xml")>-1){this.responseType=DS.TYPE_XML;}else{if(ctype.indexOf("application/json")>-1){this.responseType=DS.TYPE_JSON;}else{if(ctype.indexOf("text/plain")>-1){this.responseType=DS.TYPE_TEXT;}}}}else{if(YAHOO.lang.isArray(oRawResponse)){this.responseType=DS.TYPE_JSARRAY;}else{if(oRawResponse&&oRawResponse.nodeType&&(oRawResponse.nodeType===9||oRawResponse.nodeType===1||oRawResponse.nodeType===11)){this.responseType=DS.TYPE_XML;}else{if(oRawResponse&&oRawResponse.nodeName&&(oRawResponse.nodeName.toLowerCase()=="table")){this.responseType=DS.TYPE_HTMLTABLE;}else{if(YAHOO.lang.isObject(oRawResponse)){this.responseType=DS.TYPE_JSON;}else{if(YAHOO.lang.isString(oRawResponse)){this.responseType=DS.TYPE_TEXT;}}}}}}}switch(this.responseType){case DS.TYPE_JSARRAY:if(xhr&&oRawResponse&&oRawResponse.responseText){oFullResponse=oRawResponse.responseText;}try{if(lang.isString(oFullResponse)){var parseArgs=[oFullResponse].concat(this.parseJSONArgs);if(lang.JSON){oFullResponse=lang.JSON.parse.apply(lang.JSON,parseArgs);}else{if(window.JSON&&JSON.parse){oFullResponse=JSON.parse.apply(JSON,parseArgs);}else{if(oFullResponse.parseJSON){oFullResponse=oFullResponse.parseJSON.apply(oFullResponse,parseArgs.slice(1));}else{while(oFullResponse.length>0&&(oFullResponse.charAt(0)!="{")&&(oFullResponse.charAt(0)!="[")){oFullResponse=oFullResponse.substring(1,oFullResponse.length);}if(oFullResponse.length>0){var arrayEnd=Math.max(oFullResponse.lastIndexOf("]"),oFullResponse.lastIndexOf("}"));oFullResponse=oFullResponse.substring(0,arrayEnd+1);oFullResponse=eval("("+oFullResponse+")");}}}}}}catch(e1){}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse,oCallback);oParsedResponse=this.parseArrayData(oRequest,oFullResponse);break;case DS.TYPE_JSON:if(xhr&&oRawResponse&&oRawResponse.responseText){oFullResponse=oRawResponse.responseText;}try{if(lang.isString(oFullResponse)){var parseArgs=[oFullResponse].concat(this.parseJSONArgs);if(lang.JSON){oFullResponse=lang.JSON.parse.apply(lang.JSON,parseArgs);}else{if(window.JSON&&JSON.parse){oFullResponse=JSON.parse.apply(JSON,parseArgs);}else{if(oFullResponse.parseJSON){oFullResponse=oFullResponse.parseJSON.apply(oFullResponse,parseArgs.slice(1));}else{while(oFullResponse.length>0&&(oFullResponse.charAt(0)!="{")&&(oFullResponse.charAt(0)!="[")){oFullResponse=oFullResponse.substring(1,oFullResponse.length);}if(oFullResponse.length>0){var objEnd=Math.max(oFullResponse.lastIndexOf("]"),oFullResponse.lastIndexOf("}"));oFullResponse=oFullResponse.substring(0,objEnd+1);oFullResponse=eval("("+oFullResponse+")");}}}}}}catch(e){}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse,oCallback);oParsedResponse=this.parseJSONData(oRequest,oFullResponse);break;case DS.TYPE_HTMLTABLE:if(xhr&&oRawResponse.responseText){var el=document.createElement("div");el.innerHTML=oRawResponse.responseText;oFullResponse=el.getElementsByTagName("table")[0];}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse,oCallback);oParsedResponse=this.parseHTMLTableData(oRequest,oFullResponse);break;case DS.TYPE_XML:if(xhr&&oRawResponse.responseXML){oFullResponse=oRawResponse.responseXML;}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse,oCallback);oParsedResponse=this.parseXMLData(oRequest,oFullResponse);break;case DS.TYPE_TEXT:if(xhr&&lang.isString(oRawResponse.responseText)){oFullResponse=oRawResponse.responseText;}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse,oCallback);oParsedResponse=this.parseTextData(oRequest,oFullResponse);break;default:oFullResponse=this.doBeforeParseData(oRequest,oFullResponse,oCallback);oParsedResponse=this.parseData(oRequest,oFullResponse);break;}oParsedResponse=oParsedResponse||{};if(!oParsedResponse.results){oParsedResponse.results=[];}if(!oParsedResponse.meta){oParsedResponse.meta={};}if(!oParsedResponse.error){oParsedResponse=this.doBeforeCallback(oRequest,oFullResponse,oParsedResponse,oCallback);this.fireEvent("responseParseEvent",{request:oRequest,response:oParsedResponse,callback:oCallback,caller:oCaller});this.addToCache(oRequest,oParsedResponse);}else{oParsedResponse.error=true;this.fireEvent("dataErrorEvent",{request:oRequest,response:oRawResponse,callback:oCallback,caller:oCaller,message:DS.ERROR_DATANULL});}oParsedResponse.tId=tId;DS.issueCallback(oCallback,[oRequest,oParsedResponse],oParsedResponse.error,oCaller);},doBeforeParseData:function(oRequest,oFullResponse,oCallback){return oFullResponse;},doBeforeCallback:function(oRequest,oFullResponse,oParsedResponse,oCallback){return oParsedResponse;},parseData:function(oRequest,oFullResponse){if(lang.isValue(oFullResponse)){var oParsedResponse={results:oFullResponse,meta:{}};return oParsedResponse;}return null;},parseArrayData:function(oRequest,oFullResponse){if(lang.isArray(oFullResponse)){var results=[],i,j,rec,field,data;if(lang.isArray(this.responseSchema.fields)){var fields=this.responseSchema.fields;for(i=fields.length-1;i>=0;--i){if(typeof fields[i]!=="object"){fields[i]={key:fields[i]};}}var parsers={},p;for(i=fields.length-1;i>=0;--i){p=(typeof fields[i].parser==="function"?fields[i].parser:DS.Parser[fields[i].parser+""])||fields[i].converter;if(p){parsers[fields[i].key]=p;}}var arrType=lang.isArray(oFullResponse[0]);for(i=oFullResponse.length-1;i>-1;i--){var oResult={};rec=oFullResponse[i];if(typeof rec==="object"){for(j=fields.length-1;j>-1;j--){field=fields[j];data=arrType?rec[j]:rec[field.key];if(parsers[field.key]){data=parsers[field.key].call(this,data);}if(data===undefined){data=null;}oResult[field.key]=data;}}else{if(lang.isString(rec)){for(j=fields.length-1;j>-1;j--){field=fields[j];data=rec;if(parsers[field.key]){data=parsers[field.key].call(this,data);}if(data===undefined){data=null;}oResult[field.key]=data; -}}}results[i]=oResult;}}else{results=oFullResponse;}var oParsedResponse={results:results};return oParsedResponse;}return null;},parseTextData:function(oRequest,oFullResponse){if(lang.isString(oFullResponse)){if(lang.isString(this.responseSchema.recordDelim)&&lang.isString(this.responseSchema.fieldDelim)){var oParsedResponse={results:[]};var recDelim=this.responseSchema.recordDelim;var fieldDelim=this.responseSchema.fieldDelim;if(oFullResponse.length>0){var newLength=oFullResponse.length-recDelim.length;if(oFullResponse.substr(newLength)==recDelim){oFullResponse=oFullResponse.substr(0,newLength);}if(oFullResponse.length>0){var recordsarray=oFullResponse.split(recDelim);for(var i=0,len=recordsarray.length,recIdx=0;i0)){var fielddataarray=recordsarray[i].split(fieldDelim);var oResult={};if(lang.isArray(this.responseSchema.fields)){var fields=this.responseSchema.fields;for(var j=fields.length-1;j>-1;j--){try{var data=fielddataarray[j];if(lang.isString(data)){if(data.charAt(0)=='"'){data=data.substr(1);}if(data.charAt(data.length-1)=='"'){data=data.substr(0,data.length-1);}var field=fields[j];var key=(lang.isValue(field.key))?field.key:field;if(!field.parser&&field.converter){field.parser=field.converter;}var parser=(typeof field.parser==="function")?field.parser:DS.Parser[field.parser+""];if(parser){data=parser.call(this,data);}if(data===undefined){data=null;}oResult[key]=data;}else{bError=true;}}catch(e){bError=true;}}}else{oResult=fielddataarray;}if(!bError){oParsedResponse.results[recIdx++]=oResult;}}}}}return oParsedResponse;}}return null;},parseXMLResult:function(result){var oResult={},schema=this.responseSchema;try{for(var m=schema.fields.length-1;m>=0;m--){var field=schema.fields[m];var key=(lang.isValue(field.key))?field.key:field;var data=null;if(this.useXPath){data=YAHOO.util.DataSource._getLocationValue(field,result);}else{var xmlAttr=result.attributes.getNamedItem(key);if(xmlAttr){data=xmlAttr.value;}else{var xmlNode=result.getElementsByTagName(key);if(xmlNode&&xmlNode.item(0)){var item=xmlNode.item(0);data=(item)?((item.text)?item.text:(item.textContent)?item.textContent:null):null;if(!data){var datapieces=[];for(var j=0,len=item.childNodes.length;j0){data=datapieces.join("");}}}}}if(data===null){data="";}if(!field.parser&&field.converter){field.parser=field.converter;}var parser=(typeof field.parser==="function")?field.parser:DS.Parser[field.parser+""];if(parser){data=parser.call(this,data);}if(data===undefined){data=null;}oResult[key]=data;}}catch(e){}return oResult;},parseXMLData:function(oRequest,oFullResponse){var bError=false,schema=this.responseSchema,oParsedResponse={meta:{}},xmlList=null,metaNode=schema.metaNode,metaLocators=schema.metaFields||{},i,k,loc,v;try{if(this.useXPath){for(k in metaLocators){oParsedResponse.meta[k]=YAHOO.util.DataSource._getLocationValue(metaLocators[k],oFullResponse);}}else{metaNode=metaNode?oFullResponse.getElementsByTagName(metaNode)[0]:oFullResponse;if(metaNode){for(k in metaLocators){if(lang.hasOwnProperty(metaLocators,k)){loc=metaLocators[k];v=metaNode.getElementsByTagName(loc)[0];if(v){v=v.firstChild.nodeValue;}else{v=metaNode.attributes.getNamedItem(loc);if(v){v=v.value;}}if(lang.isValue(v)){oParsedResponse.meta[k]=v;}}}}}xmlList=(schema.resultNode)?oFullResponse.getElementsByTagName(schema.resultNode):null;}catch(e){}if(!xmlList||!lang.isArray(schema.fields)){bError=true;}else{oParsedResponse.results=[];for(i=xmlList.length-1;i>=0;--i){var oResult=this.parseXMLResult(xmlList.item(i));oParsedResponse.results[i]=oResult;}}if(bError){oParsedResponse.error=true;}else{}return oParsedResponse;},parseJSONData:function(oRequest,oFullResponse){var oParsedResponse={results:[],meta:{}};if(lang.isObject(oFullResponse)&&this.responseSchema.resultsList){var schema=this.responseSchema,fields=schema.fields,resultsList=oFullResponse,results=[],metaFields=schema.metaFields||{},fieldParsers=[],fieldPaths=[],simpleFields=[],bError=false,i,len,j,v,key,parser,path;var buildPath=function(needle){var path=null,keys=[],i=0;if(needle){needle=needle.replace(/\[(['"])(.*?)\1\]/g,function(x,$1,$2){keys[i]=$2;return".@"+(i++);}).replace(/\[(\d+)\]/g,function(x,$1){keys[i]=parseInt($1,10)|0;return".@"+(i++);}).replace(/^\./,"");if(!/[^\w\.\$@]/.test(needle)){path=needle.split(".");for(i=path.length-1;i>=0;--i){if(path[i].charAt(0)==="@"){path[i]=keys[parseInt(path[i].substr(1),10)];}}}else{}}return path;};var walkPath=function(path,origin){var v=origin,i=0,len=path.length;for(;i1){fieldPaths[fieldPaths.length]={key:key,path:path};}else{simpleFields[simpleFields.length]={key:key,path:path[0]};}}else{}}for(i=resultsList.length-1;i>=0;--i){var r=resultsList[i],rec={};if(r){for(j=simpleFields.length-1;j>=0;--j){rec[simpleFields[j].key]=(r[simpleFields[j].path]!==undefined)?r[simpleFields[j].path]:r[j];}for(j=fieldPaths.length-1;j>=0;--j){rec[fieldPaths[j].key]=walkPath(fieldPaths[j].path,r);}for(j=fieldParsers.length-1;j>=0;--j){var p=fieldParsers[j].key;rec[p]=fieldParsers[j].parser.call(this,rec[p]);if(rec[p]===undefined){rec[p]=null;}}}results[i]=rec;}}else{results=resultsList;}for(key in metaFields){if(lang.hasOwnProperty(metaFields,key)){path=buildPath(metaFields[key]); -if(path){v=walkPath(path,oFullResponse);oParsedResponse.meta[key]=v;}}}}else{oParsedResponse.error=true;}oParsedResponse.results=results;}else{oParsedResponse.error=true;}return oParsedResponse;},parseHTMLTableData:function(oRequest,oFullResponse){var bError=false;var elTable=oFullResponse;var fields=this.responseSchema.fields;var oParsedResponse={results:[]};if(lang.isArray(fields)){for(var i=0;i-1;j--){var elRow=elTbody.rows[j];var oResult={};for(var k=fields.length-1;k>-1;k--){var field=fields[k];var key=(lang.isValue(field.key))?field.key:field;var data=elRow.cells[k].innerHTML;if(!field.parser&&field.converter){field.parser=field.converter;}var parser=(typeof field.parser==="function")?field.parser:DS.Parser[field.parser+""];if(parser){data=parser.call(this,data);}if(data===undefined){data=null;}oResult[key]=data;}oParsedResponse.results[j]=oResult;}}}else{bError=true;}if(bError){oParsedResponse.error=true;}else{}return oParsedResponse;}};lang.augmentProto(DS,util.EventProvider);util.LocalDataSource=function(oLiveData,oConfigs){this.dataType=DS.TYPE_LOCAL;if(oLiveData){if(YAHOO.lang.isArray(oLiveData)){this.responseType=DS.TYPE_JSARRAY;}else{if(oLiveData.nodeType&&oLiveData.nodeType==9){this.responseType=DS.TYPE_XML;}else{if(oLiveData.nodeName&&(oLiveData.nodeName.toLowerCase()=="table")){this.responseType=DS.TYPE_HTMLTABLE;oLiveData=oLiveData.cloneNode(true);}else{if(YAHOO.lang.isString(oLiveData)){this.responseType=DS.TYPE_TEXT;}else{if(YAHOO.lang.isObject(oLiveData)){this.responseType=DS.TYPE_JSON;}}}}}}else{oLiveData=[];this.responseType=DS.TYPE_JSARRAY;}util.LocalDataSource.superclass.constructor.call(this,oLiveData,oConfigs);};lang.extend(util.LocalDataSource,DS);lang.augmentObject(util.LocalDataSource,DS);util.FunctionDataSource=function(oLiveData,oConfigs){this.dataType=DS.TYPE_JSFUNCTION;oLiveData=oLiveData||function(){};util.FunctionDataSource.superclass.constructor.call(this,oLiveData,oConfigs);};lang.extend(util.FunctionDataSource,DS,{scope:null,makeConnection:function(oRequest,oCallback,oCaller){var tId=DS._nTransactionId++;this.fireEvent("requestEvent",{tId:tId,request:oRequest,callback:oCallback,caller:oCaller});var oRawResponse=(this.scope)?this.liveData.call(this.scope,oRequest,this,oCallback):this.liveData(oRequest,oCallback);if(this.responseType===DS.TYPE_UNKNOWN){if(YAHOO.lang.isArray(oRawResponse)){this.responseType=DS.TYPE_JSARRAY;}else{if(oRawResponse&&oRawResponse.nodeType&&oRawResponse.nodeType==9){this.responseType=DS.TYPE_XML;}else{if(oRawResponse&&oRawResponse.nodeName&&(oRawResponse.nodeName.toLowerCase()=="table")){this.responseType=DS.TYPE_HTMLTABLE;}else{if(YAHOO.lang.isObject(oRawResponse)){this.responseType=DS.TYPE_JSON;}else{if(YAHOO.lang.isString(oRawResponse)){this.responseType=DS.TYPE_TEXT;}}}}}}this.handleResponse(oRequest,oRawResponse,oCallback,oCaller,tId);return tId;}});lang.augmentObject(util.FunctionDataSource,DS);util.ScriptNodeDataSource=function(oLiveData,oConfigs){this.dataType=DS.TYPE_SCRIPTNODE;oLiveData=oLiveData||"";util.ScriptNodeDataSource.superclass.constructor.call(this,oLiveData,oConfigs);};lang.extend(util.ScriptNodeDataSource,DS,{getUtility:util.Get,asyncMode:"allowAll",scriptCallbackParam:"callback",generateRequestCallback:function(id){return"&"+this.scriptCallbackParam+"=YAHOO.util.ScriptNodeDataSource.callbacks["+id+"]";},doBeforeGetScriptNode:function(sUri){return sUri;},makeConnection:function(oRequest,oCallback,oCaller){var tId=DS._nTransactionId++;this.fireEvent("requestEvent",{tId:tId,request:oRequest,callback:oCallback,caller:oCaller});if(util.ScriptNodeDataSource._nPending===0){util.ScriptNodeDataSource.callbacks=[];util.ScriptNodeDataSource._nId=0;}var id=util.ScriptNodeDataSource._nId;util.ScriptNodeDataSource._nId++;var oSelf=this;util.ScriptNodeDataSource.callbacks[id]=function(oRawResponse){if((oSelf.asyncMode!=="ignoreStaleResponses")||(id===util.ScriptNodeDataSource.callbacks.length-1)){if(oSelf.responseType===DS.TYPE_UNKNOWN){if(YAHOO.lang.isArray(oRawResponse)){oSelf.responseType=DS.TYPE_JSARRAY;}else{if(oRawResponse.nodeType&&oRawResponse.nodeType==9){oSelf.responseType=DS.TYPE_XML;}else{if(oRawResponse.nodeName&&(oRawResponse.nodeName.toLowerCase()=="table")){oSelf.responseType=DS.TYPE_HTMLTABLE;}else{if(YAHOO.lang.isObject(oRawResponse)){oSelf.responseType=DS.TYPE_JSON;}else{if(YAHOO.lang.isString(oRawResponse)){oSelf.responseType=DS.TYPE_TEXT;}}}}}}oSelf.handleResponse(oRequest,oRawResponse,oCallback,oCaller,tId);}else{}delete util.ScriptNodeDataSource.callbacks[id];};util.ScriptNodeDataSource._nPending++;var sUri=this.liveData+oRequest+this.generateRequestCallback(id);sUri=this.doBeforeGetScriptNode(sUri);this.getUtility.script(sUri,{autopurge:true,onsuccess:util.ScriptNodeDataSource._bumpPendingDown,onfail:util.ScriptNodeDataSource._bumpPendingDown});return tId;}});lang.augmentObject(util.ScriptNodeDataSource,DS);lang.augmentObject(util.ScriptNodeDataSource,{_nId:0,_nPending:0,callbacks:[]});util.XHRDataSource=function(oLiveData,oConfigs){this.dataType=DS.TYPE_XHR;this.connMgr=this.connMgr||util.Connect;oLiveData=oLiveData||"";util.XHRDataSource.superclass.constructor.call(this,oLiveData,oConfigs);};lang.extend(util.XHRDataSource,DS,{connMgr:null,connXhrMode:"allowAll",connMethodPost:false,connTimeout:0,makeConnection:function(oRequest,oCallback,oCaller){var oRawResponse=null;var tId=DS._nTransactionId++;this.fireEvent("requestEvent",{tId:tId,request:oRequest,callback:oCallback,caller:oCaller});var oSelf=this;var oConnMgr=this.connMgr;var oQueue=this._oQueue;var _xhrSuccess=function(oResponse){if(oResponse&&(this.connXhrMode=="ignoreStaleResponses")&&(oResponse.tId!=oQueue.conn.tId)){return null;}else{if(!oResponse){this.fireEvent("dataErrorEvent",{request:oRequest,response:null,callback:oCallback,caller:oCaller,message:DS.ERROR_DATANULL});DS.issueCallback(oCallback,[oRequest,{error:true}],true,oCaller);return null; -}else{if(this.responseType===DS.TYPE_UNKNOWN){var ctype=(oResponse.getResponseHeader)?oResponse.getResponseHeader["Content-Type"]:null;if(ctype){if(ctype.indexOf("text/xml")>-1){this.responseType=DS.TYPE_XML;}else{if(ctype.indexOf("application/json")>-1){this.responseType=DS.TYPE_JSON;}else{if(ctype.indexOf("text/plain")>-1){this.responseType=DS.TYPE_TEXT;}}}}}this.handleResponse(oRequest,oResponse,oCallback,oCaller,tId);}}};var _xhrFailure=function(oResponse){this.fireEvent("dataErrorEvent",{request:oRequest,response:oResponse,callback:oCallback,caller:oCaller,message:DS.ERROR_DATAINVALID});if(lang.isString(this.liveData)&&lang.isString(oRequest)&&(this.liveData.lastIndexOf("?")!==this.liveData.length-1)&&(oRequest.indexOf("?")!==0)){}oResponse=oResponse||{};oResponse.error=true;DS.issueCallback(oCallback,[oRequest,oResponse],true,oCaller);return null;};var _xhrCallback={success:_xhrSuccess,failure:_xhrFailure,scope:this};if(lang.isNumber(this.connTimeout)){_xhrCallback.timeout=this.connTimeout;}if(this.connXhrMode=="cancelStaleRequests"){if(oQueue.conn){if(oConnMgr.abort){oConnMgr.abort(oQueue.conn);oQueue.conn=null;}else{}}}if(oConnMgr&&oConnMgr.asyncRequest){var sLiveData=this.liveData;var isPost=this.connMethodPost;var sMethod=(isPost)?"POST":"GET";var sUri=(isPost||!lang.isValue(oRequest))?sLiveData:sLiveData+oRequest;var sRequest=(isPost)?oRequest:null;if(this.connXhrMode!="queueRequests"){oQueue.conn=oConnMgr.asyncRequest(sMethod,sUri,_xhrCallback,sRequest);}else{if(oQueue.conn){var allRequests=oQueue.requests;allRequests.push({request:oRequest,callback:_xhrCallback});if(!oQueue.interval){oQueue.interval=setInterval(function(){if(oConnMgr.isCallInProgress(oQueue.conn)){return;}else{if(allRequests.length>0){sUri=(isPost||!lang.isValue(allRequests[0].request))?sLiveData:sLiveData+allRequests[0].request;sRequest=(isPost)?allRequests[0].request:null;oQueue.conn=oConnMgr.asyncRequest(sMethod,sUri,allRequests[0].callback,sRequest);allRequests.shift();}else{clearInterval(oQueue.interval);oQueue.interval=null;}}},50);}}else{oQueue.conn=oConnMgr.asyncRequest(sMethod,sUri,_xhrCallback,sRequest);}}}else{DS.issueCallback(oCallback,[oRequest,{error:true}],true,oCaller);}return tId;}});lang.augmentObject(util.XHRDataSource,DS);util.DataSource=function(oLiveData,oConfigs){oConfigs=oConfigs||{};var dataType=oConfigs.dataType;if(dataType){if(dataType==DS.TYPE_LOCAL){return new util.LocalDataSource(oLiveData,oConfigs);}else{if(dataType==DS.TYPE_XHR){return new util.XHRDataSource(oLiveData,oConfigs);}else{if(dataType==DS.TYPE_SCRIPTNODE){return new util.ScriptNodeDataSource(oLiveData,oConfigs);}else{if(dataType==DS.TYPE_JSFUNCTION){return new util.FunctionDataSource(oLiveData,oConfigs);}}}}}if(YAHOO.lang.isString(oLiveData)){return new util.XHRDataSource(oLiveData,oConfigs);}else{if(YAHOO.lang.isFunction(oLiveData)){return new util.FunctionDataSource(oLiveData,oConfigs);}else{return new util.LocalDataSource(oLiveData,oConfigs);}}};lang.augmentObject(util.DataSource,DS);})();YAHOO.util.Number={format:function(e,k){if(e===""||e===null||!isFinite(e)){return"";}e=+e;k=YAHOO.lang.merge(YAHOO.util.Number.format.defaults,(k||{}));var j=e+"",l=Math.abs(e),b=k.decimalPlaces||0,r=k.thousandsSeparator,f=k.negativeFormat||("-"+k.format),q,p,g,h;if(f.indexOf("#")>-1){f=f.replace(/#/,k.format);}if(b<0){q=l-(l%1)+"";g=q.length+b;if(g>0){q=Number("."+q).toFixed(g).slice(2)+new Array(q.length-g+1).join("0");}else{q="0";}}else{var a=l+"";if(b>0||a.indexOf(".")>0){var d=Math.pow(10,b);q=Math.round(l*d)/d+"";var c=q.indexOf("."),m,o;if(c<0){m=b;o=(Math.pow(10,m)+"").substring(1);if(b>0){q=q+"."+o;}}else{m=b-(q.length-c-1);o=(Math.pow(10,m)+"").substring(1);q=q+o;}}else{q=l.toFixed(b)+"";}}p=q.split(/\D/);if(l>=1000){g=p[0].length%3||3;p[0]=p[0].slice(0,g)+p[0].slice(g).replace(/(\d{3})/g,r+"$1");}return YAHOO.util.Number.format._applyFormat((e<0?f:k.format),p.join(k.decimalSeparator),k);}};YAHOO.util.Number.format.defaults={format:"{prefix}{number}{suffix}",negativeFormat:null,decimalSeparator:".",decimalPlaces:null,thousandsSeparator:""};YAHOO.util.Number.format._applyFormat=function(a,b,c){return a.replace(/\{(\w+)\}/g,function(d,e){return e==="number"?b:e in c?c[e]:"";});};(function(){var a=function(c,e,d){if(typeof d==="undefined"){d=10;}for(;parseInt(c,10)1;d/=10){c=e.toString()+c;}return c.toString();};var b={formats:{a:function(e,c){return c.a[e.getDay()];},A:function(e,c){return c.A[e.getDay()];},b:function(e,c){return c.b[e.getMonth()];},B:function(e,c){return c.B[e.getMonth()];},C:function(c){return a(parseInt(c.getFullYear()/100,10),0);},d:["getDate","0"],e:["getDate"," "],g:function(c){return a(parseInt(b.formats.G(c)%100,10),0);},G:function(f){var g=f.getFullYear();var e=parseInt(b.formats.V(f),10);var c=parseInt(b.formats.W(f),10);if(c>e){g++;}else{if(c===0&&e>=52){g--;}}return g;},H:["getHours","0"],I:function(e){var c=e.getHours()%12;return a(c===0?12:c,0);},j:function(h){var g=new Date(""+h.getFullYear()+"/1/1 GMT");var e=new Date(""+h.getFullYear()+"/"+(h.getMonth()+1)+"/"+h.getDate()+" GMT");var c=e-g;var f=parseInt(c/60000/60/24,10)+1;return a(f,0,100);},k:["getHours"," "],l:function(e){var c=e.getHours()%12;return a(c===0?12:c," ");},m:function(c){return a(c.getMonth()+1,0);},M:["getMinutes","0"],p:function(e,c){return c.p[e.getHours()>=12?1:0];},P:function(e,c){return c.P[e.getHours()>=12?1:0];},s:function(e,c){return parseInt(e.getTime()/1000,10);},S:["getSeconds","0"],u:function(c){var e=c.getDay();return e===0?7:e;},U:function(g){var c=parseInt(b.formats.j(g),10);var f=6-g.getDay();var e=parseInt((c+f)/7,10);return a(e,0);},V:function(g){var f=parseInt(b.formats.W(g),10);var c=(new Date(""+g.getFullYear()+"/1/1")).getDay();var e=f+(c>4||c<=1?0:1);if(e===53&&(new Date(""+g.getFullYear()+"/12/31")).getDay()<4){e=1;}else{if(e===0){e=b.formats.V(new Date(""+(g.getFullYear()-1)+"/12/31"));}}return a(e,0);},w:"getDay",W:function(g){var c=parseInt(b.formats.j(g),10);var f=7-b.formats.u(g);var e=parseInt((c+f)/7,10); -return a(e,0,10);},y:function(c){return a(c.getFullYear()%100,0);},Y:"getFullYear",z:function(f){var e=f.getTimezoneOffset();var c=a(parseInt(Math.abs(e/60),10),0);var g=a(Math.abs(e%60),0);return(e>0?"-":"+")+c+g;},Z:function(c){var e=c.toString().replace(/^.*:\d\d( GMT[+-]\d+)? \(?([A-Za-z ]+)\)?\d*$/,"$2").replace(/[a-z ]/g,"");if(e.length>4){e=b.formats.z(c);}return e;},"%":function(c){return"%";}},aggregates:{c:"locale",D:"%m/%d/%y",F:"%Y-%m-%d",h:"%b",n:"\n",r:"locale",R:"%H:%M",t:"\t",T:"%H:%M:%S",x:"locale",X:"locale"},format:function(g,f,d){f=f||{};if(!(g instanceof Date)){return YAHOO.lang.isValue(g)?g:"";}var h=f.format||"%m/%d/%Y";if(h==="YYYY/MM/DD"){h="%Y/%m/%d";}else{if(h==="DD/MM/YYYY"){h="%d/%m/%Y";}else{if(h==="MM/DD/YYYY"){h="%m/%d/%Y";}}}d=d||"en";if(!(d in YAHOO.util.DateLocale)){if(d.replace(/-[a-zA-Z]+$/,"") in YAHOO.util.DateLocale){d=d.replace(/-[a-zA-Z]+$/,"");}else{d="en";}}var j=YAHOO.util.DateLocale[d];var c=function(l,k){var m=b.aggregates[k];return(m==="locale"?j[k]:m);};var e=function(l,k){var m=b.formats[k];if(typeof m==="string"){return g[m]();}else{if(typeof m==="function"){return m.call(g,g,j);}else{if(typeof m==="object"&&typeof m[0]==="string"){return a(g[m[0]](),m[1]);}else{return k;}}}};while(h.match(/%[cDFhnrRtTxX]/)){h=h.replace(/%([cDFhnrRtTxX])/g,c);}var i=h.replace(/%([aAbBCdegGHIjklmMpPsSuUVwWyYzZ%])/g,e);c=e=undefined;return i;}};YAHOO.namespace("YAHOO.util");YAHOO.util.Date=b;YAHOO.util.DateLocale={a:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],A:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],b:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],B:["January","February","March","April","May","June","July","August","September","October","November","December"],c:"%a %d %b %Y %T %Z",p:["AM","PM"],P:["am","pm"],r:"%I:%M:%S %p",x:"%d/%m/%y",X:"%T"};YAHOO.util.DateLocale["en"]=YAHOO.lang.merge(YAHOO.util.DateLocale,{});YAHOO.util.DateLocale["en-US"]=YAHOO.lang.merge(YAHOO.util.DateLocale["en"],{c:"%a %d %b %Y %I:%M:%S %p %Z",x:"%m/%d/%Y",X:"%I:%M:%S %p"});YAHOO.util.DateLocale["en-GB"]=YAHOO.lang.merge(YAHOO.util.DateLocale["en"],{r:"%l:%M:%S %P %Z"});YAHOO.util.DateLocale["en-AU"]=YAHOO.lang.merge(YAHOO.util.DateLocale["en"]);})();YAHOO.register("datasource",YAHOO.util.DataSource,{version:"2.9.0",build:"2800"});/* -Copyright (c) 2011, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.com/yui/license.html -version: 2.9.0 -*/ -YAHOO.widget.DS_JSArray=YAHOO.util.LocalDataSource;YAHOO.widget.DS_JSFunction=YAHOO.util.FunctionDataSource;YAHOO.widget.DS_XHR=function(b,a,d){var c=new YAHOO.util.XHRDataSource(b,d);c._aDeprecatedSchema=a;return c;};YAHOO.widget.DS_ScriptNode=function(b,a,d){var c=new YAHOO.util.ScriptNodeDataSource(b,d);c._aDeprecatedSchema=a;return c;};YAHOO.widget.DS_XHR.TYPE_JSON=YAHOO.util.DataSourceBase.TYPE_JSON;YAHOO.widget.DS_XHR.TYPE_XML=YAHOO.util.DataSourceBase.TYPE_XML;YAHOO.widget.DS_XHR.TYPE_FLAT=YAHOO.util.DataSourceBase.TYPE_TEXT;YAHOO.widget.AutoComplete=function(g,b,j,c){if(g&&b&&j){if(j&&YAHOO.lang.isFunction(j.sendRequest)){this.dataSource=j;}else{return;}this.key=0;var d=j.responseSchema;if(j._aDeprecatedSchema){var k=j._aDeprecatedSchema;if(YAHOO.lang.isArray(k)){if((j.responseType===YAHOO.util.DataSourceBase.TYPE_JSON)||(j.responseType===YAHOO.util.DataSourceBase.TYPE_UNKNOWN)){d.resultsList=k[0];this.key=k[1];d.fields=(k.length<3)?null:k.slice(1);}else{if(j.responseType===YAHOO.util.DataSourceBase.TYPE_XML){d.resultNode=k[0];this.key=k[1];d.fields=k.slice(1);}else{if(j.responseType===YAHOO.util.DataSourceBase.TYPE_TEXT){d.recordDelim=k[0];d.fieldDelim=k[1];}}}j.responseSchema=d;}}if(YAHOO.util.Dom.inDocument(g)){if(YAHOO.lang.isString(g)){this._sName="instance"+YAHOO.widget.AutoComplete._nIndex+" "+g;this._elTextbox=document.getElementById(g);}else{this._sName=(g.id)?"instance"+YAHOO.widget.AutoComplete._nIndex+" "+g.id:"instance"+YAHOO.widget.AutoComplete._nIndex;this._elTextbox=g;}YAHOO.util.Dom.addClass(this._elTextbox,"yui-ac-input");}else{return;}if(YAHOO.util.Dom.inDocument(b)){if(YAHOO.lang.isString(b)){this._elContainer=document.getElementById(b);}else{this._elContainer=b;}if(this._elContainer.style.display=="none"){}var e=this._elContainer.parentNode;var a=e.tagName.toLowerCase();if(a=="div"){YAHOO.util.Dom.addClass(e,"yui-ac");}else{}}else{return;}if(this.dataSource.dataType===YAHOO.util.DataSourceBase.TYPE_LOCAL){this.applyLocalFilter=true;}if(c&&(c.constructor==Object)){for(var i in c){if(i){this[i]=c[i];}}}this._initContainerEl();this._initProps();this._initListEl();this._initContainerHelperEls();var h=this;var f=this._elTextbox;YAHOO.util.Event.addListener(f,"keyup",h._onTextboxKeyUp,h);YAHOO.util.Event.addListener(f,"keydown",h._onTextboxKeyDown,h);YAHOO.util.Event.addListener(f,"focus",h._onTextboxFocus,h);YAHOO.util.Event.addListener(f,"blur",h._onTextboxBlur,h);YAHOO.util.Event.addListener(b,"mouseover",h._onContainerMouseover,h);YAHOO.util.Event.addListener(b,"mouseout",h._onContainerMouseout,h);YAHOO.util.Event.addListener(b,"click",h._onContainerClick,h);YAHOO.util.Event.addListener(b,"scroll",h._onContainerScroll,h);YAHOO.util.Event.addListener(b,"resize",h._onContainerResize,h);YAHOO.util.Event.addListener(f,"keypress",h._onTextboxKeyPress,h);YAHOO.util.Event.addListener(window,"unload",h._onWindowUnload,h);this.textboxFocusEvent=new YAHOO.util.CustomEvent("textboxFocus",this);this.textboxKeyEvent=new YAHOO.util.CustomEvent("textboxKey",this);this.dataRequestEvent=new YAHOO.util.CustomEvent("dataRequest",this);this.dataRequestCancelEvent=new YAHOO.util.CustomEvent("dataRequestCancel",this);this.dataReturnEvent=new YAHOO.util.CustomEvent("dataReturn",this);this.dataErrorEvent=new YAHOO.util.CustomEvent("dataError",this);this.containerPopulateEvent=new YAHOO.util.CustomEvent("containerPopulate",this);this.containerExpandEvent=new YAHOO.util.CustomEvent("containerExpand",this);this.typeAheadEvent=new YAHOO.util.CustomEvent("typeAhead",this);this.itemMouseOverEvent=new YAHOO.util.CustomEvent("itemMouseOver",this);this.itemMouseOutEvent=new YAHOO.util.CustomEvent("itemMouseOut",this);this.itemArrowToEvent=new YAHOO.util.CustomEvent("itemArrowTo",this);this.itemArrowFromEvent=new YAHOO.util.CustomEvent("itemArrowFrom",this);this.itemSelectEvent=new YAHOO.util.CustomEvent("itemSelect",this);this.unmatchedItemSelectEvent=new YAHOO.util.CustomEvent("unmatchedItemSelect",this);this.selectionEnforceEvent=new YAHOO.util.CustomEvent("selectionEnforce",this);this.containerCollapseEvent=new YAHOO.util.CustomEvent("containerCollapse",this);this.textboxBlurEvent=new YAHOO.util.CustomEvent("textboxBlur",this);this.textboxChangeEvent=new YAHOO.util.CustomEvent("textboxChange",this);f.setAttribute("autocomplete","off");YAHOO.widget.AutoComplete._nIndex++;}else{}};YAHOO.widget.AutoComplete.prototype.dataSource=null;YAHOO.widget.AutoComplete.prototype.applyLocalFilter=null;YAHOO.widget.AutoComplete.prototype.queryMatchCase=false;YAHOO.widget.AutoComplete.prototype.queryMatchContains=false;YAHOO.widget.AutoComplete.prototype.queryMatchSubset=false;YAHOO.widget.AutoComplete.prototype.minQueryLength=1;YAHOO.widget.AutoComplete.prototype.maxResultsDisplayed=10;YAHOO.widget.AutoComplete.prototype.queryDelay=0.2;YAHOO.widget.AutoComplete.prototype.typeAheadDelay=0.5;YAHOO.widget.AutoComplete.prototype.queryInterval=500;YAHOO.widget.AutoComplete.prototype.highlightClassName="yui-ac-highlight";YAHOO.widget.AutoComplete.prototype.prehighlightClassName=null;YAHOO.widget.AutoComplete.prototype.delimChar=null;YAHOO.widget.AutoComplete.prototype.autoHighlight=true;YAHOO.widget.AutoComplete.prototype.typeAhead=false;YAHOO.widget.AutoComplete.prototype.animHoriz=false;YAHOO.widget.AutoComplete.prototype.animVert=true;YAHOO.widget.AutoComplete.prototype.animSpeed=0.3;YAHOO.widget.AutoComplete.prototype.forceSelection=false;YAHOO.widget.AutoComplete.prototype.allowBrowserAutocomplete=true;YAHOO.widget.AutoComplete.prototype.alwaysShowContainer=false;YAHOO.widget.AutoComplete.prototype.useIFrame=false;YAHOO.widget.AutoComplete.prototype.useShadow=false;YAHOO.widget.AutoComplete.prototype.suppressInputUpdate=false;YAHOO.widget.AutoComplete.prototype.resultTypeList=true;YAHOO.widget.AutoComplete.prototype.queryQuestionMark=true;YAHOO.widget.AutoComplete.prototype.autoSnapContainer=true;YAHOO.widget.AutoComplete.prototype.toString=function(){return"AutoComplete "+this._sName;};YAHOO.widget.AutoComplete.prototype.getInputEl=function(){return this._elTextbox; -};YAHOO.widget.AutoComplete.prototype.getContainerEl=function(){return this._elContainer;};YAHOO.widget.AutoComplete.prototype.isFocused=function(){return this._bFocused;};YAHOO.widget.AutoComplete.prototype.isContainerOpen=function(){return this._bContainerOpen;};YAHOO.widget.AutoComplete.prototype.getListEl=function(){return this._elList;};YAHOO.widget.AutoComplete.prototype.getListItemMatch=function(a){if(a._sResultMatch){return a._sResultMatch;}else{return null;}};YAHOO.widget.AutoComplete.prototype.getListItemData=function(a){if(a._oResultData){return a._oResultData;}else{return null;}};YAHOO.widget.AutoComplete.prototype.getListItemIndex=function(a){if(YAHOO.lang.isNumber(a._nItemIndex)){return a._nItemIndex;}else{return null;}};YAHOO.widget.AutoComplete.prototype.setHeader=function(b){if(this._elHeader){var a=this._elHeader;if(b){a.innerHTML=b;a.style.display="";}else{a.innerHTML="";a.style.display="none";}}};YAHOO.widget.AutoComplete.prototype.setFooter=function(b){if(this._elFooter){var a=this._elFooter;if(b){a.innerHTML=b;a.style.display="";}else{a.innerHTML="";a.style.display="none";}}};YAHOO.widget.AutoComplete.prototype.setBody=function(a){if(this._elBody){var b=this._elBody;YAHOO.util.Event.purgeElement(b,true);if(a){b.innerHTML=a;b.style.display="";}else{b.innerHTML="";b.style.display="none";}this._elList=null;}};YAHOO.widget.AutoComplete.prototype.generateRequest=function(b){var a=this.dataSource.dataType;if(a===YAHOO.util.DataSourceBase.TYPE_XHR){if(!this.dataSource.connMethodPost){b=(this.queryQuestionMark?"?":"")+(this.dataSource.scriptQueryParam||"query")+"="+b+(this.dataSource.scriptQueryAppend?("&"+this.dataSource.scriptQueryAppend):"");}else{b=(this.dataSource.scriptQueryParam||"query")+"="+b+(this.dataSource.scriptQueryAppend?("&"+this.dataSource.scriptQueryAppend):"");}}else{if(a===YAHOO.util.DataSourceBase.TYPE_SCRIPTNODE){b="&"+(this.dataSource.scriptQueryParam||"query")+"="+b+(this.dataSource.scriptQueryAppend?("&"+this.dataSource.scriptQueryAppend):"");}}return b;};YAHOO.widget.AutoComplete.prototype.sendQuery=function(b){this._bFocused=true;var a=(this.delimChar)?this._elTextbox.value+b:b;this._sendQuery(a);};YAHOO.widget.AutoComplete.prototype.snapContainer=function(){var a=this._elTextbox,b=YAHOO.util.Dom.getXY(a);b[1]+=YAHOO.util.Dom.get(a).offsetHeight+2;YAHOO.util.Dom.setXY(this._elContainer,b);};YAHOO.widget.AutoComplete.prototype.expandContainer=function(){this._toggleContainer(true);};YAHOO.widget.AutoComplete.prototype.collapseContainer=function(){this._toggleContainer(false);};YAHOO.widget.AutoComplete.prototype.clearList=function(){var b=this._elList.childNodes,a=b.length-1;for(;a>-1;a--){b[a].style.display="none";}};YAHOO.widget.AutoComplete.prototype.getSubsetMatches=function(e){var d,c,a;for(var b=e.length;b>=this.minQueryLength;b--){a=this.generateRequest(e.substr(0,b));this.dataRequestEvent.fire(this,d,a);c=this.dataSource.getCachedResponse(a);if(c){return this.filterResults.apply(this.dataSource,[e,c,c,{scope:this}]);}}return null;};YAHOO.widget.AutoComplete.prototype.preparseRawResponse=function(c,b,a){var d=((this.responseStripAfter!=="")&&(b.indexOf))?b.indexOf(this.responseStripAfter):-1;if(d!=-1){b=b.substring(0,d);}return b;};YAHOO.widget.AutoComplete.prototype.filterResults=function(l,n,r,m){if(m&&m.argument&&YAHOO.lang.isValue(m.argument.query)){l=m.argument.query;}if(l&&l!==""){r=YAHOO.widget.AutoComplete._cloneObject(r);var j=m.scope,q=this,c=r.results,o=[],b=j.maxResultsDisplayed,k=(q.queryMatchCase||j.queryMatchCase),a=(q.queryMatchContains||j.queryMatchContains);for(var d=0,h=c.length;d-1))){o.push(f);}}if(h>b&&o.length===b){break;}}r.results=o;}else{}return r;};YAHOO.widget.AutoComplete.prototype.handleResponse=function(c,a,b){if((this instanceof YAHOO.widget.AutoComplete)&&this._sName){this._populateList(c,a,b);}};YAHOO.widget.AutoComplete.prototype.doBeforeLoadData=function(c,a,b){return true;};YAHOO.widget.AutoComplete.prototype.formatResult=function(b,d,a){var c=(a)?a:"";return c;};YAHOO.widget.AutoComplete.prototype.formatEscapedResult=function(c,d,b){var a=(b)?b:"";return YAHOO.lang.escapeHTML(a);};YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer=function(d,a,c,b){return true;};YAHOO.widget.AutoComplete.prototype.destroy=function(){var b=this.toString();var a=this._elTextbox;var d=this._elContainer;this.textboxFocusEvent.unsubscribeAll();this.textboxKeyEvent.unsubscribeAll();this.dataRequestEvent.unsubscribeAll();this.dataReturnEvent.unsubscribeAll();this.dataErrorEvent.unsubscribeAll();this.containerPopulateEvent.unsubscribeAll();this.containerExpandEvent.unsubscribeAll();this.typeAheadEvent.unsubscribeAll();this.itemMouseOverEvent.unsubscribeAll();this.itemMouseOutEvent.unsubscribeAll();this.itemArrowToEvent.unsubscribeAll();this.itemArrowFromEvent.unsubscribeAll();this.itemSelectEvent.unsubscribeAll();this.unmatchedItemSelectEvent.unsubscribeAll();this.selectionEnforceEvent.unsubscribeAll();this.containerCollapseEvent.unsubscribeAll();this.textboxBlurEvent.unsubscribeAll();this.textboxChangeEvent.unsubscribeAll();YAHOO.util.Event.purgeElement(a,true);YAHOO.util.Event.purgeElement(d,true);d.innerHTML="";for(var c in this){if(YAHOO.lang.hasOwnProperty(this,c)){this[c]=null;}}};YAHOO.widget.AutoComplete.prototype.textboxFocusEvent=null;YAHOO.widget.AutoComplete.prototype.textboxKeyEvent=null;YAHOO.widget.AutoComplete.prototype.dataRequestEvent=null;YAHOO.widget.AutoComplete.prototype.dataRequestCancelEvent=null;YAHOO.widget.AutoComplete.prototype.dataReturnEvent=null;YAHOO.widget.AutoComplete.prototype.dataErrorEvent=null; -YAHOO.widget.AutoComplete.prototype.containerPopulateEvent=null;YAHOO.widget.AutoComplete.prototype.containerExpandEvent=null;YAHOO.widget.AutoComplete.prototype.typeAheadEvent=null;YAHOO.widget.AutoComplete.prototype.itemMouseOverEvent=null;YAHOO.widget.AutoComplete.prototype.itemMouseOutEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowToEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowFromEvent=null;YAHOO.widget.AutoComplete.prototype.itemSelectEvent=null;YAHOO.widget.AutoComplete.prototype.unmatchedItemSelectEvent=null;YAHOO.widget.AutoComplete.prototype.selectionEnforceEvent=null;YAHOO.widget.AutoComplete.prototype.containerCollapseEvent=null;YAHOO.widget.AutoComplete.prototype.textboxBlurEvent=null;YAHOO.widget.AutoComplete.prototype.textboxChangeEvent=null;YAHOO.widget.AutoComplete._nIndex=0;YAHOO.widget.AutoComplete.prototype._sName=null;YAHOO.widget.AutoComplete.prototype._elTextbox=null;YAHOO.widget.AutoComplete.prototype._elContainer=null;YAHOO.widget.AutoComplete.prototype._elContent=null;YAHOO.widget.AutoComplete.prototype._elHeader=null;YAHOO.widget.AutoComplete.prototype._elBody=null;YAHOO.widget.AutoComplete.prototype._elFooter=null;YAHOO.widget.AutoComplete.prototype._elShadow=null;YAHOO.widget.AutoComplete.prototype._elIFrame=null;YAHOO.widget.AutoComplete.prototype._bFocused=false;YAHOO.widget.AutoComplete.prototype._oAnim=null;YAHOO.widget.AutoComplete.prototype._bContainerOpen=false;YAHOO.widget.AutoComplete.prototype._bOverContainer=false;YAHOO.widget.AutoComplete.prototype._elList=null;YAHOO.widget.AutoComplete.prototype._nDisplayedItems=0;YAHOO.widget.AutoComplete.prototype._sCurQuery=null;YAHOO.widget.AutoComplete.prototype._sPastSelections="";YAHOO.widget.AutoComplete.prototype._sInitInputValue=null;YAHOO.widget.AutoComplete.prototype._elCurListItem=null;YAHOO.widget.AutoComplete.prototype._elCurPrehighlightItem=null;YAHOO.widget.AutoComplete.prototype._bItemSelected=false;YAHOO.widget.AutoComplete.prototype._nKeyCode=null;YAHOO.widget.AutoComplete.prototype._nDelayID=-1;YAHOO.widget.AutoComplete.prototype._nTypeAheadDelayID=-1;YAHOO.widget.AutoComplete.prototype._iFrameSrc="javascript:false;";YAHOO.widget.AutoComplete.prototype._queryInterval=null;YAHOO.widget.AutoComplete.prototype._sLastTextboxValue=null;YAHOO.widget.AutoComplete.prototype._initProps=function(){var b=this.minQueryLength;if(!YAHOO.lang.isNumber(b)){this.minQueryLength=1;}var e=this.maxResultsDisplayed;if(!YAHOO.lang.isNumber(e)||(e<1)){this.maxResultsDisplayed=10;}var f=this.queryDelay;if(!YAHOO.lang.isNumber(f)||(f<0)){this.queryDelay=0.2;}var c=this.typeAheadDelay;if(!YAHOO.lang.isNumber(c)||(c<0)){this.typeAheadDelay=0.2;}var a=this.delimChar;if(YAHOO.lang.isString(a)&&(a.length>0)){this.delimChar=[a];}else{if(!YAHOO.lang.isArray(a)){this.delimChar=null;}}var d=this.animSpeed;if((this.animHoriz||this.animVert)&&YAHOO.util.Anim){if(!YAHOO.lang.isNumber(d)||(d<0)){this.animSpeed=0.3;}if(!this._oAnim){this._oAnim=new YAHOO.util.Anim(this._elContent,{},this.animSpeed);}else{this._oAnim.duration=this.animSpeed;}}if(this.forceSelection&&a){}};YAHOO.widget.AutoComplete.prototype._initContainerHelperEls=function(){if(this.useShadow&&!this._elShadow){var a=document.createElement("div");a.className="yui-ac-shadow";a.style.width=0;a.style.height=0;this._elShadow=this._elContainer.appendChild(a);}if(this.useIFrame&&!this._elIFrame){var b=document.createElement("iframe");b.src=this._iFrameSrc;b.frameBorder=0;b.scrolling="no";b.style.position="absolute";b.style.width=0;b.style.height=0;b.style.padding=0;b.tabIndex=-1;b.role="presentation";b.title="Presentational iframe shim";this._elIFrame=this._elContainer.appendChild(b);}};YAHOO.widget.AutoComplete.prototype._initContainerEl=function(){YAHOO.util.Dom.addClass(this._elContainer,"yui-ac-container");if(!this._elContent){var c=document.createElement("div");c.className="yui-ac-content";c.style.display="none";this._elContent=this._elContainer.appendChild(c);var b=document.createElement("div");b.className="yui-ac-hd";b.style.display="none";this._elHeader=this._elContent.appendChild(b);var d=document.createElement("div");d.className="yui-ac-bd";this._elBody=this._elContent.appendChild(d);var a=document.createElement("div");a.className="yui-ac-ft";a.style.display="none";this._elFooter=this._elContent.appendChild(a);}else{}};YAHOO.widget.AutoComplete.prototype._initListEl=function(){var c=this.maxResultsDisplayed,a=this._elList||document.createElement("ul"),b;while(a.childNodes.length=18&&a<=20)||(a==27)||(a>=33&&a<=35)||(a>=36&&a<=40)||(a>=44&&a<=45)||(a==229)){return true;}return false;};YAHOO.widget.AutoComplete.prototype._sendQuery=function(d){if(this.minQueryLength<0){this._toggleContainer(false);return;}if(this.delimChar){var a=this._extractQuery(d);d=a.query;this._sPastSelections=a.previous;}if((d&&(d.length0)){if(this._nDelayID!=-1){clearTimeout(this._nDelayID); -}this._toggleContainer(false);return;}d=encodeURIComponent(d);this._nDelayID=-1;if(this.dataSource.queryMatchSubset||this.queryMatchSubset){var c=this.getSubsetMatches(d);if(c){this.handleResponse(d,c,{query:d});return;}}if(this.dataSource.responseStripAfter){this.dataSource.doBeforeParseData=this.preparseRawResponse;}if(this.applyLocalFilter){this.dataSource.doBeforeCallback=this.filterResults;}var b=this.generateRequest(d);if(b!==undefined){this.dataRequestEvent.fire(this,d,b);this.dataSource.sendRequest(b,{success:this.handleResponse,failure:this.handleResponse,scope:this,argument:{query:d}});}else{this.dataRequestCancelEvent.fire(this,d);}};YAHOO.widget.AutoComplete.prototype._populateListItem=function(b,a,c){b.innerHTML=this.formatResult(a,c,b._sResultMatch);};YAHOO.widget.AutoComplete.prototype._populateList=function(n,f,c){if(this._nTypeAheadDelayID!=-1){clearTimeout(this._nTypeAheadDelayID);}n=(c&&c.query)?c.query:n;var h=this.doBeforeLoadData(n,f,c);if(h&&!f.error){this.dataReturnEvent.fire(this,n,f.results);if(this._bFocused){var p=decodeURIComponent(n);this._sCurQuery=p;this._bItemSelected=false;var u=f.results,a=Math.min(u.length,this.maxResultsDisplayed),m=(this.dataSource.responseSchema.fields)?(this.dataSource.responseSchema.fields[0].key||this.dataSource.responseSchema.fields[0]):0;if(a>0){if(!this._elList||(this._elList.childNodes.length=0;t--){var s=l[t],e=u[t];if(this.resultTypeList){var b=[];b[0]=(YAHOO.lang.isString(e))?e:e[m]||e[this.key];var o=this.dataSource.responseSchema.fields;if(YAHOO.lang.isArray(o)&&(o.length>1)){for(var q=1,v=o.length;q=a;r--){g=l[r];g.style.display="none";}}this._nDisplayedItems=a;this.containerPopulateEvent.fire(this,n,u);if(this.autoHighlight){var d=this._elList.firstChild;this._toggleHighlight(d,"to");this.itemArrowToEvent.fire(this,d);this._typeAhead(d,n);}else{this._toggleHighlight(this._elCurListItem,"from");}h=this._doBeforeExpandContainer(this._elTextbox,this._elContainer,n,u);this._toggleContainer(h);}else{this._toggleContainer(false);}return;}}else{this.dataErrorEvent.fire(this,n,f);}};YAHOO.widget.AutoComplete.prototype._doBeforeExpandContainer=function(d,a,c,b){if(this.autoSnapContainer){this.snapContainer();}return this.doBeforeExpandContainer(d,a,c,b);};YAHOO.widget.AutoComplete.prototype._clearSelection=function(){var a=(this.delimChar)?this._extractQuery(this._elTextbox.value):{previous:"",query:this._elTextbox.value};this._elTextbox.value=a.previous;this.selectionEnforceEvent.fire(this,a.query);};YAHOO.widget.AutoComplete.prototype._textMatchesOption=function(){var a=null;for(var b=0;b=0;b--){g=h.lastIndexOf(c[b]);if(g>f){f=g;}}if(c[b]==" "){for(var a=c.length-1;a>=0;a--){if(h[f-1]==c[a]){f--;break;}}}if(f>-1){e=f+1;while(h.charAt(e)==" "){e+=1;}d=h.substring(0,e);h=h.substr(e);}else{d="";}return{previous:d,query:h};};YAHOO.widget.AutoComplete.prototype._toggleContainerHelpers=function(d){var e=this._elContent.offsetWidth+"px";var b=this._elContent.offsetHeight+"px";if(this.useIFrame&&this._elIFrame){var c=this._elIFrame;if(d){c.style.width=e;c.style.height=b;c.style.padding="";}else{c.style.width=0;c.style.height=0;c.style.padding=0;}}if(this.useShadow&&this._elShadow){var a=this._elShadow;if(d){a.style.width=e;a.style.height=b;}else{a.style.width=0;a.style.height=0;}}};YAHOO.widget.AutoComplete.prototype._toggleContainer=function(i){var d=this._elContainer;if(this.alwaysShowContainer&&this._bContainerOpen){return;}if(!i){this._toggleHighlight(this._elCurListItem,"from");this._nDisplayedItems=0;this._sCurQuery=null;if(this._elContent.style.display=="none"){return;}}var a=this._oAnim;if(a&&a.getEl()&&(this.animHoriz||this.animVert)){if(a.isAnimated()){a.stop(true);}var g=this._elContent.cloneNode(true);d.appendChild(g);g.style.top="-9000px";g.style.width="";g.style.height="";g.style.display="";var f=g.offsetWidth;var c=g.offsetHeight;var b=(this.animHoriz)?0:f;var e=(this.animVert)?0:c;a.attributes=(i)?{width:{to:f},height:{to:c}}:{width:{to:b},height:{to:e}};if(i&&!this._bContainerOpen){this._elContent.style.width=b+"px";this._elContent.style.height=e+"px";}else{this._elContent.style.width=f+"px";this._elContent.style.height=c+"px";}d.removeChild(g);g=null;var h=this;var j=function(){a.onComplete.unsubscribeAll();if(i){h._toggleContainerHelpers(true);h._bContainerOpen=i;h.containerExpandEvent.fire(h);}else{h._elContent.style.display="none";h._bContainerOpen=i;h.containerCollapseEvent.fire(h);}};this._toggleContainerHelpers(false);this._elContent.style.display="";a.onComplete.subscribe(j);a.animate();}else{if(i){this._elContent.style.display="";this._toggleContainerHelpers(true); -this._bContainerOpen=i;this.containerExpandEvent.fire(this);}else{this._toggleContainerHelpers(false);this._elContent.style.display="none";this._bContainerOpen=i;this.containerCollapseEvent.fire(this);}}};YAHOO.widget.AutoComplete.prototype._toggleHighlight=function(a,c){if(a){var b=this.highlightClassName;if(this._elCurListItem){YAHOO.util.Dom.removeClass(this._elCurListItem,b);this._elCurListItem=null;}if((c=="to")&&b){YAHOO.util.Dom.addClass(a,b);this._elCurListItem=a;}}};YAHOO.widget.AutoComplete.prototype._togglePrehighlight=function(b,c){var a=this.prehighlightClassName;if(this._elCurPrehighlightItem){YAHOO.util.Dom.removeClass(this._elCurPrehighlightItem,a);}if(b==this._elCurListItem){return;}if((c=="mouseover")&&a){YAHOO.util.Dom.addClass(b,a);this._elCurPrehighlightItem=b;}else{YAHOO.util.Dom.removeClass(b,a);}};YAHOO.widget.AutoComplete.prototype._updateValue=function(c){if(!this.suppressInputUpdate){var f=this._elTextbox;var e=(this.delimChar)?(this.delimChar[0]||this.delimChar):null;var b=c._sResultMatch;var d="";if(e){d=this._sPastSelections;d+=b+e;if(e!=" "){d+=" ";}}else{d=b;}f.value=d;if(f.type=="textarea"){f.scrollTop=f.scrollHeight;}var a=f.value.length;this._selectText(f,a,a);this._elCurListItem=c;}};YAHOO.widget.AutoComplete.prototype._selectItem=function(a){this._bItemSelected=true;this._updateValue(a);this._sPastSelections=this._elTextbox.value;this._clearInterval();this.itemSelectEvent.fire(this,a,a._oResultData);this._toggleContainer(false);};YAHOO.widget.AutoComplete.prototype._jumpSelection=function(){if(this._elCurListItem){this._selectItem(this._elCurListItem);}else{this._toggleContainer(false);}};YAHOO.widget.AutoComplete.prototype._moveSelection=function(g){if(this._bContainerOpen){var h=this._elCurListItem,d=-1;if(h){d=h._nItemIndex;}var e=(g==40)?(d+1):(d-1);if(e<-2||e>=this._nDisplayedItems){return;}if(h){this._toggleHighlight(h,"from");this.itemArrowFromEvent.fire(this,h);}if(e==-1){if(this.delimChar){this._elTextbox.value=this._sPastSelections+this._sCurQuery;}else{this._elTextbox.value=this._sCurQuery;}return;}if(e==-2){this._toggleContainer(false);return;}var f=this._elList.childNodes[e],b=this._elContent,c=YAHOO.util.Dom.getStyle(b,"overflow"),i=YAHOO.util.Dom.getStyle(b,"overflowY"),a=((c=="auto")||(c=="scroll")||(i=="auto")||(i=="scroll"));if(a&&(e>-1)&&(e(b.scrollTop+b.offsetHeight)){b.scrollTop=(f.offsetTop+f.offsetHeight)-b.offsetHeight;}else{if((f.offsetTop+f.offsetHeight)(b.scrollTop+b.offsetHeight)){this._elContent.scrollTop=(f.offsetTop+f.offsetHeight)-b.offsetHeight;}}}}this._toggleHighlight(f,"to");this.itemArrowToEvent.fire(this,f);if(this.typeAhead){this._updateValue(f);this._sCurQuery=f._sResultMatch;}}};YAHOO.widget.AutoComplete.prototype._onContainerMouseover=function(a,c){var d=YAHOO.util.Event.getTarget(a);var b=d.nodeName.toLowerCase();while(d&&(b!="table")){switch(b){case"body":return;case"li":if(c.prehighlightClassName){c._togglePrehighlight(d,"mouseover");}else{c._toggleHighlight(d,"to");}c.itemMouseOverEvent.fire(c,d);break;case"div":if(YAHOO.util.Dom.hasClass(d,"yui-ac-container")){c._bOverContainer=true;return;}break;default:break;}d=d.parentNode;if(d){b=d.nodeName.toLowerCase();}}};YAHOO.widget.AutoComplete.prototype._onContainerMouseout=function(a,c){var d=YAHOO.util.Event.getTarget(a);var b=d.nodeName.toLowerCase();while(d&&(b!="table")){switch(b){case"body":return;case"li":if(c.prehighlightClassName){c._togglePrehighlight(d,"mouseout");}else{c._toggleHighlight(d,"from");}c.itemMouseOutEvent.fire(c,d);break;case"ul":c._toggleHighlight(c._elCurListItem,"to");break;case"div":if(YAHOO.util.Dom.hasClass(d,"yui-ac-container")){c._bOverContainer=false;return;}break;default:break;}d=d.parentNode;if(d){b=d.nodeName.toLowerCase();}}};YAHOO.widget.AutoComplete.prototype._onContainerClick=function(a,c){var d=YAHOO.util.Event.getTarget(a);var b=d.nodeName.toLowerCase();while(d&&(b!="table")){switch(b){case"body":return;case"li":c._toggleHighlight(d,"to");c._selectItem(d);return;default:break;}d=d.parentNode;if(d){b=d.nodeName.toLowerCase();}}};YAHOO.widget.AutoComplete.prototype._onContainerScroll=function(a,b){b._focus();};YAHOO.widget.AutoComplete.prototype._onContainerResize=function(a,b){b._toggleContainerHelpers(b._bContainerOpen);};YAHOO.widget.AutoComplete.prototype._onTextboxKeyDown=function(a,b){var c=a.keyCode;if(b._nTypeAheadDelayID!=-1){clearTimeout(b._nTypeAheadDelayID);}switch(c){case 9:if(!YAHOO.env.ua.opera&&(navigator.userAgent.toLowerCase().indexOf("mac")==-1)||(YAHOO.env.ua.webkit>420)){if(b._elCurListItem){if(b.delimChar&&(b._nKeyCode!=c)){if(b._bContainerOpen){YAHOO.util.Event.stopEvent(a);}}b._selectItem(b._elCurListItem);}else{b._toggleContainer(false);}}break;case 13:if(!YAHOO.env.ua.opera&&(navigator.userAgent.toLowerCase().indexOf("mac")==-1)||(YAHOO.env.ua.webkit>420)){if(b._elCurListItem){if(b._nKeyCode!=c){if(b._bContainerOpen){YAHOO.util.Event.stopEvent(a);}}b._selectItem(b._elCurListItem);}else{b._toggleContainer(false);}}break;case 27:b._toggleContainer(false);return;case 39:b._jumpSelection();break;case 38:if(b._bContainerOpen){YAHOO.util.Event.stopEvent(a);b._moveSelection(c);}break;case 40:if(b._bContainerOpen){YAHOO.util.Event.stopEvent(a);b._moveSelection(c);}break;default:b._bItemSelected=false;b._toggleHighlight(b._elCurListItem,"from");b.textboxKeyEvent.fire(b,c);break;}if(c===18){b._enableIntervalDetection();}b._nKeyCode=c;};YAHOO.widget.AutoComplete.prototype._onTextboxKeyPress=function(a,b){var c=a.keyCode;if(YAHOO.env.ua.opera||(navigator.userAgent.toLowerCase().indexOf("mac")!=-1)&&(YAHOO.env.ua.webkit<420)){switch(c){case 9:if(b._bContainerOpen){if(b.delimChar){YAHOO.util.Event.stopEvent(a);}if(b._elCurListItem){b._selectItem(b._elCurListItem);}else{b._toggleContainer(false);}}break;case 13:if(b._bContainerOpen){YAHOO.util.Event.stopEvent(a); -if(b._elCurListItem){b._selectItem(b._elCurListItem);}else{b._toggleContainer(false);}}break;default:break;}}else{if(c==229){b._enableIntervalDetection();}}};YAHOO.widget.AutoComplete.prototype._onTextboxKeyUp=function(a,c){var b=this.value;c._initProps();var d=a.keyCode;if(c._isIgnoreKey(d)){return;}if(c._nDelayID!=-1){clearTimeout(c._nDelayID);}c._nDelayID=setTimeout(function(){c._sendQuery(b);},(c.queryDelay*1000));};YAHOO.widget.AutoComplete.prototype._onTextboxFocus=function(a,b){if(!b._bFocused){b._elTextbox.setAttribute("autocomplete","off");b._bFocused=true;b._sInitInputValue=b._elTextbox.value;b.textboxFocusEvent.fire(b);}};YAHOO.widget.AutoComplete.prototype._onTextboxBlur=function(a,c){if(!c._bOverContainer||(c._nKeyCode==9)){if(!c._bItemSelected){var b=c._textMatchesOption();if(!c._bContainerOpen||(c._bContainerOpen&&(b===null))){if(c.forceSelection){c._clearSelection();}else{c.unmatchedItemSelectEvent.fire(c,c._sCurQuery);}}else{if(c.forceSelection){c._selectItem(b);}}}c._clearInterval();c._bFocused=false;if(c._sInitInputValue!==c._elTextbox.value){c.textboxChangeEvent.fire(c);}c.textboxBlurEvent.fire(c);c._toggleContainer(false);}else{c._focus();}};YAHOO.widget.AutoComplete.prototype._onWindowUnload=function(a,b){if(b&&b._elTextbox&&b.allowBrowserAutocomplete){b._elTextbox.setAttribute("autocomplete","on");}};YAHOO.widget.AutoComplete.prototype.doBeforeSendQuery=function(a){return this.generateRequest(a);};YAHOO.widget.AutoComplete.prototype.getListItems=function(){var c=[],b=this._elList.childNodes;for(var a=b.length-1;a>=0;a--){c[a]=b[a];}return c;};YAHOO.widget.AutoComplete._cloneObject=function(d){if(!YAHOO.lang.isValue(d)){return d;}var f={};if(YAHOO.lang.isFunction(d)){f=d;}else{if(YAHOO.lang.isArray(d)){var e=[];for(var c=0,b=d.length;c0){g=f-1;do{d=e.subscribers[g];if(d&&d.obj==j&&d.fn==h){return true;}}while(g--);}return false;};YAHOO.lang.augmentProto(a,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Module=function(r,q){if(r){this.init(r,q);}else{}};var f=YAHOO.util.Dom,d=YAHOO.util.Config,n=YAHOO.util.Event,m=YAHOO.util.CustomEvent,g=YAHOO.widget.Module,i=YAHOO.env.ua,h,p,o,e,a={"BEFORE_INIT":"beforeInit","INIT":"init","APPEND":"append","BEFORE_RENDER":"beforeRender","RENDER":"render","CHANGE_HEADER":"changeHeader","CHANGE_BODY":"changeBody","CHANGE_FOOTER":"changeFooter","CHANGE_CONTENT":"changeContent","DESTROY":"destroy","BEFORE_SHOW":"beforeShow","SHOW":"show","BEFORE_HIDE":"beforeHide","HIDE":"hide"},j={"VISIBLE":{key:"visible",value:true,validator:YAHOO.lang.isBoolean},"EFFECT":{key:"effect",suppressEvent:true,supercedes:["visible"]},"MONITOR_RESIZE":{key:"monitorresize",value:true},"APPEND_TO_DOCUMENT_BODY":{key:"appendtodocumentbody",value:false}};g.IMG_ROOT=null;g.IMG_ROOT_SSL=null;g.CSS_MODULE="yui-module";g.CSS_HEADER="hd";g.CSS_BODY="bd";g.CSS_FOOTER="ft";g.RESIZE_MONITOR_SECURE_URL="javascript:false;";g.RESIZE_MONITOR_BUFFER=1;g.textResizeEvent=new m("textResize");g.forceDocumentRedraw=function(){var q=document.documentElement;if(q){q.className+=" ";q.className=YAHOO.lang.trim(q.className);}};function l(){if(!h){h=document.createElement("div");h.innerHTML=('
'+'
');p=h.firstChild;o=p.nextSibling;e=o.nextSibling;}return h;}function k(){if(!p){l();}return(p.cloneNode(false));}function b(){if(!o){l();}return(o.cloneNode(false));}function c(){if(!e){l();}return(e.cloneNode(false));}g.prototype={constructor:g,element:null,header:null,body:null,footer:null,id:null,imageRoot:g.IMG_ROOT,initEvents:function(){var q=m.LIST; -this.beforeInitEvent=this.createEvent(a.BEFORE_INIT);this.beforeInitEvent.signature=q;this.initEvent=this.createEvent(a.INIT);this.initEvent.signature=q;this.appendEvent=this.createEvent(a.APPEND);this.appendEvent.signature=q;this.beforeRenderEvent=this.createEvent(a.BEFORE_RENDER);this.beforeRenderEvent.signature=q;this.renderEvent=this.createEvent(a.RENDER);this.renderEvent.signature=q;this.changeHeaderEvent=this.createEvent(a.CHANGE_HEADER);this.changeHeaderEvent.signature=q;this.changeBodyEvent=this.createEvent(a.CHANGE_BODY);this.changeBodyEvent.signature=q;this.changeFooterEvent=this.createEvent(a.CHANGE_FOOTER);this.changeFooterEvent.signature=q;this.changeContentEvent=this.createEvent(a.CHANGE_CONTENT);this.changeContentEvent.signature=q;this.destroyEvent=this.createEvent(a.DESTROY);this.destroyEvent.signature=q;this.beforeShowEvent=this.createEvent(a.BEFORE_SHOW);this.beforeShowEvent.signature=q;this.showEvent=this.createEvent(a.SHOW);this.showEvent.signature=q;this.beforeHideEvent=this.createEvent(a.BEFORE_HIDE);this.beforeHideEvent.signature=q;this.hideEvent=this.createEvent(a.HIDE);this.hideEvent.signature=q;},platform:function(){var q=navigator.userAgent.toLowerCase();if(q.indexOf("windows")!=-1||q.indexOf("win32")!=-1){return"windows";}else{if(q.indexOf("macintosh")!=-1){return"mac";}else{return false;}}}(),browser:function(){var q=navigator.userAgent.toLowerCase();if(q.indexOf("opera")!=-1){return"opera";}else{if(q.indexOf("msie 7")!=-1){return"ie7";}else{if(q.indexOf("msie")!=-1){return"ie";}else{if(q.indexOf("safari")!=-1){return"safari";}else{if(q.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){this.cfg.addProperty(j.VISIBLE.key,{handler:this.configVisible,value:j.VISIBLE.value,validator:j.VISIBLE.validator});this.cfg.addProperty(j.EFFECT.key,{handler:this.configEffect,suppressEvent:j.EFFECT.suppressEvent,supercedes:j.EFFECT.supercedes});this.cfg.addProperty(j.MONITOR_RESIZE.key,{handler:this.configMonitorResize,value:j.MONITOR_RESIZE.value});this.cfg.addProperty(j.APPEND_TO_DOCUMENT_BODY.key,{value:j.APPEND_TO_DOCUMENT_BODY.value});},init:function(v,u){var s,w;this.initEvents();this.beforeInitEvent.fire(g);this.cfg=new d(this);if(this.isSecure){this.imageRoot=g.IMG_ROOT_SSL;}if(typeof v=="string"){s=v;v=document.getElementById(v);if(!v){v=(l()).cloneNode(false);v.id=s;}}this.id=f.generateId(v);this.element=v;w=this.element.firstChild;if(w){var r=false,q=false,t=false;do{if(1==w.nodeType){if(!r&&f.hasClass(w,g.CSS_HEADER)){this.header=w;r=true;}else{if(!q&&f.hasClass(w,g.CSS_BODY)){this.body=w;q=true;}else{if(!t&&f.hasClass(w,g.CSS_FOOTER)){this.footer=w;t=true;}}}}}while((w=w.nextSibling));}this.initDefaultConfig();f.addClass(this.element,g.CSS_MODULE);if(u){this.cfg.applyConfig(u,true);}if(!d.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}this.initEvent.fire(g);},initResizeMonitor:function(){var r=(i.gecko&&this.platform=="windows");if(r){var q=this;setTimeout(function(){q._initResizeMonitor();},0);}else{this._initResizeMonitor();}},_initResizeMonitor:function(){var q,s,u;function w(){g.textResizeEvent.fire();}if(!i.opera){s=f.get("_yuiResizeMonitor");var v=this._supportsCWResize();if(!s){s=document.createElement("iframe");if(this.isSecure&&g.RESIZE_MONITOR_SECURE_URL&&i.ie){s.src=g.RESIZE_MONITOR_SECURE_URL;}if(!v){u=[" diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html --- a/rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html Tue Jun 05 21:22:23 2012 +0200 @@ -106,12 +106,7 @@ YUD.setStyle('add_perm', 'opacity', '0.6'); YUD.setStyle('add_perm', 'cursor', 'default'); }); - MembersAutoComplete( - ${c.users_array|n}, - ${c.users_groups_array|n}, - "${_('Group')}", - "${_('members')}" - ); + MembersAutoComplete(${c.users_array|n}, ${c.users_groups_array|n}); }); diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/templates/admin/users/user_edit_my_account_form.html --- a/rhodecode/templates/admin/users/user_edit_my_account_form.html Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/templates/admin/users/user_edit_my_account_form.html Tue Jun 05 21:22:23 2012 +0200 @@ -82,4 +82,4 @@ ${h.end_form()} - \ No newline at end of file + diff -r 9d61aad859bc -r 91fae60bf2b6 rhodecode/templates/base/root.html --- a/rhodecode/templates/base/root.html Wed May 30 23:12:24 2012 +0200 +++ b/rhodecode/templates/base/root.html Tue Jun 05 21:22:23 2012 +0200 @@ -36,6 +36,18 @@ ## JAVASCRIPT ## <%def name="js()"> +