backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 13 Oct 2010 08:37:21 +0200
changeset 6470 8936b6786fb9
parent 6468 40033d536ed8 (diff)
parent 6469 82cf41ae8b89 (current diff)
child 6472 6e058f937126
backport stable
devtools/testlib.py
--- a/__pkginfo__.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/__pkginfo__.py	Wed Oct 13 08:37:21 2010 +0200
@@ -22,7 +22,7 @@
 
 modname = distname = "cubicweb"
 
-numversion = (3, 9, 8)
+numversion = (3, 10, 0)
 version = '.'.join(str(num) for num in numversion)
 
 description = "a repository of entities / relations for knowledge management"
@@ -42,7 +42,7 @@
 __depends__ = {
     'logilab-common': '>= 0.51.0',
     'logilab-mtconverter': '>= 0.8.0',
-    'rql': '>= 0.26.2',
+    'rql': '>= 0.27.0',
     'yams': '>= 0.30.1',
     'docutils': '>= 0.6',
     #gettext                    # for xgettext, msgcat, etc...
@@ -52,7 +52,7 @@
     'Twisted': '',
     # XXX graphviz
     # server dependencies
-    'logilab-database': '>= 1.3.0',
+    'logilab-database': '>= 1.3.1',
     'pysqlite': '>= 2.5.5', # XXX install pysqlite2
     }
 
--- a/cwconfig.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/cwconfig.py	Wed Oct 13 08:37:21 2010 +0200
@@ -26,12 +26,7 @@
 directories, such as cubes, instances, etc. to ease development with the
 framework. There are two running modes with *CubicWeb*:
 
-* 'user', resources are searched / created in the user home directory:
-
-  - instances are stored in :file:`~/etc/cubicweb.d`
-  - temporary files (such as pid file) in :file:`/tmp`
-
-* 'system', resources are searched / created in the system directories (eg
+* **system**: resources are searched / created in the system directories (eg
   usually requiring root access):
 
   - instances are stored in :file:`<INSTALL_PREFIX>/etc/cubicweb.d`
@@ -40,28 +35,34 @@
   where `<INSTALL_PREFIX>` is the detected installation prefix ('/usr/local' for
   instance).
 
+* **user**: resources are searched / created in the user home directory:
+
+  - instances are stored in :file:`~/etc/cubicweb.d`
+  - temporary files (such as pid file) in :file:`/tmp`
+
+
 
 Notice that each resource path may be explicitly set using an environment
 variable if the default doesn't suit your needs. Here are the default resource
 directories that are affected according to mode:
 
-* 'system': ::
+* **system**: ::
 
         CW_INSTANCES_DIR = <INSTALL_PREFIX>/etc/cubicweb.d/
         CW_INSTANCES_DATA_DIR = /var/lib/cubicweb/instances/
         CW_RUNTIME_DIR = /var/run/cubicweb/
 
-* 'user': ::
+* **user**: ::
 
         CW_INSTANCES_DIR = ~/etc/cubicweb.d/
         CW_INSTANCES_DATA_DIR = ~/etc/cubicweb.d/
         CW_RUNTIME_DIR = /tmp
 
-Cubes search path is also affected, see the :ref:Cube section.
+Cubes search path is also affected, see the :ref:`Cube` section.
 
-By default, the mode automatically set to 'user' if a :file:`.hg` directory is found
-in the cubicweb package, else it's set to 'system'. You can force this by setting
-the :envvar:`CW_MODE` environment variable to either 'user' or 'system' so you can
+By default, the mode automatically set to `user` if a :file:`.hg` directory is found
+in the cubicweb package, else it's set to `system`. You can force this by setting
+the :envvar:`CW_MODE` environment variable to either `user` or `system` so you can
 easily:
 
 * use system wide installation but user specific instances and all, without root
--- a/cwvreg.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/cwvreg.py	Wed Oct 13 08:37:21 2010 +0200
@@ -196,7 +196,7 @@
 from warnings import warn
 
 from logilab.common.decorators import cached, clear_cache
-from logilab.common.deprecation import  deprecated
+from logilab.common.deprecation import deprecated, class_deprecated
 from logilab.common.modutils import cleanup_sys_modules
 
 from rql import RQLHelper
@@ -389,6 +389,8 @@
         for vid, views in self.items():
             if vid[0] == '_':
                 continue
+            views = [view for view in views
+                     if not isinstance(view, class_deprecated)]
             try:
                 view = self._select_best(views, req, rset=rset, **kwargs)
                 if view.linkable():
@@ -421,6 +423,44 @@
 VRegistry.REGISTRY_FACTORY['actions'] = ActionsRegistry
 
 
+class CtxComponentsRegistry(CWRegistry):
+    def poss_visible_objects(self, *args, **kwargs):
+        """return an ordered list of possible components"""
+        context = kwargs.pop('context')
+        if kwargs.get('rset') is None:
+            cache = args[0]
+        else:
+            cache = kwargs['rset']
+        try:
+            cached = cache.__components_cache
+        except AttributeError:
+            ctxcomps = super(CtxComponentsRegistry, self).poss_visible_objects(
+                *args, **kwargs)
+            cached = cache.__components_cache = {}
+            for component in ctxcomps:
+                cached.setdefault(component.cw_propval('context'), []).append(component)
+        thisctxcomps = cached.get(context, ())
+        # XXX set context for bw compat (should now be taken by comp.render())
+        for component in thisctxcomps:
+            component.cw_extra_kwargs['context'] = context
+        return thisctxcomps
+
+VRegistry.REGISTRY_FACTORY['ctxcomponents'] = CtxComponentsRegistry
+
+
+class BwCompatCWRegistry(object):
+    def __init__(self, vreg, oldreg, redirecttoreg):
+        self.vreg = vreg
+        self.oldreg = oldreg
+        self.redirecto = redirecttoreg
+
+    def __getattr__(self, attr):
+        warn('[3.10] you should now use the %s registry instead of the %s registry'
+             % (self.redirecto, self.oldreg), DeprecationWarning, stacklevel=2)
+        return getattr(self.vreg[self.redirecto], attr)
+
+    def clear(self): pass
+    def initialization_completed(self): pass
 
 class CubicWebVRegistry(VRegistry):
     """Central registry for the cubicweb instance, extending the generic
@@ -433,15 +473,23 @@
     stored objects. Currently we have the following registries of objects known
     by the web instance (library may use some others additional registries):
 
-    * etypes
-    * views
-    * components
-    * actions
-    * forms
-    * formrenderers
-    * controllers, which are directly plugged into the application
-      object to handle request publishing XXX to merge with views
-    * contentnavigation XXX to merge with components? to kill?
+    * 'etypes', entity type classes
+
+    * 'views', views and templates (e.g. layout views)
+
+    * 'components', non contextual components, like magic search, url evaluators
+
+    * 'ctxcomponents', contextual components like boxes and dynamic section
+
+    * 'actions', contextual actions, eg links to display in predefined places in
+      the ui
+
+    * 'forms', describing logic of HTML form
+
+    * 'formrenderers', rendering forms to html
+
+    * 'controllers', primary objects to handle request publishing, directly
+      plugged into the application
     """
 
     def __init__(self, config, initlog=True):
@@ -456,6 +504,8 @@
             # don't clear rtags during test, this may cause breakage with
             # manually imported appobject modules
             CW_EVENT_MANAGER.bind('before-registry-reload', clear_rtag_objects)
+        self['boxes'] = BwCompatCWRegistry(self, 'boxes', 'ctxcomponents')
+        self['contentnavigation'] = BwCompatCWRegistry(self, 'contentnavigation', 'ctxcomponents')
 
     def setdefault(self, regid):
         try:
@@ -713,7 +763,7 @@
         vocab = pdef['vocabulary']
         if vocab is not None:
             if callable(vocab):
-                vocab = vocab(key, None) # XXX need a req object
+                vocab = vocab(None) # XXX need a req object
             if not value in vocab:
                 raise ValueError(_('unauthorized value'))
         return value
@@ -751,7 +801,7 @@
     def possible_actions(self, req, rset=None, **kwargs):
         return self["actions"].possible_actions(req, rest=rset, **kwargs)
 
-    @deprecated('[3.4] use vreg["boxes"].select_object(...)')
+    @deprecated('[3.4] use vreg["ctxcomponents"].select_object(...)')
     def select_box(self, oid, *args, **kwargs):
         return self['boxes'].select_object(oid, *args, **kwargs)
 
--- a/dataimport.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/dataimport.py	Wed Oct 13 08:37:21 2010 +0200
@@ -81,6 +81,7 @@
 from logilab.common.deprecation import deprecated
 
 from cubicweb.server.utils import eschema_eid
+from cubicweb.server.ssplanner import EditedEntity
 
 def count_lines(stream_or_filename):
     if isinstance(stream_or_filename, basestring):
@@ -612,8 +613,7 @@
         entity = copy(entity)
         entity.cw_clear_relation_cache()
         self.metagen.init_entity(entity)
-        entity.update(kwargs)
-        entity.edited_attributes = set(entity)
+        entity.cw_edited.update(kwargs, skipsec=False)
         session = self.session
         self.source.add_entity(session, entity)
         self.source.add_info(session, entity, self.source, None, complete=False)
@@ -651,6 +651,11 @@
 
 
 class MetaGenerator(object):
+    META_RELATIONS = (META_RTYPES
+                      - VIRTUAL_RTYPES
+                      - set(('eid', 'cwuri',
+                             'is', 'is_instance_of', 'cw_source')))
+
     def __init__(self, session, baseurl=None):
         self.session = session
         self.source = session.repo.system_source
@@ -669,25 +674,20 @@
         #self.entity_rels = [] XXX not handled (YAGNI?)
         schema = session.vreg.schema
         rschema = schema.rschema
-        for rtype in META_RTYPES:
-            if rtype in ('eid', 'cwuri') or rtype in VIRTUAL_RTYPES:
-                continue
+        for rtype in self.META_RELATIONS:
             if rschema(rtype).final:
                 self.etype_attrs.append(rtype)
             else:
                 self.etype_rels.append(rtype)
-        if not schema._eid_index:
-            # test schema loaded from the fs
-            self.gen_is = self.test_gen_is
-            self.gen_is_instance_of = self.test_gen_is_instanceof
 
     @cached
     def base_etype_dicts(self, etype):
         entity = self.session.vreg['etypes'].etype_class(etype)(self.session)
         # entity are "surface" copied, avoid shared dict between copies
         del entity.cw_extra_kwargs
+        entity.cw_edited = EditedEntity(entity)
         for attr in self.etype_attrs:
-            entity[attr] = self.generate(entity, attr)
+            entity.cw_edited.attribute_edited(attr, self.generate(entity, attr))
         rels = {}
         for rel in self.etype_rels:
             rels[rel] = self.generate(entity, rel)
@@ -696,7 +696,7 @@
     def init_entity(self, entity):
         entity.eid = self.source.create_eid(self.session)
         for attr in self.entity_attrs:
-            entity[attr] = self.generate(entity, attr)
+            entity.cw_edited.attribute_edited(attr, self.generate(entity, attr))
 
     def generate(self, entity, rtype):
         return getattr(self, 'gen_%s' % rtype)(entity)
@@ -709,26 +709,7 @@
     def gen_modification_date(self, entity):
         return self.time
 
-    def gen_is(self, entity):
-        return entity.e_schema.eid
-    def gen_is_instance_of(self, entity):
-        eids = []
-        for etype in entity.e_schema.ancestors() + [entity.e_schema]:
-            eids.append(entity.e_schema.eid)
-        return eids
-
     def gen_created_by(self, entity):
         return self.session.user.eid
     def gen_owned_by(self, entity):
         return self.session.user.eid
-
-    # implementations of gen_is / gen_is_instance_of to use during test where
-    # schema has been loaded from the fs (hence entity type schema eids are not
-    # known)
-    def test_gen_is(self, entity):
-        return eschema_eid(self.session, entity.e_schema)
-    def test_gen_is_instanceof(self, entity):
-        eids = []
-        for eschema in entity.e_schema.ancestors() + [entity.e_schema]:
-            eids.append(eschema_eid(self.session, eschema))
-        return eids
--- a/dbapi.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/dbapi.py	Wed Oct 13 08:37:21 2010 +0200
@@ -313,19 +313,17 @@
 
     # low level session data management #######################################
 
-    def get_shared_data(self, key, default=None, pop=False):
-        """return value associated to `key` in shared data"""
-        return self.cnx.get_shared_data(key, default, pop)
-
-    def set_shared_data(self, key, value, querydata=False):
-        """set value associated to `key` in shared data
+    def get_shared_data(self, key, default=None, pop=False, txdata=False):
+        """see :meth:`Connection.get_shared_data`"""
+        return self.cnx.get_shared_data(key, default, pop, txdata)
 
-        if `querydata` is true, the value will be added to the repository
-        session's query data which are cleared on commit/rollback of the current
-        transaction, and won't be available through the connexion, only on the
-        repository side.
-        """
-        return self.cnx.set_shared_data(key, value, querydata)
+    def set_shared_data(self, key, value, txdata=False, querydata=None):
+        """see :meth:`Connection.set_shared_data`"""
+        if querydata is not None:
+            txdata = querydata
+            warn('[3.10] querydata argument has been renamed to txdata',
+                 DeprecationWarning, stacklevel=2)
+        return self.cnx.set_shared_data(key, value, txdata)
 
     # server session compat layer #############################################
 
@@ -593,13 +591,15 @@
         else:
             from cubicweb.entity import Entity
             user = Entity(req, rset, row=0)
-        user['login'] = login # cache login
+        user.cw_attr_cache['login'] = login # cache login
         return user
 
     @check_not_closed
     def check(self):
-        """raise `BadConnectionId` if the connection is no more valid"""
-        self._repo.check_session(self.sessionid)
+        """raise `BadConnectionId` if the connection is no more valid, else
+        return its latest activity timestamp.
+        """
+        return self._repo.check_session(self.sessionid)
 
     def _txid(self, cursor=None): # XXX could now handle various isolation level!
         # return a dict as bw compat trick
@@ -616,20 +616,26 @@
         self._repo.set_session_props(self.sessionid, props)
 
     @check_not_closed
-    def get_shared_data(self, key, default=None, pop=False):
-        """return value associated to `key` in shared data"""
-        return self._repo.get_shared_data(self.sessionid, key, default, pop)
+    def get_shared_data(self, key, default=None, pop=False, txdata=False):
+        """return value associated to key in the session's data dictionary or
+        session's transaction's data if `txdata` is true.
+
+        If pop is True, value will be removed from the dictionnary.
+
+        If key isn't defined in the dictionnary, value specified by the
+        `default` argument will be returned.
+        """
+        return self._repo.get_shared_data(self.sessionid, key, default, pop, txdata)
 
     @check_not_closed
-    def set_shared_data(self, key, value, querydata=False):
+    def set_shared_data(self, key, value, txdata=False):
         """set value associated to `key` in shared data
 
-        if `querydata` is true, the value will be added to the repository
+        if `txdata` is true, the value will be added to the repository
         session's query data which are cleared on commit/rollback of the current
-        transaction, and won't be available through the connexion, only on the
-        repository side.
+        transaction.
         """
-        return self._repo.set_shared_data(self.sessionid, key, value, querydata)
+        return self._repo.set_shared_data(self.sessionid, key, value, txdata)
 
     # meta-data accessors ######################################################
 
--- a/debian/changelog	Wed Oct 13 08:37:09 2010 +0200
+++ b/debian/changelog	Wed Oct 13 08:37:21 2010 +0200
@@ -1,3 +1,9 @@
+cubicweb (3.10.0-1) unstable; urgency=low
+
+  * 
+
+ --
+
 cubicweb (3.9.8-1) unstable; urgency=low
 
   * new upstream release
--- a/debian/control	Wed Oct 13 08:37:09 2010 +0200
+++ b/debian/control	Wed Oct 13 08:37:21 2010 +0200
@@ -33,7 +33,7 @@
 Conflicts: cubicweb-multisources
 Replaces: cubicweb-multisources
 Provides: cubicweb-multisources
-Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-logilab-database (>= 1.3.0), cubicweb-postgresql-support | cubicweb-mysql-support | python-pysqlite2
+Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-logilab-database (>= 1.3.1), cubicweb-postgresql-support | cubicweb-mysql-support | python-pysqlite2
 Recommends: pyro (< 4.0.0), cubicweb-documentation (= ${source:Version})
 Description: server part of the CubicWeb framework
  CubicWeb is a semantic web application framework.
@@ -97,7 +97,7 @@
 Package: cubicweb-common
 Architecture: all
 XB-Python-Version: ${python:Versions}
-Depends: ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.8.0), python-logilab-common (>= 0.51.0), python-yams (>= 0.30.1), python-rql (>= 0.26.3), python-lxml
+Depends: ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.8.0), python-logilab-common (>= 0.51.0), python-yams (>= 0.30.1), python-rql (>= 0.27.0), python-lxml
 Recommends: python-simpletal (>= 4.0), python-crypto
 Conflicts: cubicweb-core
 Replaces: cubicweb-core
--- a/devtools/__init__.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/devtools/__init__.py	Wed Oct 13 08:37:21 2010 +0200
@@ -35,30 +35,19 @@
 
 # db auto-population configuration #############################################
 
-SYSTEM_ENTITIES = schema.SCHEMA_TYPES | set((
-    'CWGroup', 'CWUser', 'CWProperty',
-    'Workflow', 'State', 'BaseTransition', 'Transition', 'WorkflowTransition',
-    'TrInfo', 'SubWorkflowExitPoint',
-    ))
-
-SYSTEM_RELATIONS = schema.META_RTYPES | set((
-    # workflow related
-    'workflow_of', 'state_of', 'transition_of', 'initial_state', 'default_workflow',
-    'allowed_transition', 'destination_state', 'from_state', 'to_state',
-    'condition', 'subworkflow', 'subworkflow_state', 'subworkflow_exit',
-    'custom_workflow', 'in_state', 'wf_info_for',
-    # cwproperty
-    'for_user',
-    # schema definition
-    'specializes',
-    'relation_type', 'from_entity', 'to_entity',
-    'constrained_by', 'cstrtype', 'widget',
-    'read_permission', 'update_permission', 'delete_permission', 'add_permission',
-    # permission
-    'in_group', 'require_group', 'require_permission',
-    # deducted from other relations
-    'primary_email',
-    ))
+SYSTEM_ENTITIES = (schema.SCHEMA_TYPES
+                   | schema.INTERNAL_TYPES
+                   | schema.WORKFLOW_TYPES
+                   | set(('CWGroup', 'CWUser',))
+                   )
+SYSTEM_RELATIONS = (schema.META_RTYPES
+                    | schema.WORKFLOW_RTYPES
+                    | schema.WORKFLOW_DEF_RTYPES
+                    | schema.SYSTEM_RTYPES
+                    | schema.SCHEMA_TYPES
+                    | set(('primary_email', # deducted from other relations
+                           ))
+                    )
 
 # content validation configuration #############################################
 
@@ -166,6 +155,8 @@
         sources = super(TestServerConfiguration, self).sources()
         if not sources:
             sources = DEFAULT_SOURCES
+        if 'admin' not in sources:
+            sources['admin'] = DEFAULT_SOURCES['admin']
         return sources
 
     # web config methods needed here for cases when we use this config as a web
--- a/devtools/devctl.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/devtools/devctl.py	Wed Oct 13 08:37:21 2010 +0200
@@ -122,8 +122,8 @@
     from copy import deepcopy
     from cubicweb.i18n import add_msg
     from cubicweb.web import uicfg
-    from cubicweb.schema import META_RTYPES, SYSTEM_RTYPES, CONSTRAINTS
-    no_context_rtypes = META_RTYPES | SYSTEM_RTYPES
+    from cubicweb.schema import META_RTYPES, WORKFLOW_RTYPES, CONSTRAINTS
+    no_context_rtypes = META_RTYPES | WORKFLOW_RTYPES
     w('# schema pot file, generated on %s\n'
       % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
     w('# \n')
@@ -234,6 +234,8 @@
 
 def _iter_vreg_objids(vreg, done):
     for reg, objdict in vreg.items():
+        if reg in ('boxes', 'contentnavigation'):
+            continue
         for objects in objdict.values():
             for obj in objects:
                 objid = '%s_%s' % (reg, obj.__regid__)
@@ -345,7 +347,7 @@
         print 'when you are done, run "cubicweb-ctl i18ncube yourcube".'
 
 
-class UpdateTemplateCatalogCommand(Command):
+class UpdateCubeCatalogCommand(Command):
     """Update i18n catalogs for cubes. If no cube is specified, update
     catalogs of all registered cubes.
     """
@@ -782,7 +784,7 @@
         print make_qunit_html(args[0], args[1:])
 
 for cmdcls in (UpdateCubicWebCatalogCommand,
-               UpdateTemplateCatalogCommand,
+               UpdateCubeCatalogCommand,
                #LiveServerCommand,
                NewCubeCommand,
                ExamineLogCommand,
--- a/devtools/fake.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/devtools/fake.py	Wed Oct 13 08:37:21 2010 +0200
@@ -170,6 +170,7 @@
         self.config = config or FakeConfig()
         self.vreg = vreg or CubicWebVRegistry(self.config, initlog=False)
         self.vreg.schema = schema
+        self.sources = []
 
     def internal_session(self):
         return FakeSession(self)
--- a/devtools/repotest.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/devtools/repotest.py	Wed Oct 13 08:37:21 2010 +0200
@@ -284,8 +284,7 @@
         self.repo.vreg.rqlhelper.backend = 'postgres' # so FTIRANK is considered
 
     def add_source(self, sourcecls, uri):
-        self.sources.append(sourcecls(self.repo, self.o.schema,
-                                      {'uri': uri}))
+        self.sources.append(sourcecls(self.repo, {'uri': uri}))
         self.repo.sources_by_uri[uri] = self.sources[-1]
         setattr(self, uri, self.sources[-1])
         self.newsources += 1
--- a/devtools/testlib.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/devtools/testlib.py	Wed Oct 13 08:37:21 2010 +0200
@@ -37,7 +37,7 @@
 from logilab.common.debugger import Debugger
 from logilab.common.umessage import message_from_string
 from logilab.common.decorators import cached, classproperty, clear_cache
-from logilab.common.deprecation import deprecated
+from logilab.common.deprecation import deprecated, class_deprecated
 
 from cubicweb import ValidationError, NoSelectableObject, AuthenticationError
 from cubicweb import cwconfig, devtools, web, server
@@ -295,12 +295,15 @@
     def set_debug(self, debugmode):
         server.set_debug(debugmode)
 
+    def debugged(self, debugmode):
+        return server.debugged(debugmode)
+
     # default test setup and teardown #########################################
 
     def setUp(self):
         # monkey patch send mail operation so emails are sent synchronously
-        self._old_mail_commit_event = SendMailOp.commit_event
-        SendMailOp.commit_event = SendMailOp.sendmails
+        self._old_mail_postcommit_event = SendMailOp.postcommit_event
+        SendMailOp.postcommit_event = SendMailOp.sendmails
         pause_tracing()
         previous_failure = self.__class__.__dict__.get('_repo_init_failed')
         if previous_failure is not None:
@@ -322,7 +325,7 @@
         for cnx in self._cnxs:
             if not cnx._closed:
                 cnx.close()
-        SendMailOp.commit_event = self._old_mail_commit_event
+        SendMailOp.postcommit_event = self._old_mail_postcommit_event
 
     def setup_database(self):
         """add your database setup code by overriding this method"""
@@ -492,7 +495,8 @@
                 continue
             views = [view for view in views
                      if view.category != 'startupview'
-                     and not issubclass(view, notification.NotificationView)]
+                     and not issubclass(view, notification.NotificationView)
+                     and not isinstance(view, class_deprecated)]
             if views:
                 try:
                     view = viewsvreg._select_best(views, req, rset=rset)
@@ -514,7 +518,7 @@
     def list_boxes_for(self, rset):
         """returns the list of boxes that can be applied on `rset`"""
         req = rset.req
-        for box in self.vreg['boxes'].possible_objects(req, rset=rset):
+        for box in self.vreg['ctxcomponents'].possible_objects(req, rset=rset):
             yield box
 
     def list_startup_views(self):
@@ -969,7 +973,8 @@
         for action in self.list_actions_for(rset):
             yield InnerTest(self._testname(rset, action.__regid__, 'action'), self._test_action, action)
         for box in self.list_boxes_for(rset):
-            yield InnerTest(self._testname(rset, box.__regid__, 'box'), box.render)
+            w = [].append
+            yield InnerTest(self._testname(rset, box.__regid__, 'box'), box.render, w)
 
     @staticmethod
     def _testname(rset, objid, objtype):
--- a/doc/book/en/devrepo/devcore/cwconfig.rst	Wed Oct 13 08:37:09 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-Configuration
--------------
-
-.. automodule:: cubicweb.cwconfig
-      :members:
--- a/doc/book/en/devrepo/devcore/index.rst	Wed Oct 13 08:37:09 2010 +0200
+++ b/doc/book/en/devrepo/devcore/index.rst	Wed Oct 13 08:37:21 2010 +0200
@@ -6,5 +6,4 @@
 
    dbapi.rst
    reqbase.rst
-   cwconfig.rst
 
--- a/doc/book/en/devrepo/repo/hooks.rst	Wed Oct 13 08:37:09 2010 +0200
+++ b/doc/book/en/devrepo/repo/hooks.rst	Wed Oct 13 08:37:21 2010 +0200
@@ -1,162 +1,27 @@
 .. -*- coding: utf-8 -*-
-
 .. _hooks:
 
 Hooks and Operations
 ====================
 
-Generalities
-------------
-
-Paraphrasing the `emacs`_ documentation, let us say that hooks are an
-important mechanism for customizing an application. A hook is
-basically a list of functions to be called on some well-defined
-occasion (this is called `running the hook`).
-
-.. _`emacs`: http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html
-
-In CubicWeb, hooks are subclasses of the Hook class in
-`server/hook.py`, implementing their own `call` method, and selected
-over a set of pre-defined `events` (and possibly more conditions,
-hooks being selectable AppObjects like views and components).
-
-There are two families of events: data events and server events. In a
-typical application, most of the Hooks are defined over data
-events.
-
-The purpose of data hooks is to complement the data model as defined
-in the schema.py, which is static by nature, with dynamic or value
-driven behaviours. It is functionally equivalent to a `database
-trigger`_, except that database triggers definition languages are not
-standardized, hence not portable (for instance, PL/SQL works with
-Oracle and PostgreSQL but not SqlServer nor Sqlite).
-
-.. _`database trigger`: http://en.wikipedia.org/wiki/Database_trigger
-
-Data hooks can serve the following purposes:
-
-* enforcing constraints that the static schema cannot express
-  (spanning several entities/relations, exotic value ranges and
-  cardinalities, etc.)
-
-* implement computed attributes
-
-Operations are Hook-like objects that may be created by Hooks and
-scheduled to happen just before (or after) the `commit` event. Hooks
-being fired immediately on data operations, it is sometime necessary
-to delay the actual work down to a time where all other Hooks have
-run, for instance a validation check which needs that all relations be
-already set on an entity. Also while the order of execution of Hooks
-is data dependant (and thus hard to predict), it is possible to force
-an order on Operations.
-
-Operations also may be used to process various side effects associated
-with a transaction such as filesystem udpates, mail notifications,
-etc.
-
-Operations are subclasses of the Operation class in `server/hook.py`,
-implementing `precommit_event` and other standard methods (wholly
-described in :ref:`operations_api`).
-
-.. hint::
-
-   It is a good practice, to write unit tests for each hook. See an example in :ref:`hook_test`
-
-Events
-------
-
-Hooks are mostly defined and used to handle `dataflow`_ operations. It
-means as data gets in (entities added, updated, relations set or
-unset), specific events are issued and the Hooks matching these events
-are called.
-
-.. _`dataflow`: http://en.wikipedia.org/wiki/Dataflow
-
-Below comes a list of the dataflow events related to entities operations:
-
-* before_add_entity
-
-* before_update_entity
-
-* before_delete_entity
-
-* after_add_entity
-
-* after_update_entity
-
-* after_delete_entity
-
-These define ENTTIES HOOKS. RELATIONS HOOKS are defined
-over the following events:
-
-* after_add_relation
-
-* after_delete_relation
-
-* before_add_relation
-
-* before_delete_relation
-
-This is an occasion to remind us that relations support the add/delete
-operation, but no update.
-
-Non data events also exist. These are called SYSTEM HOOKS.
-
-* server_startup
-
-* server_shutdown
-
-* server_maintenance
-
-* server_backup
-
-* server_restore
-
-* session_open
-
-* session_close
+.. autodocstring:: cubicweb.server.hook
 
 
-Using dataflow Hooks
---------------------
-
-Dataflow hooks either automate data operations or maintain the
-consistency of the data model. In the later case, we must use a
-specific exception named ValidationError
-
-Validation Errors
-~~~~~~~~~~~~~~~~~
-
-When a condition is not met in a Hook/Operation, it must raise a
-`ValidationError`. Raising anything but a (subclass of)
-ValidationError is a programming error. Raising a ValidationError
-entails aborting the current transaction.
+Example using dataflow hooks
+----------------------------
 
-The ValidationError exception is used to convey enough information up
-to the user interface. Hence its constructor is different from the
-default Exception constructor. It accepts, positionally:
-
-* an entity eid,
-
-* a dict whose keys represent attribute (or relation) names and values
-  an end-user facing message (hence properly translated) relating the
-  problem.
-
-An entity hook
-~~~~~~~~~~~~~~
-
-We will use a very simple example to show hooks usage. Let us start
-with the following schema.
+We will use a very simple example to show hooks usage. Let us start with the
+following schema.
 
 .. sourcecode:: python
 
    class Person(EntityType):
        age = Int(required=True)
 
-We would like to add a range constraint over a person's age. Let's
-write an hook. It shall be placed into mycube/hooks.py. If this file
-were to grow too much, we can easily have a mycube/hooks/... package
-containing hooks in various modules.
+We would like to add a range constraint over a person's age. Let's write an hook
+(supposing yams can not handle this nativly, which is wrong). It shall be placed
+into `mycube/hooks.py`. If this file were to grow too much, we can easily have a
+`mycube/hooks/... package` containing hooks in various modules.
 
 .. sourcecode:: python
 
@@ -166,68 +31,30 @@
 
    class PersonAgeRange(Hook):
         __regid__ = 'person_age_range'
+        __select__ = Hook.__select__ & is_instance('Person')
         events = ('before_add_entity', 'before_update_entity')
-        __select__ = Hook.__select__ & is_instance('Person')
 
         def __call__(self):
-            if 0 >= self.entity.age <= 120:
-               return
-            msg = self._cw._('age must be between 0 and 120')
-            raise ValidationError(self.entity.eid, {'age': msg})
-
-Hooks being AppObjects like views, they have a __regid__ and a
-__select__ class attribute. The base __select__ is augmented with an
-`is_instance` selector matching the desired entity type. The `events`
-tuple is used by the Hook.__select__ base selector to dispatch the
-hook on the right events. In an entity hook, it is possible to
-dispatch on any entity event (e.g. 'before_add_entity',
-'before_update_entity') at once if needed.
+	    if 'age' in self.entity.cw_edited:
+                if 0 <= self.entity.age <= 120:
+                   return
+		msg = self._cw._('age must be between 0 and 120')
+		raise ValidationError(self.entity.eid, {'age': msg})
 
-Like all appobjects, hooks have the `self._cw` attribute which
-represents the current session. In entity hooks, a `self.entity`
-attribute is also present.
-
-
-A relation hook
-~~~~~~~~~~~~~~~
-
-Let us add another entity type with a relation to person (in
-mycube/schema.py).
-
-.. sourcecode:: python
+In our example the base `__select__` is augmented with an `is_instance` selector
+matching the desired entity type.
 
-   class Company(EntityType):
-        name = String(required=True)
-        boss = SubjectRelation('Person', cardinality='1*')
+The `events` tuple is used specify that our hook should be called before the
+entity is added or updated.
 
-We would like to constrain the company's bosses to have a minimum
-(legal) age. Let's write an hook for this, which will be fired when
-the `boss` relation is established.
-
-.. sourcecode:: python
-
-   class CompanyBossLegalAge(Hook):
-        __regid__ = 'company_boss_legal_age'
-        events = ('before_add_relation',)
-        __select__ = Hook.__select__ & match_rtype('boss')
+Then in the hook's `__call__` method, we:
 
-        def __call__(self):
-            boss = self._cw.entity_from_eid(self.eidto)
-            if boss.age < 18:
-                msg = self._cw._('the minimum age for a boss is 18')
-                raise ValidationError(self.eidfrom, {'boss': msg})
-
-We use the `match_rtype` selector to select the proper relation type.
+* check if the 'age' attribute is edited
+* if so, check the value is in the range
+* if not, raise a validation error properly
 
-The essential difference with respect to an entity hook is that there
-is no self.entity, but `self.eidfrom` and `self.eidto` hook attributes
-which represent the subject and object eid of the relation.
-
-
-Using Operations
-----------------
-
-Let's augment our example with a new `subsidiary_of` relation on Company.
+Now Let's augment our schema with new `Company` entity type with some relation to
+`Person` (in 'mycube/schema.py').
 
 .. sourcecode:: python
 
@@ -236,12 +63,37 @@
         boss = SubjectRelation('Person', cardinality='1*')
         subsidiary_of = SubjectRelation('Company', cardinality='*?')
 
-Base example
-~~~~~~~~~~~~
+
+We would like to constrain the company's bosses to have a minimum (legal)
+age. Let's write an hook for this, which will be fired when the `boss` relation
+is established (still supposing we could not specify that kind of thing in the
+schema).
+
+.. sourcecode:: python
+
+   class CompanyBossLegalAge(Hook):
+        __regid__ = 'company_boss_legal_age'
+        __select__ = Hook.__select__ & match_rtype('boss')
+        events = ('before_add_relation',)
 
-We would like to check that there is no cycle by the `subsidiary_of`
-relation. This is best achieved in an Operation since all relations
-are likely to be set at commit time.
+        def __call__(self):
+            boss = self._cw.entity_from_eid(self.eidto)
+            if boss.age < 18:
+                msg = self._cw._('the minimum age for a boss is 18')
+                raise ValidationError(self.eidfrom, {'boss': msg})
+
+.. Note::
+
+    We use the :class:`~cubicweb.server.hook.match_rtype` selector to select the
+    proper relation type.
+
+    The essential difference with respect to an entity hook is that there is no
+    self.entity, but `self.eidfrom` and `self.eidto` hook attributes which
+    represent the subject and object **eid** of the relation.
+
+Suppose we want to check that there is no cycle by the `subsidiary_of`
+relation. This is best achieved in an operation since all relations are likely to
+be set at commit time.
 
 .. sourcecode:: python
 
@@ -257,6 +109,7 @@
                 raise ValidationError(eid, {rtype: msg})
             parents.add(parent.eid)
 
+
     class CheckSubsidiaryCycleOp(Operation):
 
         def precommit_event(self):
@@ -265,30 +118,20 @@
 
     class CheckSubsidiaryCycleHook(Hook):
         __regid__ = 'check_no_subsidiary_cycle'
+        __select__ = Hook.__select__ & match_rtype('subsidiary_of')
         events = ('after_add_relation',)
-        __select__ = Hook.__select__ & match_rtype('subsidiary_of')
 
         def __call__(self):
             CheckSubsidiaryCycleOp(self._cw, eidto=self.eidto)
 
-The operation is instantiated in the Hook.__call__ method.
 
-An operation always takes a session object as first argument
-(accessible as `.session` from the operation instance), and optionally
-all keyword arguments needed by the operation. These keyword arguments
-will be accessible as attributes from the operation instance.
+Like in hooks, :exc:`~cubicweb.ValidationError` can be raised in operations. Other
+exceptions are usually programming errors.
 
-Like in Hooks, ValidationError can be raised in Operations. Other
-exceptions are programming errors.
-
-Notice how our hook will instantiate an operation each time the Hook
-is called, i.e. each time the `subsidiary_of` relation is set.
-
-Using set_operation
-~~~~~~~~~~~~~~~~~~~
-
-There is an alternative method to schedule an Operation from a Hook,
-using the `set_operation` function.
+In the above example, our hook will instantiate an operation each time the hook
+is called, i.e. each time the `subsidiary_of` relation is set. There is an
+alternative method to schedule an operation from a hook, using the
+:func:`set_operation` function.
 
 .. sourcecode:: python
 
@@ -301,7 +144,7 @@
 
        def __call__(self):
            set_operation(self._cw, 'subsidiary_cycle_detection', self.eidto,
-                         CheckSubsidiaryCycleOp, rtype=self.rtype)
+                         CheckSubsidiaryCycleOp)
 
    class CheckSubsidiaryCycleOp(Operation):
 
@@ -309,134 +152,83 @@
            for eid in self.session.transaction_data['subsidiary_cycle_detection']:
                check_cycle(self.session, eid, self.rtype)
 
-Here, we call set_operation with a session object, a specially forged
-key, a value that is the actual payload of an individual operation (in
-our case, the object of the subsidiary_of relation) , the class of the
-Operation, and more optional parameters to give to the operation (here
-the rtype which do not vary accross operations).
-
-The body of the operation must then iterate over the values that have
-been mapped in the transaction_data dictionary to the forged key.
 
-This mechanism is especially useful on two occasions (not shown in our
-example):
+Here, we call :func:`set_operation` so that we will simply accumulate eids of
+entities to check at the end in a single `CheckSubsidiaryCycleOp`
+operation. Value are stored in a set associated to the
+'subsidiary_cycle_detection' transaction data key. The set initialization and
+operation creation are handled nicely by :func:`set_operation`.
 
-* massive data import (reduced memory consumption within a large
-  transaction)
+A more realistic example can be found in the advanced tutorial chapter
+:ref:`adv_tuto_security_propagation`.
 
-* when several hooks need to instantiate the same operation (e.g. an
-  entity and a relation hook).
-
-.. note::
 
-  A more realistic example can be found in the advanced tutorial
-  chapter :ref:`adv_tuto_security_propagation`.
-
-.. _operations_api:
-
-Operation: a small API overview
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Hooks writing tips
+------------------
 
-.. autoclass:: cubicweb.server.hook.Operation
-.. autoclass:: cubicweb.server.hook.LateOperation
-.. autofunction:: cubicweb.server.hook.set_operation
+Reminder
+~~~~~~~~
 
-Hooks writing rules
--------------------
+Never, ever use the `entity.foo = 42` notation to update an entity. It will not
+work.To updating an entity attribute or relation, uses :meth:`set_attributes` and
+:meth:`set_relations` methods.
 
-Remainder
-~~~~~~~~~
-
-Never, ever use the `entity.foo = 42` notation to update an entity. It
-will not work.
 
 How to choose between a before and an after event ?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Before hooks give you access to the old attribute (or relation)
-values. By definition the database is not yet updated in a before
-hook.
-
-To access old and new values in an before_update_entity hook, one can
-use the `server.hook.entity_oldnewvalue` function which returns a
-tuple of the old and new values. This function takes an entity and an
-attribute name as parameters.
-
-In a 'before_add|update_entity' hook the self.entity contains the new
-values. One is allowed to further modify them before database
-operations, using the dictionary notation.
-
-.. sourcecode:: python
-
-   self.entity['age'] = 42
+'before_*' hooks give you access to the old attribute (or relation)
+values. You can also hi-jack actually edited stuff in the case of entity
+modification. Needing one of this will definitly guide your choice.
 
-This is because using self.entity.set_attributes(age=42) will
-immediately update the database (which does not make sense in a
-pre-database hook), and will trigger any existing
-before_add|update_entity hook, thus leading to infinite hook loops or
-such awkward situations.
-
-Beyond these specific cases, updating an entity attribute or relation
-must *always* be done using `set_attributes` and `set_relations`
-methods.
+Else the question is: should I need to do things before or after the actual
+modification. If the answer is "it doesn't matter", use an 'after' event.
 
-(Of course, ValidationError will always abort the current transaction,
-whetever the event).
 
-Peculiarities of inlined relations
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Some relations are defined in the schema as `inlined` (see
-:ref:`RelationType` for details). In this case, they are inserted in
-the database at the same time as entity attributes.
-
-Hence in the case of before_add_relation, such relations already exist
-in the database.
-
-Edited attributes
+Validation Errors
 ~~~~~~~~~~~~~~~~~
 
-On udpates, it is possible to ask the `entity.edited_attributes`
-variable whether one attribute has been updated.
+When a hook is responsible to maintain the consistency of the data model detect
+an error, it must use a specific exception named
+:exc:`~cubicweb.ValidationError`. Raising anything but a (subclass of)
+:exc:`~cubicweb.ValidationError` is a programming error. Raising a it entails
+aborting the current transaction.
 
-.. sourcecode:: python
+This exception is used to convey enough information up to the user
+interface. Hence its constructor is different from the default Exception
+constructor. It accepts, positionally:
+
+* an entity eid,
 
-  if 'age' not in entity.edited_attribute:
-      return
+* a dict whose keys represent attribute (or relation) names and values
+  an end-user facing message (hence properly translated) relating the
+  problem.
+
+
+Checking for object created/deleted in the current transaction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Deleted in transaction
-~~~~~~~~~~~~~~~~~~~~~~
+In hooks, you can use the
+:meth:`~cubicweb.server.session.Session.added_in_transaction` or
+:meth:`~cubicweb.server.session.Session.deleted_in_transaction` of the session
+object to check if an eid has been created or deleted during the hook's
+transaction.
 
-The session object has a deleted_in_transaction method, which can help
-writing deletion Hooks.
+This is useful to enable or disable some stuff if some entity is being added or
+deleted.
 
 .. sourcecode:: python
 
    if self._cw.deleted_in_transaction(self.eidto):
       return
 
-Given this predicate, we can avoid scheduling an operation.
 
-Disabling hooks
-~~~~~~~~~~~~~~~
-
-It is sometimes convenient to disable some hooks. For instance to
-avoid infinite Hook loops. One uses the `hooks_control` context
-manager.
-
-This can be controlled more finely through the `category` Hook class
-attribute, which is a string.
+Peculiarities of inlined relations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. sourcecode:: python
-
-   with hooks_control(self.session, self.session.HOOKS_ALLOW_ALL, <category>):
-       # ... do stuff
-
-.. autoclass:: cubicweb.server.session.hooks_control
-
-The existing categories are: ``email``, ``syncsession``,
-``syncschema``, ``bookmark``, ``security``, ``worfklow``,
-``metadata``, ``notification``, ``integrity``, ``activeintegrity``.
-
-Nothing precludes one to invent new categories and use the
-hooks_control context manager to filter them (in or out).
+Relations which are defined in the schema as `inlined` (see :ref:`RelationType`
+for details) are inserted in the database at the same time as entity attributes.
+This may have some side effect, for instance when creating entity and setting an
+inlined relation in the same rql query, when 'before_add_relation' for that
+relation will be run, the relation will already exist in the database (it's
+usually not the case).
--- a/doc/book/en/devrepo/vreg.rst	Wed Oct 13 08:37:09 2010 +0200
+++ b/doc/book/en/devrepo/vreg.rst	Wed Oct 13 08:37:21 2010 +0200
@@ -38,6 +38,7 @@
 .. autoclass:: cubicweb.selectors.match_kwargs
 .. autoclass:: cubicweb.selectors.appobject_selectable
 .. autoclass:: cubicweb.selectors.adaptable
+.. autoclass:: cubicweb.selectors.configuration_values
 
 
 Result set selectors
@@ -77,6 +78,7 @@
 .. autoclass:: cubicweb.selectors.has_permission
 .. autoclass:: cubicweb.selectors.has_add_permission
 .. autoclass:: cubicweb.selectors.has_mimetype
+.. autoclass:: cubicweb.selectors.is_in_state
 .. autoclass:: cubicweb.selectors.implements
 
 
@@ -100,11 +102,13 @@
 .. autoclass:: cubicweb.selectors.match_view
 .. autoclass:: cubicweb.selectors.primary_view
 .. autoclass:: cubicweb.selectors.specified_etype_implements
+.. autoclass:: cubicweb.selectors.attribute_edited
 
 
 Other selectors
 ~~~~~~~~~~~~~~~
 .. autoclass:: cubicweb.selectors.match_transition
+.. autoclass:: cubicweb.selectors.debug_mode
 
 You'll also find some other (very) specific selectors hidden in other modules
 than :mod:`cubicweb.selectors`.
--- a/doc/book/en/intro/concepts.rst	Wed Oct 13 08:37:09 2010 +0200
+++ b/doc/book/en/intro/concepts.rst	Wed Oct 13 08:37:21 2010 +0200
@@ -32,7 +32,7 @@
 
 On a Unix system, the available cubes are usually stored in the directory
 :file:`/usr/share/cubicweb/cubes`. If you're using the cubicweb forest
-(:ref:SourceInstallation), the cubes are searched in the directory
+(:ref:`SourceInstallation`), the cubes are searched in the directory
 :file:`/path/to/cubicweb_forest/cubes`. The environment variable
 :envvar:`CW_CUBES_PATH` gives additionnal locations where to search for cubes.
 
--- a/entities/__init__.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/entities/__init__.py	Wed Oct 13 08:37:21 2010 +0200
@@ -35,6 +35,11 @@
     __regid__ = 'Any'
     __implements__ = ()
 
+    @classmethod
+    def cw_create_url(cls, req, **kwargs):
+        """ return the url of the entity creation form for this entity type"""
+        return req.build_url('add/%s' % cls.__regid__, **kwargs)
+
     # meta data api ###########################################################
 
     def dc_title(self):
--- a/entities/adapters.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/entities/adapters.py	Wed Oct 13 08:37:21 2010 +0200
@@ -28,7 +28,8 @@
 from logilab.common.decorators import cached
 
 from cubicweb.view import EntityAdapter, implements_adapter_compat
-from cubicweb.selectors import implements, is_instance, relation_possible
+from cubicweb.selectors import (implements, is_instance, relation_possible,
+                                match_exception)
 from cubicweb.interfaces import IDownloadable, ITree, IProgress, IMileStone
 
 
@@ -463,3 +464,24 @@
     def contractors(self):
         """returns the list of persons supposed to work on this task"""
         raise NotImplementedError
+
+
+# error handling adapters ######################################################
+
+from cubicweb import UniqueTogetherError
+
+class IUserFriendlyError(EntityAdapter):
+    __regid__ = 'IUserFriendlyError'
+    __abstract__ = True
+    def __init__(self, *args, **kwargs):
+        self.exc = kwargs.pop('exc')
+        super(IUserFriendlyError, self).__init__(*args, **kwargs)
+
+
+class IUserFriendlyUniqueTogether(IUserFriendlyError):
+    __select__ = match_exception(UniqueTogetherError)
+    def raise_user_exception(self):
+        etype, rtypes = self.exc.args
+        msg = self._cw._('violates unique_together constraints (%s)') % (
+            ', '.join(self._cw._(rtypes)))
+        raise ValidationError(self.entity.eid, dict((col, msg) for col in rtypes))
--- a/entities/schemaobjs.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/entities/schemaobjs.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,12 +15,15 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""schema definition related entities
+"""schema definition related entities"""
 
-"""
 __docformat__ = "restructuredtext en"
 
+import re
+from socket import gethostname
+
 from logilab.common.decorators import cached
+from logilab.common.textutils import text_to_dict
 
 from yams.schema import role_name
 
@@ -30,6 +33,41 @@
 from cubicweb.entities import AnyEntity, fetch_config
 
 
+
+class CWSource(AnyEntity):
+    __regid__ = 'CWSource'
+    fetch_attrs, fetch_order = fetch_config(['name', 'type'])
+
+    @property
+    def dictconfig(self):
+        return self.config and text_to_dict(self.config) or {}
+
+    @property
+    def host_config(self):
+        dictconfig = self.dictconfig
+        host = gethostname()
+        for hostcfg in self.host_configs:
+            if hostcfg.match(hostname):
+                dictconfig.update(hostcfg.dictconfig)
+        return dictconfig
+
+    @property
+    def host_configs(self):
+        return self.reverse_cw_host_config_of
+
+
+class CWSourceHostConfig(AnyEntity):
+    __regid__ = 'CWSourceHostConfig'
+    fetch_attrs, fetch_order = fetch_config(['match_host', 'config'])
+
+    @property
+    def dictconfig(self):
+        return self.config and text_to_dict(self.config) or {}
+
+    def match(self, hostname):
+        return re.match(self.match_host, hostname)
+
+
 class CWEType(AnyEntity):
     __regid__ = 'CWEType'
     fetch_attrs, fetch_order = fetch_config(['name'])
--- a/entity.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/entity.py	Wed Oct 13 08:37:21 2010 +0200
@@ -19,7 +19,6 @@
 
 __docformat__ = "restructuredtext en"
 
-from copy import copy
 from warnings import warn
 
 from logilab.common import interface
@@ -313,6 +312,9 @@
         return '<Entity %s %s %s at %s>' % (
             self.e_schema, self.eid, self.cw_attr_cache.keys(), id(self))
 
+    def __cmp__(self, other):
+        raise NotImplementedError('comparison not implemented for %s' % self.__class__)
+
     def __json_encode__(self):
         """custom json dumps hook to dump the entity's eid
         which is not part of dict structure itself
@@ -321,107 +323,6 @@
         dumpable['eid'] = self.eid
         return dumpable
 
-    def __nonzero__(self):
-        return True
-
-    def __hash__(self):
-        return id(self)
-
-    def __cmp__(self, other):
-        raise NotImplementedError('comparison not implemented for %s' % self.__class__)
-
-    def __contains__(self, key):
-        return key in self.cw_attr_cache
-
-    def __iter__(self):
-        return iter(self.cw_attr_cache)
-
-    def __getitem__(self, key):
-        if key == 'eid':
-            warn('[3.7] entity["eid"] is deprecated, use entity.eid instead',
-                 DeprecationWarning, stacklevel=2)
-            return self.eid
-        return self.cw_attr_cache[key]
-
-    def __setitem__(self, attr, value):
-        """override __setitem__ to update self.edited_attributes.
-
-        Typically, a before_[update|add]_hook could do::
-
-            entity['generated_attr'] = generated_value
-
-        and this way, edited_attributes will be updated accordingly. Also, add
-        the attribute to skip_security since we don't want to check security
-        for such attributes set by hooks.
-        """
-        if attr == 'eid':
-            warn('[3.7] entity["eid"] = value is deprecated, use entity.eid = value instead',
-                 DeprecationWarning, stacklevel=2)
-            self.eid = value
-        else:
-            self.cw_attr_cache[attr] = value
-            # don't add attribute into skip_security if already in edited
-            # attributes, else we may accidentaly skip a desired security check
-            if hasattr(self, 'edited_attributes') and \
-                   attr not in self.edited_attributes:
-                self.edited_attributes.add(attr)
-                self._cw_skip_security_attributes.add(attr)
-
-    def __delitem__(self, attr):
-        """override __delitem__ to update self.edited_attributes on cleanup of
-        undesired changes introduced in the entity's dict. For example, see the
-        code snippet below from the `forge` cube:
-
-        .. sourcecode:: python
-
-            edited = self.entity.edited_attributes
-            has_load_left = 'load_left' in edited
-            if 'load' in edited and self.entity.load_left is None:
-                self.entity.load_left = self.entity['load']
-            elif not has_load_left and edited:
-                # cleanup, this may cause undesired changes
-                del self.entity['load_left']
-
-        """
-        del self.cw_attr_cache[attr]
-        if hasattr(self, 'edited_attributes'):
-            self.edited_attributes.remove(attr)
-
-    def clear(self):
-        self.cw_attr_cache.clear()
-
-    def get(self, key, default=None):
-        return self.cw_attr_cache.get(key, default)
-
-    def setdefault(self, attr, default):
-        """override setdefault to update self.edited_attributes"""
-        value = self.cw_attr_cache.setdefault(attr, default)
-        # don't add attribute into skip_security if already in edited
-        # attributes, else we may accidentaly skip a desired security check
-        if hasattr(self, 'edited_attributes') and \
-               attr not in self.edited_attributes:
-            self.edited_attributes.add(attr)
-            self._cw_skip_security_attributes.add(attr)
-        return value
-
-    def pop(self, attr, default=_marker):
-        """override pop to update self.edited_attributes on cleanup of
-        undesired changes introduced in the entity's dict. See `__delitem__`
-        """
-        if default is _marker:
-            value = self.cw_attr_cache.pop(attr)
-        else:
-            value = self.cw_attr_cache.pop(attr, default)
-        if hasattr(self, 'edited_attributes') and attr in self.edited_attributes:
-            self.edited_attributes.remove(attr)
-        return value
-
-    def update(self, values):
-        """override update to update self.edited_attributes. See `__setitem__`
-        """
-        for attr, value in values.items():
-            self[attr] = value # use self.__setitem__ implementation
-
     def cw_adapt_to(self, interface):
         """return an adapter the entity to the given interface name.
 
@@ -592,12 +493,6 @@
 
     # entity cloning ##########################################################
 
-    def cw_copy(self):
-        thecopy = copy(self)
-        thecopy.cw_attr_cache = copy(self.cw_attr_cache)
-        thecopy._cw_related_cache = {}
-        return thecopy
-
     def copy_relations(self, ceid): # XXX cw_copy_relations
         """copy relations of the object with the given eid on this
         object (this method is called on the newly created copy, and
@@ -682,7 +577,7 @@
             rdef = rschema.rdef(self.e_schema, attrschema)
             if not self._cw.user.matching_groups(rdef.get_groups('read')) \
                    or (attrschema.type == 'Password' and skip_pwd):
-                self[attr] = None
+                self.cw_attr_cache[attr] = None
                 continue
             yield attr
 
@@ -741,7 +636,7 @@
             rset = self._cw.execute(rql, {'x': self.eid}, build_descr=False)[0]
             # handle attributes
             for i in xrange(1, lastattr):
-                self[str(selected[i-1][0])] = rset[i]
+                self.cw_attr_cache[str(selected[i-1][0])] = rset[i]
             # handle relations
             for i in xrange(lastattr, len(rset)):
                 rtype, role = selected[i-1][0]
@@ -761,7 +656,7 @@
         :param name: name of the attribute to get
         """
         try:
-            value = self.cw_attr_cache[name]
+            return self.cw_attr_cache[name]
         except KeyError:
             if not self.cw_is_saved():
                 return None
@@ -769,21 +664,20 @@
             try:
                 rset = self._cw.execute(rql, {'x': self.eid})
             except Unauthorized:
-                self[name] = value = None
+                self.cw_attr_cache[name] = value = None
             else:
                 assert rset.rowcount <= 1, (self, rql, rset.rowcount)
                 try:
-                    self[name] = value = rset.rows[0][0]
+                    self.cw_attr_cache[name] = value = rset.rows[0][0]
                 except IndexError:
                     # probably a multisource error
                     self.critical("can't get value for attribute %s of entity with eid %s",
                                   name, self.eid)
                     if self.e_schema.destination(name) == 'String':
-                        # XXX (syt) imo emtpy string is better
-                        self[name] = value = self._cw._('unaccessible')
+                        self.cw_attr_cache[name] = value = self._cw._('unaccessible')
                     else:
-                        self[name] = value = None
-        return value
+                        self.cw_attr_cache[name] = value = None
+            return value
 
     def related(self, rtype, role='subject', limit=None, entities=False): # XXX .cw_related
         """returns a resultset of related entities
@@ -987,7 +881,6 @@
         you should override this method to clear them as well.
         """
         # clear attributes cache
-        haseid = 'eid' in self
         self._cw_completed = False
         self.cw_attr_cache.clear()
         # clear relations cache
@@ -1014,9 +907,9 @@
                          kwargs)
         kwargs.pop('x')
         # update current local object _after_ the rql query to avoid
-        # interferences between the query execution itself and the
-        # edited_attributes / skip_security_attributes machinery
-        self.update(kwargs)
+        # interferences between the query execution itself and the cw_edited /
+        # skip_security machinery
+        self.cw_attr_cache.update(kwargs)
 
     def set_relations(self, **kwargs): # XXX cw_set_relations
         """add relations to the given object. To set a relation where this entity
@@ -1047,58 +940,13 @@
         self._cw.execute('DELETE %s X WHERE X eid %%(x)s' % self.e_schema,
                          {'x': self.eid}, **kwargs)
 
-    # server side utilities ###################################################
-
-    def _cw_rql_set_value(self, attr, value):
-        """call by rql execution plan when some attribute is modified
-
-        don't use dict api in such case since we don't want attribute to be
-        added to skip_security_attributes.
-
-        This method is for internal use, you should not use it.
-        """
-        self.cw_attr_cache[attr] = value
+    # server side utilities ####################################################
 
     def _cw_clear_local_perm_cache(self, action):
         for rqlexpr in self.e_schema.get_rqlexprs(action):
             self._cw.local_perm_cache.pop((rqlexpr.eid, (('x', self.eid),)), None)
 
-    @property
-    def _cw_skip_security_attributes(self):
-        try:
-            return self.__cw_skip_security_attributes
-        except:
-            self.__cw_skip_security_attributes = set()
-            return self.__cw_skip_security_attributes
-
-    def _cw_set_defaults(self):
-        """set default values according to the schema"""
-        for attr, value in self.e_schema.defaults():
-            if not self.cw_attr_cache.has_key(attr):
-                self[str(attr)] = value
-
-    def _cw_check(self, creation=False):
-        """check this entity against its schema. Only final relation
-        are checked here, constraint on actual relations are checked in hooks
-        """
-        # necessary since eid is handled specifically and yams require it to be
-        # in the dictionary
-        if self._cw is None:
-            _ = unicode
-        else:
-            _ = self._cw._
-        if creation:
-            # on creations, we want to check all relations, especially
-            # required attributes
-            relations = [rschema for rschema in self.e_schema.subject_relations()
-                         if rschema.final and rschema.type != 'eid']
-        elif hasattr(self, 'edited_attributes'):
-            relations = [self._cw.vreg.schema.rschema(rtype)
-                         for rtype in self.edited_attributes]
-        else:
-            relations = None
-        self.e_schema.check(self, creation=creation, _=_,
-                            relations=relations)
+    # deprecated stuff #########################################################
 
     @deprecated('[3.9] use entity.cw_attr_value(attr)')
     def get_value(self, name):
@@ -1128,6 +976,109 @@
     def related_rql(self, rtype, role='subject', targettypes=None):
         return self.cw_related_rql(rtype, role, targettypes)
 
+    @property
+    @deprecated('[3.10] use entity.cw_edited')
+    def edited_attributes(self):
+        return self.cw_edited
+
+    @property
+    @deprecated('[3.10] use entity.cw_edited.skip_security')
+    def skip_security_attributes(self):
+        return self.cw_edited.skip_security
+
+    @property
+    @deprecated('[3.10] use entity.cw_edited.skip_security')
+    def _cw_skip_security_attributes(self):
+        return self.cw_edited.skip_security
+
+    @property
+    @deprecated('[3.10] use entity.cw_edited.skip_security')
+    def querier_pending_relations(self):
+        return self.cw_edited.querier_pending_relations
+
+    @deprecated('[3.10] use key in entity.cw_attr_cache')
+    def __contains__(self, key):
+        return key in self.cw_attr_cache
+
+    @deprecated('[3.10] iter on entity.cw_attr_cache')
+    def __iter__(self):
+        return iter(self.cw_attr_cache)
+
+    @deprecated('[3.10] use entity.cw_attr_cache[attr]')
+    def __getitem__(self, key):
+        if key == 'eid':
+            warn('[3.7] entity["eid"] is deprecated, use entity.eid instead',
+                 DeprecationWarning, stacklevel=2)
+            return self.eid
+        return self.cw_attr_cache[key]
+
+    @deprecated('[3.10] use entity.cw_attr_cache.get(attr[, default])')
+    def get(self, key, default=None):
+        return self.cw_attr_cache.get(key, default)
+
+    @deprecated('[3.10] use entity.cw_attr_cache.clear()')
+    def clear(self):
+        self.cw_attr_cache.clear()
+        # XXX clear cw_edited ?
+
+    @deprecated('[3.10] use entity.cw_edited[attr] = value or entity.cw_attr_cache[attr] = value')
+    def __setitem__(self, attr, value):
+        """override __setitem__ to update self.cw_edited.
+
+        Typically, a before_[update|add]_hook could do::
+
+            entity['generated_attr'] = generated_value
+
+        and this way, cw_edited will be updated accordingly. Also, add
+        the attribute to skip_security since we don't want to check security
+        for such attributes set by hooks.
+        """
+        if attr == 'eid':
+            warn('[3.7] entity["eid"] = value is deprecated, use entity.eid = value instead',
+                 DeprecationWarning, stacklevel=2)
+            self.eid = value
+        else:
+            try:
+                self.cw_edited[attr] = value
+            except AttributeError:
+                self.cw_attr_cache[attr] = value
+
+    @deprecated('[3.10] use del entity.cw_edited[attr]')
+    def __delitem__(self, attr):
+        """override __delitem__ to update self.cw_edited on cleanup of
+        undesired changes introduced in the entity's dict. For example, see the
+        code snippet below from the `forge` cube:
+
+        .. sourcecode:: python
+
+            edited = self.entity.cw_edited
+            has_load_left = 'load_left' in edited
+            if 'load' in edited and self.entity.load_left is None:
+                self.entity.load_left = self.entity['load']
+            elif not has_load_left and edited:
+                # cleanup, this may cause undesired changes
+                del self.entity['load_left']
+        """
+        del self.cw_edited[attr]
+
+    @deprecated('[3.10] use entity.cw_edited.setdefault(attr, default)')
+    def setdefault(self, attr, default):
+        """override setdefault to update self.cw_edited"""
+        return self.cw_edited.setdefault(attr, default)
+
+    @deprecated('[3.10] use entity.cw_edited.pop(attr[, default])')
+    def pop(self, attr, *args):
+        """override pop to update self.cw_edited on cleanup of
+        undesired changes introduced in the entity's dict. See `__delitem__`
+        """
+        return self.cw_edited.pop(attr, *args)
+
+    @deprecated('[3.10] use entity.cw_edited.update(values)')
+    def update(self, values):
+        """override update to update self.cw_edited. See `__setitem__`
+        """
+        self.cw_edited.update(values)
+
 
 # attribute and relation descriptors ##########################################
 
@@ -1143,8 +1094,9 @@
             return self
         return eobj.cw_attr_value(self._attrname)
 
+    @deprecated('[3.10] use entity.cw_attr_cache[attr] = value')
     def __set__(self, eobj, value):
-        eobj[self._attrname] = value
+        eobj.cw_attr_cache[self._attrname] = value
 
 
 class Relation(object):
--- a/etwist/twconfig.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/etwist/twconfig.py	Wed Oct 13 08:37:21 2010 +0200
@@ -76,12 +76,6 @@
 the repository rather than the user running the command',
           'group': 'main', 'level': WebConfiguration.mode == 'system'
           }),
-        ('session-time',
-         {'type' : 'time',
-          'default': '30min',
-          'help': 'session expiration time, default to 30 minutes',
-          'group': 'main', 'level': 1,
-          }),
         ('pyro-server',
          {'type' : 'yn',
           # pyro is only a recommends by default, so don't activate it here
--- a/hooks/integrity.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/integrity.py	Wed Oct 13 08:37:21 2010 +0200
@@ -17,8 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Core hooks: check for data integrity according to the instance'schema
 validity
+"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from threading import Lock
@@ -31,7 +31,6 @@
 from cubicweb.selectors import is_instance
 from cubicweb.uilib import soup2xhtml
 from cubicweb.server import hook
-from cubicweb.server.hook import set_operation
 
 # special relations that don't have to be checked for integrity, usually
 # because they are handled internally by hooks (so we trust ourselves)
@@ -62,27 +61,27 @@
         _UNIQUE_CONSTRAINTS_LOCK.release()
 
 class _ReleaseUniqueConstraintsOperation(hook.Operation):
-    def commit_event(self):
-        pass
     def postcommit_event(self):
         _release_unique_cstr_lock(self.session)
     def rollback_event(self):
         _release_unique_cstr_lock(self.session)
 
 
-class _CheckRequiredRelationOperation(hook.LateOperation):
-    """checking relation cardinality has to be done after commit in
-    case the relation is being replaced
+class _CheckRequiredRelationOperation(hook.DataOperationMixIn,
+                                      hook.LateOperation):
+    """checking relation cardinality has to be done after commit in case the
+    relation is being replaced
     """
+    containercls = list
     role = key = base_rql = None
 
     def precommit_event(self):
-        session =self.session
+        session = self.session
         pendingeids = session.transaction_data.get('pendingeids', ())
         pendingrtypes = session.transaction_data.get('pendingrtypes', ())
         # poping key is not optional: if further operation trigger new deletion
         # of relation, we'll need a new operation
-        for eid, rtype in session.transaction_data.pop(self.key):
+        for eid, rtype in self.get_data():
             # recheck pending eids / relation types
             if eid in pendingeids:
                 continue
@@ -100,13 +99,11 @@
 class _CheckSRelationOp(_CheckRequiredRelationOperation):
     """check required subject relation"""
     role = 'subject'
-    key = '_cwisrel'
     base_rql = 'Any O WHERE S eid %%(x)s, S %s O'
 
 class _CheckORelationOp(_CheckRequiredRelationOperation):
     """check required object relation"""
     role = 'object'
-    key = '_cwiorel'
     base_rql = 'Any S WHERE O eid %%(x)s, S %s O'
 
 
@@ -133,11 +130,10 @@
             rdef = rschema.role_rdef(eschema, targetschemas[0], role)
             if rdef.role_cardinality(role) in '1+':
                 if role == 'subject':
-                    set_operation(self._cw, '_cwisrel', (eid, rschema.type),
-                                  _CheckSRelationOp, list)
+                    op = _CheckSRelationOp.get_instance(self._cw)
                 else:
-                    set_operation(self._cw, '_cwiorel', (eid, rschema.type),
-                                  _CheckORelationOp, list)
+                    op = _CheckORelationOp.get_instance(self._cw)
+                op.add_data((eid, rschema.type))
 
     def before_delete_relation(self):
         rtype = self.rtype
@@ -150,19 +146,17 @@
             return
         card = session.schema_rproperty(rtype, eidfrom, eidto, 'cardinality')
         if card[0] in '1+' and not session.deleted_in_transaction(eidfrom):
-            set_operation(self._cw, '_cwisrel', (eidfrom, rtype),
-                          _CheckSRelationOp, list)
+            _CheckSRelationOp.get_instance(self._cw).add_data((eidfrom, rtype))
         if card[1] in '1+' and not session.deleted_in_transaction(eidto):
-            set_operation(self._cw, '_cwiorel', (eidto, rtype),
-                          _CheckORelationOp, list)
+            _CheckORelationOp.get_instance(self._cw).add_data((eidto, rtype))
 
 
-class _CheckConstraintsOp(hook.LateOperation):
+class _CheckConstraintsOp(hook.DataOperationMixIn, hook.LateOperation):
     """ check a new relation satisfy its constraints """
-
+    containercls = list
     def precommit_event(self):
         session = self.session
-        for values in session.transaction_data.pop('check_constraints_op'):
+        for values in self.get_data():
             eidfrom, rtype, eidto, constraints = values
             # first check related entities have not been deleted in the same
             # transaction
@@ -183,9 +177,6 @@
                     self.critical('can\'t check constraint %s, not supported',
                                   constraint)
 
-    def commit_event(self):
-        pass
-
 
 class CheckConstraintHook(IntegrityHook):
     """check the relation satisfy its constraints
@@ -201,9 +192,8 @@
         constraints = self._cw.schema_rproperty(self.rtype, self.eidfrom, self.eidto,
                                                 'constraints')
         if constraints:
-            hook.set_operation(self._cw, 'check_constraints_op',
-                               (self.eidfrom, self.rtype, self.eidto, tuple(constraints)),
-                               _CheckConstraintsOp, list)
+            _CheckConstraintsOp.get_instance(self._cw).add_data(
+                (self.eidfrom, self.rtype, self.eidto, constraints))
 
 
 class CheckAttributeConstraintHook(IntegrityHook):
@@ -217,14 +207,13 @@
 
     def __call__(self):
         eschema = self.entity.e_schema
-        for attr in self.entity.edited_attributes:
+        for attr in self.entity.cw_edited:
             if eschema.subjrels[attr].final:
                 constraints = [c for c in eschema.rdef(attr).constraints
                                if isinstance(c, (RQLUniqueConstraint, RQLConstraint))]
                 if constraints:
-                    hook.set_operation(self._cw, 'check_constraints_op',
-                                       (self.entity.eid, attr, None, tuple(constraints)),
-                                       _CheckConstraintsOp, list)
+                    _CheckConstraintsOp.get_instance(self._cw).add_data(
+                        (self.entity.eid, attr, None, constraints))
 
 
 class CheckUniqueHook(IntegrityHook):
@@ -234,9 +223,8 @@
     def __call__(self):
         entity = self.entity
         eschema = entity.e_schema
-        for attr in entity.edited_attributes:
+        for attr, val in entity.cw_edited.iteritems():
             if eschema.subjrels[attr].final and eschema.has_unique_values(attr):
-                val = entity[attr]
                 if val is None:
                     continue
                 rql = '%s X WHERE X %s %%(val)s' % (entity.e_schema, attr)
@@ -255,18 +243,17 @@
     events = ('before_delete_entity', 'before_update_entity')
 
     def __call__(self):
-        if self.event == 'before_delete_entity' and self.entity.name == 'owners':
+        entity = self.entity
+        if self.event == 'before_delete_entity' and entity.name == 'owners':
             msg = self._cw._('can\'t be deleted')
-            raise ValidationError(self.entity.eid, {None: msg})
-        elif self.event == 'before_update_entity' and \
-                 'name' in self.entity.edited_attributes:
-            newname = self.entity.pop('name')
-            oldname = self.entity.name
+            raise ValidationError(entity.eid, {None: msg})
+        elif self.event == 'before_update_entity' \
+                 and 'name' in entity.cw_edited:
+            oldname, newname = entity.cw_edited.oldnewvalue('name')
             if oldname == 'owners' and newname != oldname:
                 qname = role_name('name', 'subject')
                 msg = self._cw._('can\'t be changed')
-                raise ValidationError(self.entity.eid, {qname: msg})
-            self.entity['name'] = newname
+                raise ValidationError(entity.eid, {qname: msg})
 
 
 class TidyHtmlFields(IntegrityHook):
@@ -277,15 +264,16 @@
     def __call__(self):
         entity = self.entity
         metaattrs = entity.e_schema.meta_attributes()
+        edited = entity.cw_edited
         for metaattr, (metadata, attr) in metaattrs.iteritems():
-            if metadata == 'format' and attr in entity.edited_attributes:
+            if metadata == 'format' and attr in edited:
                 try:
-                    value = entity[attr]
+                    value = edited[attr]
                 except KeyError:
                     continue # no text to tidy
                 if isinstance(value, unicode): # filter out None and Binary
                     if getattr(entity, str(metaattr)) == 'text/html':
-                        entity[attr] = soup2xhtml(value, self._cw.encoding)
+                        edited[attr] = soup2xhtml(value, self._cw.encoding)
 
 
 class StripCWUserLoginHook(IntegrityHook):
@@ -295,19 +283,19 @@
     events = ('before_add_entity', 'before_update_entity',)
 
     def __call__(self):
-        user = self.entity
-        if 'login' in user.edited_attributes and user.login:
-            user.login = user.login.strip()
+        login = self.entity.cw_edited.get('login')
+        if login:
+            self.entity.cw_edited['login'] = login.strip()
 
 
 # 'active' integrity hooks: you usually don't want to deactivate them, they are
 # not really integrity check, they maintain consistency on changes
 
-class _DelayedDeleteOp(hook.Operation):
+class _DelayedDeleteOp(hook.DataOperationMixIn, hook.Operation):
     """delete the object of composite relation except if the relation has
     actually been redirected to another composite
     """
-    key = base_rql = None
+    base_rql = None
 
     def precommit_event(self):
         session = self.session
@@ -315,7 +303,7 @@
         neweids = session.transaction_data.get('neweids', ())
         # poping key is not optional: if further operation trigger new deletion
         # of composite relation, we'll need a new operation
-        for eid, rtype in session.transaction_data.pop(self.key):
+        for eid, rtype in self.get_data():
             # don't do anything if the entity is being created or deleted
             if not (eid in pendingeids or eid in neweids):
                 etype = session.describe(eid)[0]
@@ -323,12 +311,10 @@
 
 class _DelayedDeleteSEntityOp(_DelayedDeleteOp):
     """delete orphan subject entity of a composite relation"""
-    key = '_cwiscomp'
     base_rql = 'DELETE %s X WHERE X eid %%(x)s, NOT X %s Y'
 
 class _DelayedDeleteOEntityOp(_DelayedDeleteOp):
     """check required object relation"""
-    key = '_cwiocomp'
     base_rql = 'DELETE %s X WHERE X eid %%(x)s, NOT Y %s X'
 
 
@@ -349,8 +335,8 @@
         composite = self._cw.schema_rproperty(self.rtype, self.eidfrom, self.eidto,
                                               'composite')
         if composite == 'subject':
-            set_operation(self._cw, '_cwiocomp', (self.eidto, self.rtype),
-                          _DelayedDeleteOEntityOp)
+            _DelayedDeleteOEntityOp.get_instance(self._cw).add_data(
+                (self.eidto, self.rtype))
         elif composite == 'object':
-            set_operation(self._cw, '_cwiscomp', (self.eidfrom, self.rtype),
-                          _DelayedDeleteSEntityOp)
+            _DelayedDeleteSEntityOp.get_instance(self._cw).add_data(
+                (self.eidfrom, self.rtype))
--- a/hooks/metadata.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/metadata.py	Wed Oct 13 08:37:21 2010 +0200
@@ -23,7 +23,6 @@
 
 from cubicweb.selectors import is_instance
 from cubicweb.server import hook
-from cubicweb.server.utils import eschema_eid
 
 
 class MetaDataHook(hook.Hook):
@@ -41,11 +40,12 @@
 
     def __call__(self):
         timestamp = datetime.now()
-        self.entity.setdefault('creation_date', timestamp)
-        self.entity.setdefault('modification_date', timestamp)
+        edited = self.entity.cw_edited
+        edited.setdefault('creation_date', timestamp)
+        edited.setdefault('modification_date', timestamp)
         if not self._cw.get_shared_data('do-not-insert-cwuri'):
             cwuri = u'%seid/%s' % (self._cw.base_url(), self.entity.eid)
-            self.entity.setdefault('cwuri', cwuri)
+            edited.setdefault('cwuri', cwuri)
 
 
 class UpdateMetaAttrsHook(MetaDataHook):
@@ -60,14 +60,14 @@
         # XXX to be really clean, we should turn off modification_date update
         # explicitly on each command where we do not want that behaviour.
         if not self._cw.vreg.config.repairing:
-            self.entity.setdefault('modification_date', datetime.now())
+            self.entity.cw_edited.setdefault('modification_date', datetime.now())
 
 
-class _SetCreatorOp(hook.Operation):
+class SetCreatorOp(hook.DataOperationMixIn, hook.Operation):
 
     def precommit_event(self):
         session = self.session
-        for eid in session.transaction_data.pop('set_creator_op'):
+        for eid in self.get_data():
             if session.deleted_in_transaction(eid):
                 # entity have been created and deleted in the same transaction
                 continue
@@ -76,30 +76,6 @@
                 session.add_relation(eid, 'created_by', session.user.eid)
 
 
-class SetIsHook(MetaDataHook):
-    """create a new entity -> set is and is_instance_of relations
-
-    those relations are inserted using sql so they are not hookable.
-    """
-    __regid__ = 'setis'
-    events = ('after_add_entity',)
-
-    def __call__(self):
-        if hasattr(self.entity, '_cw_recreating'):
-            return
-        session = self._cw
-        entity = self.entity
-        try:
-            session.system_sql('INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)'
-                           % (entity.eid, eschema_eid(session, entity.e_schema)))
-        except IndexError:
-            # during schema serialization, skip
-            return
-        for eschema in entity.e_schema.ancestors() + [entity.e_schema]:
-            session.system_sql('INSERT INTO is_instance_of_relation(eid_from,eid_to) VALUES (%s,%s)'
-                               % (entity.eid, eschema_eid(session, eschema)))
-
-
 class SetOwnershipHook(MetaDataHook):
     """create a new entity -> set owner and creator metadata"""
     __regid__ = 'setowner'
@@ -108,11 +84,12 @@
     def __call__(self):
         if not self._cw.is_internal_session:
             self._cw.add_relation(self.entity.eid, 'owned_by', self._cw.user.eid)
-            hook.set_operation(self._cw, 'set_creator_op', self.entity.eid, _SetCreatorOp)
+            SetCreatorOp.get_instance(self._cw).add_data(self.entity.eid)
+
 
-class _SyncOwnersOp(hook.Operation):
+class SyncOwnersOp(hook.DataOperationMixIn, hook.Operation):
     def precommit_event(self):
-        for compositeeid, composedeid in self.session.transaction_data.pop('sync_owners_op'):
+        for compositeeid, composedeid in self.get_data():
             self.session.execute('SET X owned_by U WHERE C owned_by U, C eid %(c)s,'
                                  'NOT EXISTS(X owned_by U, X eid %(x)s)',
                                  {'c': compositeeid, 'x': composedeid})
@@ -132,9 +109,9 @@
         eidfrom, eidto = self.eidfrom, self.eidto
         composite = self._cw.schema_rproperty(self.rtype, eidfrom, eidto, 'composite')
         if composite == 'subject':
-            hook.set_operation(self._cw, 'sync_owners_op', (eidfrom, eidto), _SyncOwnersOp)
+            SyncOwnersOp.get_instance(self._cw).add_data( (eidfrom, eidto) )
         elif composite == 'object':
-            hook.set_operation(self._cw, 'sync_owners_op', (eidto, eidfrom), _SyncOwnersOp)
+            SyncOwnersOp.get_instance(self._cw).add_data( (eidto, eidfrom) )
 
 
 class FixUserOwnershipHook(MetaDataHook):
--- a/hooks/notification.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/notification.py	Wed Oct 13 08:37:21 2010 +0200
@@ -125,7 +125,7 @@
         if session.added_in_transaction(self.entity.eid):
             return # entity is being created
         # then compute changes
-        attrs = [k for k in self.entity.edited_attributes
+        attrs = [k for k in self.entity.cw_edited
                  if not k in self.skip_attrs]
         if not attrs:
             return
@@ -140,7 +140,7 @@
         rset = session.execute(rql, {'x': self.entity.eid})
         for i, attr in enumerate(attrs):
             oldvalue = rset[0][i]
-            newvalue = self.entity[attr]
+            newvalue = self.entity.cw_edited[attr]
             if oldvalue != newvalue:
                 thisentitychanges.add((attr, oldvalue, newvalue))
         if thisentitychanges:
@@ -168,8 +168,9 @@
             if self._cw.added_in_transaction(self.entity.eid):
                 return False
             if self.entity.e_schema == 'CWUser':
-                if not (self.entity.edited_attributes - frozenset(('eid', 'modification_date',
-                                                                   'last_login_time'))):
+                if not (frozenset(self.entity.cw_edited)
+                        - frozenset(('eid', 'modification_date',
+                                     'last_login_time'))):
                     # don't record last_login_time update which are done
                     # automatically at login time
                     return False
--- a/hooks/security.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/security.py	Wed Oct 13 08:37:21 2010 +0200
@@ -31,12 +31,9 @@
     eschema = entity.e_schema
     # ._cw_skip_security_attributes is there to bypass security for attributes
     # set by hooks by modifying the entity's dictionnary
-    dontcheck = entity._cw_skip_security_attributes
     if editedattrs is None:
-        try:
-            editedattrs = entity.edited_attributes
-        except AttributeError:
-            editedattrs = entity # XXX unexpected
+        editedattrs = entity.cw_edited
+    dontcheck = editedattrs.skip_security
     for attr in editedattrs:
         if attr in dontcheck:
             continue
@@ -46,39 +43,26 @@
             if creation and not rdef.permissions.get('update'):
                 continue
             rdef.check_perm(session, 'update', eid=eid)
-    # don't update dontcheck until everything went fine: see usage in
-    # after_update_entity, where if we got an Unauthorized at hook time, we will
-    # retry and commit time
-    dontcheck |= frozenset(editedattrs)
 
 
-class _CheckEntityPermissionOp(hook.LateOperation):
+class CheckEntityPermissionOp(hook.DataOperationMixIn, hook.LateOperation):
     def precommit_event(self):
-        #print 'CheckEntityPermissionOp', self.session.user, self.entity, self.action
         session = self.session
-        for values in session.transaction_data.pop('check_entity_perm_op'):
-            entity = session.entity_from_eid(values[0])
-            action = values[1]
+        for eid, action, edited in self.get_data():
+            entity = session.entity_from_eid(eid)
             entity.cw_check_perm(action)
-            check_entity_attributes(session, entity, values[2:],
-                                    creation=self.creation)
-
-    def commit_event(self):
-        pass
+            check_entity_attributes(session, entity, edited,
+                                    creation=(action == 'add'))
 
 
-class _CheckRelationPermissionOp(hook.LateOperation):
+class CheckRelationPermissionOp(hook.DataOperationMixIn, hook.LateOperation):
     def precommit_event(self):
         session = self.session
-        for args in session.transaction_data.pop('check_relation_perm_op'):
-            action, rschema, eidfrom, eidto = args
+        for action, rschema, eidfrom, eidto in self.get_data():
             rdef = rschema.rdef(session.describe(eidfrom)[0],
                                 session.describe(eidto)[0])
             rdef.check_perm(session, action, fromeid=eidfrom, toeid=eidto)
 
-    def commit_event(self):
-        pass
-
 
 @objectify_selector
 @lltrace
@@ -98,9 +82,8 @@
     events = ('after_add_entity',)
 
     def __call__(self):
-        hook.set_operation(self._cw, 'check_entity_perm_op',
-                           (self.entity.eid, 'add') + tuple(self.entity.edited_attributes),
-                           _CheckEntityPermissionOp, creation=True)
+        CheckEntityPermissionOp.get_instance(self._cw).add_data(
+            (self.entity.eid, 'add', self.entity.cw_edited) )
 
 
 class AfterUpdateEntitySecurityHook(SecurityHook):
@@ -115,11 +98,10 @@
         except Unauthorized:
             self.entity._cw_clear_local_perm_cache('update')
             # save back editedattrs in case the entity is reedited later in the
-            # same transaction, which will lead to edited_attributes being
+            # same transaction, which will lead to cw_edited being
             # overwritten
-            hook.set_operation(self._cw, 'check_entity_perm_op',
-                               (self.entity.eid, 'update') + tuple(self.entity.edited_attributes),
-                               _CheckEntityPermissionOp, creation=False)
+            CheckEntityPermissionOp.get_instance(self._cw).add_data(
+                (self.entity.eid, 'update', self.entity.cw_edited) )
 
 
 class BeforeDelEntitySecurityHook(SecurityHook):
@@ -156,9 +138,8 @@
                 return
             rschema = self._cw.repo.schema[self.rtype]
             if self.rtype in ON_COMMIT_ADD_RELATIONS:
-                hook.set_operation(self._cw, 'check_relation_perm_op',
-                                   ('add', rschema, self.eidfrom, self.eidto),
-                                   _CheckRelationPermissionOp)
+                CheckRelationPermissionOp.get_instance(self._cw).add_data(
+                    ('add', rschema, self.eidfrom, self.eidto) )
             else:
                 rdef = rschema.rdef(self._cw.describe(self.eidfrom)[0],
                                     self._cw.describe(self.eidto)[0])
--- a/hooks/syncschema.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/syncschema.py	Wed Oct 13 08:37:21 2010 +0200
@@ -121,14 +121,12 @@
 def check_valid_changes(session, entity, ro_attrs=('name', 'final')):
     errors = {}
     # don't use getattr(entity, attr), we would get the modified value if any
-    for attr in entity.edited_attributes:
+    for attr in entity.cw_edited:
         if attr in ro_attrs:
-            newval = entity.pop(attr)
-            origval = getattr(entity, attr)
+            origval, newval = entity.cw_edited.oldnewvalue(attr)
             if newval != origval:
                 errors[attr] = session._("can't change the %s attribute") % \
                                display_name(session, attr)
-            entity[attr] = newval
     if errors:
         raise ValidationError(entity.eid, errors)
 
@@ -259,7 +257,12 @@
         gmap = group_mapping(session)
         cmap = ss.cstrtype_mapping(session)
         for rtype in (META_RTYPES - VIRTUAL_RTYPES):
-            rschema = schema[rtype]
+            try:
+                rschema = schema[rtype]
+            except:
+                if rtype == 'cw_source':
+                    continue # XXX 3.10 migration
+                raise
             sampletype = rschema.subjects()[0]
             desttype = rschema.objects()[0]
             rdef = copy(rschema.rdef(sampletype, desttype))
@@ -309,11 +312,10 @@
             return # watched changes to final relation type are unexpected
         session = self.session
         if 'fulltext_container' in self.values:
+            op = UpdateFTIndexOp.get_instance(session)
             for subjtype, objtype in rschema.rdefs:
-                hook.set_operation(session, 'fti_update_etypes', subjtype,
-                                   UpdateFTIndexOp)
-                hook.set_operation(session, 'fti_update_etypes', objtype,
-                                   UpdateFTIndexOp)
+                op.add_data(subjtype)
+                op.add_data(objtype)
         # update the in-memory schema first
         self.oldvalues = dict( (attr, getattr(rschema, attr)) for attr in self.values)
         self.rschema.__dict__.update(self.values)
@@ -605,8 +607,7 @@
             syssource.update_rdef_null_allowed(self.session, rdef)
             self.null_allowed_changed = True
         if 'fulltextindexed' in self.values:
-            hook.set_operation(session, 'fti_update_etypes', rdef.subject,
-                               UpdateFTIndexOp)
+            UpdateFTIndexOp.get_instance(session).add_data(rdef.subject)
 
     def revertprecommit_event(self):
         if self.rdef is None:
@@ -902,7 +903,7 @@
 
     def __call__(self):
         entity = self.entity
-        if entity.get('final'):
+        if entity.cw_edited.get('final'):
             return
         CWETypeAddOp(self._cw, entity=entity)
 
@@ -916,8 +917,8 @@
         entity = self.entity
         check_valid_changes(self._cw, entity, ro_attrs=('final',))
         # don't use getattr(entity, attr), we would get the modified value if any
-        if 'name' in entity.edited_attributes:
-            oldname, newname = hook.entity_oldnewvalue(entity, 'name')
+        if 'name' in entity.cw_edited:
+            oldname, newname = entity.cw_edited.oldnewvalue('name')
             if newname.lower() != oldname.lower():
                 CWETypeRenameOp(self._cw, oldname=oldname, newname=newname)
 
@@ -960,8 +961,8 @@
         entity = self.entity
         rtypedef = ybo.RelationType(name=entity.name,
                                     description=entity.description,
-                                    inlined=entity.get('inlined', False),
-                                    symmetric=entity.get('symmetric', False),
+                                    inlined=entity.cw_edited.get('inlined', False),
+                                    symmetric=entity.cw_edited.get('symmetric', False),
                                     eid=entity.eid)
         MemSchemaCWRTypeAdd(self._cw, rtypedef=rtypedef)
 
@@ -976,10 +977,10 @@
         check_valid_changes(self._cw, entity)
         newvalues = {}
         for prop in ('symmetric', 'inlined', 'fulltext_container'):
-            if prop in entity.edited_attributes:
-                old, new = hook.entity_oldnewvalue(entity, prop)
+            if prop in entity.cw_edited:
+                old, new = entity.cw_edited.oldnewvalue(prop)
                 if old != new:
-                    newvalues[prop] = entity[prop]
+                    newvalues[prop] = new
         if newvalues:
             rschema = self._cw.vreg.schema.rschema(entity.name)
             CWRTypeUpdateOp(self._cw, rschema=rschema, entity=entity,
@@ -1064,8 +1065,8 @@
                 attr = 'ordernum'
             else:
                 attr = prop
-            if attr in entity.edited_attributes:
-                old, new = hook.entity_oldnewvalue(entity, attr)
+            if attr in entity.cw_edited:
+                old, new = entity.cw_edited.oldnewvalue(attr)
                 if old != new:
                     newvalues[prop] = new
         if newvalues:
@@ -1183,19 +1184,20 @@
 
 
 
-class UpdateFTIndexOp(hook.SingleLastOperation):
+class UpdateFTIndexOp(hook.DataOperationMixIn, hook.SingleLastOperation):
     """operation to update full text indexation of entity whose schema change
 
-    We wait after the commit to as the schema in memory is only updated after the commit.
+    We wait after the commit to as the schema in memory is only updated after
+    the commit.
     """
 
     def postcommit_event(self):
         session = self.session
         source = session.repo.system_source
-        to_reindex = session.transaction_data.pop('fti_update_etypes', ())
+        schema = session.repo.vreg.schema
+        to_reindex = self.get_data()
         self.info('%i etypes need full text indexed reindexation',
                   len(to_reindex))
-        schema = self.session.repo.vreg.schema
         for etype in to_reindex:
             rset = session.execute('Any X WHERE X is %s' % etype)
             self.info('Reindexing full text index for %i entity of type %s',
@@ -1207,8 +1209,8 @@
                     if still_fti or container is not entity:
                         source.fti_unindex_entity(session, container.eid)
                         source.fti_index_entity(session, container)
-        if len(to_reindex):
-            # Transaction have already been committed
+        if to_reindex:
+            # Transaction has already been committed
             session.pool.commit()
 
 
--- a/hooks/syncsession.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/syncsession.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,9 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Core hooks: synchronize living session on persistent data changes
+"""Core hooks: synchronize living session on persistent data changes"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from yams.schema import role_name
@@ -56,26 +55,25 @@
 
 class _DeleteGroupOp(_GroupOperation):
     """synchronize user when a in_group relation has been deleted"""
-    def commit_event(self):
+    def postcommit_event(self):
         """the observed connections pool has been commited"""
         groups = self.cnxuser.groups
         try:
             groups.remove(self.group)
         except KeyError:
             self.error('user %s not in group %s',  self.cnxuser, self.group)
-            return
 
 
 class _AddGroupOp(_GroupOperation):
     """synchronize user when a in_group relation has been added"""
-    def commit_event(self):
+    def postcommit_event(self):
         """the observed connections pool has been commited"""
         groups = self.cnxuser.groups
         if self.group in groups:
             self.warning('user %s already in group %s', self.cnxuser,
                          self.group)
-            return
-        groups.add(self.group)
+        else:
+            groups.add(self.group)
 
 
 class SyncInGroupHook(SyncSessionHook):
@@ -98,7 +96,7 @@
         self.cnxid = cnxid
         hook.Operation.__init__(self, session)
 
-    def commit_event(self):
+    def postcommit_event(self):
         """the observed connections pool has been commited"""
         try:
             self.session.repo.close(self.cnxid)
@@ -123,7 +121,7 @@
 class _DelCWPropertyOp(hook.Operation):
     """a user's custom properties has been deleted"""
 
-    def commit_event(self):
+    def postcommit_event(self):
         """the observed connections pool has been commited"""
         try:
             del self.cwpropdict[self.key]
@@ -134,7 +132,7 @@
 class _ChangeCWPropertyOp(hook.Operation):
     """a user's custom properties has been added/changed"""
 
-    def commit_event(self):
+    def postcommit_event(self):
         """the observed connections pool has been commited"""
         self.cwpropdict[self.key] = self.value
 
@@ -142,7 +140,7 @@
 class _AddCWPropertyOp(hook.Operation):
     """a user's custom properties has been added/changed"""
 
-    def commit_event(self):
+    def postcommit_event(self):
         """the observed connections pool has been commited"""
         cwprop = self.cwprop
         if not cwprop.for_user:
@@ -180,8 +178,8 @@
 
     def __call__(self):
         entity = self.entity
-        if not ('pkey' in entity.edited_attributes or
-                'value' in entity.edited_attributes):
+        if not ('pkey' in entity.cw_edited or
+                'value' in entity.cw_edited):
             return
         key, value = entity.pkey, entity.value
         session = self._cw
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hooks/syncsources.py	Wed Oct 13 08:37:21 2010 +0200
@@ -0,0 +1,33 @@
+from cubicweb import ValidationError
+from cubicweb.selectors import is_instance
+from cubicweb.server import hook
+
+class SourceHook(hook.Hook):
+    __abstract__ = True
+    category = 'cw.sources'
+
+
+class SourceAddedOp(hook.Operation):
+    def precommit_event(self):
+        self.session.repo.add_source(self.entity)
+
+class SourceAddedHook(SourceHook):
+    __regid__ = 'cw.sources.added'
+    __select__ = SourceHook.__select__ & is_instance('CWSource')
+    events = ('after_add_entity',)
+    def __call__(self):
+        SourceAddedOp(self._cw, entity=self.entity)
+
+
+class SourceRemovedOp(hook.Operation):
+    def precommit_event(self):
+        self.session.repo.remove_source(self.uri)
+
+class SourceRemovedHook(SourceHook):
+    __regid__ = 'cw.sources.removed'
+    __select__ = SourceHook.__select__ & is_instance('CWSource')
+    events = ('before_delete_entity',)
+    def __call__(self):
+        if self.entity.name == 'system':
+            raise ValidationError(self.entity.eid, {None: 'cant remove system source'})
+        SourceRemovedOp(self._cw, uri=self.entity.name)
--- a/hooks/test/unittest_hooks.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/test/unittest_hooks.py	Wed Oct 13 08:37:21 2010 +0200
@@ -143,10 +143,9 @@
         entity.set_attributes(name=u'wf2')
         self.assertEqual(entity.description, u'yo')
         entity.set_attributes(description=u'R&D<p>yo')
-        entity.pop('description')
+        entity.cw_attr_cache.pop('description')
         self.assertEqual(entity.description, u'R&amp;D<p>yo</p>')
 
-
     def test_metadata_cwuri(self):
         entity = self.request().create_entity('Workflow', name=u'wf1')
         self.assertEqual(entity.cwuri, self.repo.config['base-url'] + 'eid/%s' % entity.eid)
--- a/hooks/workflow.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/hooks/workflow.py	Wed Oct 13 08:37:21 2010 +0200
@@ -135,7 +135,7 @@
             qname = role_name('to_state', 'subject')
             msg = session._("state doesn't belong to entity's current workflow")
             raise ValidationError(self.trinfo.eid, {'to_state': msg})
-        tostate = wftr.get_exit_point(forentity, trinfo['to_state'])
+        tostate = wftr.get_exit_point(forentity, trinfo.cw_attr_cache['to_state'])
         if tostate is not None:
             # reached an exit point
             msg = session._('exiting from subworkflow %s')
@@ -185,7 +185,7 @@
         entity = self.entity
         # first retreive entity to which the state change apply
         try:
-            foreid = entity['wf_info_for']
+            foreid = entity.cw_attr_cache['wf_info_for']
         except KeyError:
             qname = role_name('wf_info_for', 'subject')
             msg = session._('mandatory relation')
@@ -213,7 +213,7 @@
                      or not session.write_security)
         # no investigate the requested state change...
         try:
-            treid = entity['by_transition']
+            treid = entity.cw_attr_cache['by_transition']
         except KeyError:
             # no transition set, check user is a manager and destination state
             # is specified (and valid)
@@ -221,7 +221,7 @@
                 qname = role_name('by_transition', 'subject')
                 msg = session._('mandatory relation')
                 raise ValidationError(entity.eid, {qname: msg})
-            deststateeid = entity.get('to_state')
+            deststateeid = entity.cw_attr_cache.get('to_state')
             if not deststateeid:
                 qname = role_name('by_transition', 'subject')
                 msg = session._('mandatory relation')
@@ -247,8 +247,8 @@
                 if not tr.may_be_fired(foreid):
                     msg = session._("transition may not be fired")
                     raise ValidationError(entity.eid, {qname: msg})
-            if entity.get('to_state'):
-                deststateeid = entity['to_state']
+            deststateeid = entity.cw_attr_cache.get('to_state')
+            if deststateeid is not None:
                 if not cowpowers and deststateeid != tr.destination(forentity).eid:
                     qname = role_name('by_transition', 'subject')
                     msg = session._("transition isn't allowed")
@@ -262,8 +262,8 @@
             else:
                 deststateeid = tr.destination(forentity).eid
         # everything is ok, add missing information on the trinfo entity
-        entity['from_state'] = fromstate.eid
-        entity['to_state'] = deststateeid
+        entity.cw_edited['from_state'] = fromstate.eid
+        entity.cw_edited['to_state'] = deststateeid
         nocheck = session.transaction_data.setdefault('skip-security', set())
         nocheck.add((entity.eid, 'from_state', fromstate.eid))
         nocheck.add((entity.eid, 'to_state', deststateeid))
@@ -278,11 +278,12 @@
 
     def __call__(self):
         trinfo = self.entity
-        _change_state(self._cw, trinfo['wf_info_for'],
-                      trinfo['from_state'], trinfo['to_state'])
-        forentity = self._cw.entity_from_eid(trinfo['wf_info_for'])
+        rcache = trinfo.cw_attr_cache
+        _change_state(self._cw, rcache['wf_info_for'], rcache['from_state'],
+                      rcache['to_state'])
+        forentity = self._cw.entity_from_eid(rcache['wf_info_for'])
         iworkflowable = forentity.cw_adapt_to('IWorkflowable')
-        assert iworkflowable.current_state.eid == trinfo['to_state']
+        assert iworkflowable.current_state.eid == rcache['to_state']
         if iworkflowable.main_workflow.eid != iworkflowable.current_workflow.eid:
             _SubWorkflowExitOp(self._cw, forentity=forentity, trinfo=trinfo)
 
--- a/i18n/en.po	Wed Oct 13 08:37:09 2010 +0200
+++ b/i18n/en.po	Wed Oct 13 08:37:21 2010 +0200
@@ -47,6 +47,10 @@
 msgstr ""
 
 #, python-format
+msgid "%(etype)s by %(author)s"
+msgstr ""
+
+#, python-format
 msgid "%(firstname)s %(surname)s"
 msgstr ""
 
@@ -200,6 +204,9 @@
 msgid "AND"
 msgstr ""
 
+msgid "About this site"
+msgstr ""
+
 msgid "Any"
 msgstr ""
 
@@ -320,6 +327,18 @@
 msgid "CWRelation_plural"
 msgstr "Relations"
 
+msgid "CWSource"
+msgstr ""
+
+msgid "CWSourceHostConfig"
+msgstr ""
+
+msgid "CWSourceHostConfig_plural"
+msgstr ""
+
+msgid "CWSource_plural"
+msgstr ""
+
 msgid "CWUniqueTogetherConstraint"
 msgstr ""
 
@@ -505,6 +524,12 @@
 msgid "New CWRelation"
 msgstr "New relation"
 
+msgid "New CWSource"
+msgstr ""
+
+msgid "New CWSourceHostConfig"
+msgstr ""
+
 msgid "New CWUniqueTogetherConstraint"
 msgstr ""
 
@@ -569,6 +594,9 @@
 msgid "Please note that this is only a shallow copy"
 msgstr ""
 
+msgid "Powered by CubicWeb"
+msgstr ""
+
 msgid "RQLConstraint"
 msgstr "RQL constraint"
 
@@ -615,6 +643,12 @@
 msgid "SizeConstraint"
 msgstr "size constraint"
 
+msgid ""
+"Source's configuration for a particular host. One key=value per line, "
+"authorized keys depending on the source's type, overriding values defined on "
+"the source."
+msgstr ""
+
 msgid "Startup views"
 msgstr ""
 
@@ -698,6 +732,12 @@
 msgid "This CWRelation"
 msgstr "This relation"
 
+msgid "This CWSource"
+msgstr ""
+
+msgid "This CWSourceHostConfig"
+msgstr ""
+
 msgid "This CWUniqueTogetherConstraint"
 msgstr ""
 
@@ -829,9 +869,6 @@
 "get_cache() method."
 msgstr ""
 
-msgid "about this site"
-msgstr ""
-
 msgid "abstract base class for transitions"
 msgstr ""
 
@@ -895,6 +932,9 @@
 msgid "add CWRelation relation_type CWRType object"
 msgstr "relation definition"
 
+msgid "add CWSourceHostConfig cw_host_config_of CWSource object"
+msgstr ""
+
 msgid "add CWUniqueTogetherConstraint constraint_of CWEType object"
 msgstr ""
 
@@ -1083,6 +1123,14 @@
 msgstr ""
 
 #, python-format
+msgid "archive for %(author)s"
+msgstr ""
+
+#, python-format
+msgid "archive for %(month)s/%(year)s"
+msgstr ""
+
+#, python-format
 msgid "at least one relation %(rtype)s is required on %(etype)s (%(eid)s)"
 msgstr ""
 
@@ -1139,54 +1187,6 @@
 msgid "boxes"
 msgstr ""
 
-msgid "boxes_bookmarks_box"
-msgstr "bookmarks box"
-
-msgid "boxes_bookmarks_box_description"
-msgstr "box listing the user's bookmarks"
-
-msgid "boxes_download_box"
-msgstr "download box"
-
-msgid "boxes_download_box_description"
-msgstr ""
-
-msgid "boxes_edit_box"
-msgstr "actions box"
-
-msgid "boxes_edit_box_description"
-msgstr "box listing the applicable actions on the displayed data"
-
-msgid "boxes_filter_box"
-msgstr "filter"
-
-msgid "boxes_filter_box_description"
-msgstr "box providing filter within current search results functionality"
-
-msgid "boxes_possible_views_box"
-msgstr "possible views box"
-
-msgid "boxes_possible_views_box_description"
-msgstr "box listing the possible views for the displayed data"
-
-msgid "boxes_rss"
-msgstr "rss box"
-
-msgid "boxes_rss_description"
-msgstr "RSS icon to get displayed data as a RSS thread"
-
-msgid "boxes_search_box"
-msgstr "search box"
-
-msgid "boxes_search_box_description"
-msgstr "search box"
-
-msgid "boxes_startup_views_box"
-msgstr "startup views box"
-
-msgid "boxes_startup_views_box_description"
-msgstr "box listing the possible start pages"
-
 msgid "bug report sent"
 msgstr ""
 
@@ -1279,6 +1279,9 @@
 "%(card)s"
 msgstr ""
 
+msgid "cancel"
+msgstr ""
+
 msgid "cancel select"
 msgstr ""
 
@@ -1338,45 +1341,12 @@
 msgid "components"
 msgstr ""
 
-msgid "components_appliname"
-msgstr "application title"
-
-msgid "components_appliname_description"
-msgstr "display the application title in the page's header"
-
-msgid "components_breadcrumbs"
-msgstr "breadcrumbs"
-
-msgid "components_breadcrumbs_description"
-msgstr "breadcrumbs bar that display a path locating the page in the site"
-
 msgid "components_etypenavigation"
 msgstr "filtering by type"
 
 msgid "components_etypenavigation_description"
 msgstr "permit to filter search results by entity type"
 
-msgid "components_help"
-msgstr "help button"
-
-msgid "components_help_description"
-msgstr "the help button on the top right-hand corner"
-
-msgid "components_loggeduserlink"
-msgstr "user link"
-
-msgid "components_loggeduserlink_description"
-msgstr ""
-"for anonymous users, this is a link pointing to authentication form, for "
-"logged in users, this is a link that makes a box appear and listing some "
-"possible user actions"
-
-msgid "components_logo"
-msgstr "icon"
-
-msgid "components_logo_description"
-msgstr "the application's icon displayed in the page's header"
-
 msgid "components_navigation"
 msgstr "page navigation"
 
@@ -1421,6 +1391,17 @@
 msgid "conditions"
 msgstr ""
 
+msgid "config"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "config"
+msgstr ""
+
+msgctxt "CWSourceHostConfig"
+msgid "config"
+msgstr ""
+
 msgid "config mode"
 msgstr ""
 
@@ -1474,43 +1455,6 @@
 msgid "content type"
 msgstr ""
 
-msgid "contentnavigation"
-msgstr "contextual components"
-
-msgid "contentnavigation_breadcrumbs"
-msgstr "breadcrumb"
-
-msgid "contentnavigation_breadcrumbs_description"
-msgstr "breadcrumbs bar that display a path locating the page in the site"
-
-msgid "contentnavigation_metadata"
-msgstr "entity's metadata"
-
-msgid "contentnavigation_metadata_description"
-msgstr ""
-
-msgid "contentnavigation_prevnext"
-msgstr "previous / next entity"
-
-msgid "contentnavigation_prevnext_description"
-msgstr ""
-"display link to go from one entity to another on entities implementing the "
-"\"previous/next\" interface."
-
-msgid "contentnavigation_seealso"
-msgstr "see also"
-
-msgid "contentnavigation_seealso_description"
-msgstr ""
-"section containing entities related by the \"see also\" relation on entities "
-"supporting it."
-
-msgid "contentnavigation_wfhistory"
-msgstr "workflow history"
-
-msgid "contentnavigation_wfhistory_description"
-msgstr "show the workflow's history."
-
 msgid "context"
 msgstr ""
 
@@ -1589,9 +1533,14 @@
 msgstr "creating relation %(linkto)s"
 
 msgid ""
+"creating CWSourceHostConfig (CWSourceHostConfig cw_host_config_of CWSource "
+"%(linkto)s)"
+msgstr "creating host configuration for source %(linkto)s"
+
+msgid ""
 "creating CWUniqueTogetherConstraint (CWUniqueTogetherConstraint "
 "constraint_of CWEType %(linkto)s)"
-msgstr ""
+msgstr "creating unique together constrain for entity type %(linkto)s"
 
 msgid "creating CWUser (CWUser in_group CWGroup %(linkto)s)"
 msgstr "creating a new user in group %(linkto)s"
@@ -1710,6 +1659,118 @@
 msgid "csv export"
 msgstr ""
 
+msgid "ctxcomponents"
+msgstr "contextual components"
+
+msgid "ctxcomponents_anonuserlink"
+msgstr "user link"
+
+msgid "ctxcomponents_anonuserlink_description"
+msgstr ""
+"for anonymous users, this is a link pointing to authentication form, for "
+"logged in users, this is a link that makes a box appear and listing some "
+"possible user actions"
+
+msgid "ctxcomponents_appliname"
+msgstr "application title"
+
+msgid "ctxcomponents_appliname_description"
+msgstr "display the application title in the page's header"
+
+msgid "ctxcomponents_bookmarks_box"
+msgstr "bookmarks box"
+
+msgid "ctxcomponents_bookmarks_box_description"
+msgstr "box listing the user's bookmarks"
+
+msgid "ctxcomponents_breadcrumbs"
+msgstr "breadcrumb"
+
+msgid "ctxcomponents_breadcrumbs_description"
+msgstr "breadcrumbs bar that display a path locating the page in the site"
+
+msgid "ctxcomponents_download_box"
+msgstr "download box"
+
+msgid "ctxcomponents_download_box_description"
+msgstr ""
+
+msgid "ctxcomponents_edit_box"
+msgstr "actions box"
+
+msgid "ctxcomponents_edit_box_description"
+msgstr "box listing the applicable actions on the displayed data"
+
+msgid "ctxcomponents_facet.filters"
+msgstr "facets box"
+
+msgid "ctxcomponents_facet.filters_description"
+msgstr "box providing filter within current search results functionality"
+
+msgid "ctxcomponents_logo"
+msgstr "logo"
+
+msgid "ctxcomponents_logo_description"
+msgstr "the application's icon displayed in the page's header"
+
+msgid "ctxcomponents_metadata"
+msgstr "entity's metadata"
+
+msgid "ctxcomponents_metadata_description"
+msgstr ""
+
+msgid "ctxcomponents_possible_views_box"
+msgstr "possible views box"
+
+msgid "ctxcomponents_possible_views_box_description"
+msgstr "box listing the possible views for the displayed data"
+
+msgid "ctxcomponents_prevnext"
+msgstr "previous / next entity"
+
+msgid "ctxcomponents_prevnext_description"
+msgstr ""
+"display link to go from one entity to another on entities implementing the "
+"\"previous/next\" interface."
+
+msgid "ctxcomponents_rss"
+msgstr "rss box"
+
+msgid "ctxcomponents_rss_description"
+msgstr "RSS icon to get displayed data as a RSS thread"
+
+msgid "ctxcomponents_search_box"
+msgstr "search box"
+
+msgid "ctxcomponents_search_box_description"
+msgstr "search box"
+
+msgid "ctxcomponents_seealso"
+msgstr "see also"
+
+msgid "ctxcomponents_seealso_description"
+msgstr ""
+"section containing entities related by the \"see also\" relation on entities "
+"supporting it."
+
+msgid "ctxcomponents_startup_views_box"
+msgstr "startup views box"
+
+msgid "ctxcomponents_startup_views_box_description"
+msgstr "box listing the possible start pages"
+
+msgid "ctxcomponents_userstatus"
+msgstr ""
+
+msgid "ctxcomponents_userstatus_description"
+msgstr ""
+
+msgid "ctxcomponents_wfhistory"
+msgstr "workflow history"
+
+msgid "ctxcomponents_wfhistory_description"
+msgstr "show the workflow's history."
+
 msgid "ctxtoolbar"
 msgstr "toolbar"
 
@@ -1719,6 +1780,72 @@
 msgid "custom_workflow_object"
 msgstr "custom workflow of"
 
+msgid "cw_dont_cross"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_dont_cross"
+msgstr ""
+
+msgid "cw_dont_cross_object"
+msgstr ""
+
+msgctxt "CWRType"
+msgid "cw_dont_cross_object"
+msgstr ""
+
+msgid "cw_host_config_of"
+msgstr ""
+
+msgctxt "CWSourceHostConfig"
+msgid "cw_host_config_of"
+msgstr ""
+
+msgid "cw_host_config_of_object"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_host_config_of_object"
+msgstr ""
+
+msgid "cw_may_cross"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_may_cross"
+msgstr ""
+
+msgid "cw_may_cross_object"
+msgstr ""
+
+msgctxt "CWRType"
+msgid "cw_may_cross_object"
+msgstr ""
+
+msgid "cw_source"
+msgstr ""
+
+msgid "cw_source_object"
+msgstr ""
+
+msgid "cw_support"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_support"
+msgstr ""
+
+msgid "cw_support_object"
+msgstr ""
+
+msgctxt "CWEType"
+msgid "cw_support_object"
+msgstr ""
+
+msgctxt "CWRType"
+msgid "cw_support_object"
+msgstr ""
+
 msgid "cwetype-box"
 msgstr "\"box\" view"
 
@@ -2112,10 +2239,6 @@
 msgid "error while embedding page"
 msgstr ""
 
-#, python-format
-msgid "error while handling __method: %s"
-msgstr "error while handling method %s"
-
 msgid "error while publishing ReST text"
 msgstr ""
 
@@ -2159,8 +2282,11 @@
 msgid "external page"
 msgstr ""
 
+msgid "facet.filters"
+msgstr "filter"
+
 msgid "facetbox"
-msgstr ""
+msgstr "facettes"
 
 msgid "facets_created_by-facet"
 msgstr "\"created by\" facet"
@@ -2168,6 +2294,12 @@
 msgid "facets_created_by-facet_description"
 msgstr ""
 
+msgid "facets_cw_source-facet"
+msgstr "data source"
+
+msgid "facets_cw_source-facet_description"
+msgstr ""
+
 msgid "facets_cwfinal-facet"
 msgstr "\"final entity or relation type\" facet"
 
@@ -2372,8 +2504,11 @@
 msgid "has_text"
 msgstr "has text"
 
-msgid "help"
-msgstr ""
+msgid "header-center"
+msgstr "header (center)"
+
+msgid "header-right"
+msgstr "header (right)"
 
 msgid "hide filter form"
 msgstr ""
@@ -2679,6 +2814,9 @@
 msgid "login"
 msgstr "login"
 
+msgid "login / password"
+msgstr ""
+
 msgid "login or email"
 msgstr ""
 
@@ -2723,6 +2861,13 @@
 msgid "march"
 msgstr ""
 
+msgid "match_host"
+msgstr ""
+
+msgctxt "CWSourceHostConfig"
+msgid "match_host"
+msgstr ""
+
 msgid "maximum number of characters in short description"
 msgstr ""
 
@@ -2803,6 +2948,10 @@
 msgid "name"
 msgstr "name"
 
+msgctxt "CWSource"
+msgid "name"
+msgstr ""
+
 msgctxt "State"
 msgid "name"
 msgstr "name"
@@ -2827,6 +2976,9 @@
 "necessary (comma separated)"
 msgstr ""
 
+msgid "name of the source"
+msgstr ""
+
 msgid "name or identifier of the permission"
 msgstr ""
 
@@ -3020,9 +3172,6 @@
 msgid "possible views"
 msgstr ""
 
-msgid "powered by CubicWeb"
-msgstr ""
-
 msgid "prefered_form"
 msgstr "prefered form"
 
@@ -3107,6 +3256,9 @@
 msgid "read_permission_object"
 msgstr "can be read by"
 
+msgid "regexp matching host(s) to which this config applies"
+msgstr ""
+
 msgid "registry"
 msgstr ""
 
@@ -3279,6 +3431,9 @@
 msgid "security"
 msgstr ""
 
+msgid "see more"
+msgstr ""
+
 msgid "see them all"
 msgstr ""
 
@@ -3376,6 +3531,11 @@
 msgid "sorry, the server is unable to handle this query"
 msgstr ""
 
+msgid ""
+"source's configuration. One key=value per line, authorized keys depending on "
+"the source's type"
+msgstr ""
+
 msgid "sparql xml"
 msgstr ""
 
@@ -3695,6 +3855,10 @@
 msgid "type"
 msgstr "type"
 
+msgctxt "CWSource"
+msgid "type"
+msgstr ""
+
 msgctxt "Transition"
 msgid "type"
 msgstr "type"
@@ -3706,6 +3870,9 @@
 msgid "type here a sparql query"
 msgstr ""
 
+msgid "type of the source"
+msgstr ""
+
 msgid "ui"
 msgstr ""
 
@@ -4045,15 +4212,3 @@
 
 msgid "you should probably delete that property"
 msgstr ""
-
-#~ msgid "add_perm"
-#~ msgstr "add permission"
-
-#~ msgid "delete_perm"
-#~ msgstr "delete permission"
-
-#~ msgid "read_perm"
-#~ msgstr "read permission"
-
-#~ msgid "update_perm"
-#~ msgstr "update permission"
--- a/i18n/es.po	Wed Oct 13 08:37:09 2010 +0200
+++ b/i18n/es.po	Wed Oct 13 08:37:21 2010 +0200
@@ -53,6 +53,10 @@
 msgstr "el valor %(value)r no satisface la condición %(cstr)s"
 
 #, python-format
+msgid "%(etype)s by %(author)s"
+msgstr ""
+
+#, python-format
 msgid "%(firstname)s %(surname)s"
 msgstr "%(firstname)s %(surname)s"
 
@@ -209,6 +213,9 @@
 msgid "AND"
 msgstr "Y"
 
+msgid "About this site"
+msgstr "Información del Sistema"
+
 msgid "Any"
 msgstr "Cualquiera"
 
@@ -329,6 +336,18 @@
 msgid "CWRelation_plural"
 msgstr "Relaciones"
 
+msgid "CWSource"
+msgstr ""
+
+msgid "CWSourceHostConfig"
+msgstr ""
+
+msgid "CWSourceHostConfig_plural"
+msgstr ""
+
+msgid "CWSource_plural"
+msgstr ""
+
 msgid "CWUniqueTogetherConstraint"
 msgstr ""
 
@@ -526,6 +545,12 @@
 msgid "New CWRelation"
 msgstr "Nueva definición de relación final"
 
+msgid "New CWSource"
+msgstr ""
+
+msgid "New CWSourceHostConfig"
+msgstr ""
+
 msgid "New CWUniqueTogetherConstraint"
 msgstr ""
 
@@ -590,6 +615,9 @@
 msgid "Please note that this is only a shallow copy"
 msgstr "Recuerde que sólo es una copia superficial"
 
+msgid "Powered by CubicWeb"
+msgstr "Potenciado en CubicWeb"
+
 msgid "RQLConstraint"
 msgstr "Restricción RQL"
 
@@ -636,6 +664,12 @@
 msgid "SizeConstraint"
 msgstr "Restricción de tamaño"
 
+msgid ""
+"Source's configuration for a particular host. One key=value per line, "
+"authorized keys depending on the source's type, overriding values defined on "
+"the source."
+msgstr ""
+
 msgid "Startup views"
 msgstr "Vistas de inicio"
 
@@ -719,6 +753,12 @@
 msgid "This CWRelation"
 msgstr "Esta definición de relación no final"
 
+msgid "This CWSource"
+msgstr ""
+
+msgid "This CWSourceHostConfig"
+msgstr ""
+
 msgid "This CWUniqueTogetherConstraint"
 msgstr ""
 
@@ -871,9 +911,6 @@
 "Para recuperar un caché, hace falta utilizar el método\n"
 "get_cache(cachename)."
 
-msgid "about this site"
-msgstr "Información del Sistema"
-
 msgid "abstract base class for transitions"
 msgstr "Clase de base abstracta para la transiciones"
 
@@ -937,6 +974,9 @@
 msgid "add CWRelation relation_type CWRType object"
 msgstr "Definición de relación"
 
+msgid "add CWSourceHostConfig cw_host_config_of CWSource object"
+msgstr ""
+
 msgid "add CWUniqueTogetherConstraint constraint_of CWEType object"
 msgstr ""
 
@@ -1127,6 +1167,14 @@
 msgstr "Abril"
 
 #, python-format
+msgid "archive for %(author)s"
+msgstr ""
+
+#, python-format
+msgid "archive for %(month)s/%(year)s"
+msgstr ""
+
+#, python-format
 msgid "at least one relation %(rtype)s is required on %(etype)s (%(eid)s)"
 msgstr ""
 "La entidad #%(eid)s de tipo %(etype)s debe necesariamente tener almenos una "
@@ -1185,56 +1233,6 @@
 msgid "boxes"
 msgstr "Cajas"
 
-msgid "boxes_bookmarks_box"
-msgstr "Caja de Favoritos"
-
-msgid "boxes_bookmarks_box_description"
-msgstr "Muestra y permite administrar los favoritos del usuario"
-
-msgid "boxes_download_box"
-msgstr "Configuración de caja de descargas"
-
-msgid "boxes_download_box_description"
-msgstr "Caja que contiene los elementos descargados"
-
-msgid "boxes_edit_box"
-msgstr "Caja de Acciones"
-
-msgid "boxes_edit_box_description"
-msgstr "Muestra las acciones posibles a ejecutar para los datos seleccionados"
-
-msgid "boxes_filter_box"
-msgstr "Filtros"
-
-msgid "boxes_filter_box_description"
-msgstr "Muestra los filtros aplicables a una búsqueda realizada"
-
-msgid "boxes_possible_views_box"
-msgstr "Caja de Vistas Posibles"
-
-msgid "boxes_possible_views_box_description"
-msgstr "Muestra las vistas posibles a aplicar a los datos seleccionados"
-
-msgid "boxes_rss"
-msgstr "Ícono RSS"
-
-msgid "boxes_rss_description"
-msgstr "Muestra el ícono RSS para vistas RSS"
-
-msgid "boxes_search_box"
-msgstr "Caja de búsqueda"
-
-msgid "boxes_search_box_description"
-msgstr ""
-"Permite realizar una búsqueda simple para cualquier tipo de dato en la "
-"aplicación"
-
-msgid "boxes_startup_views_box"
-msgstr "Caja Vistas de inicio"
-
-msgid "boxes_startup_views_box_description"
-msgstr "Muestra las vistas de inicio de la aplicación"
-
 msgid "bug report sent"
 msgstr "Reporte de error enviado"
 
@@ -1329,6 +1327,9 @@
 "no puede poner 'inlined' = %(inlined)s, %(stype)s %(rtype)s %(otype)s tiene "
 "cardinalidad %(card)s"
 
+msgid "cancel"
+msgstr ""
+
 msgid "cancel select"
 msgstr "Cancelar la selección"
 
@@ -1388,44 +1389,12 @@
 msgid "components"
 msgstr "Componentes"
 
-msgid "components_appliname"
-msgstr "Nombre de la aplicación"
-
-msgid "components_appliname_description"
-msgstr "Muestra el nombre de la aplicación en el encabezado de la página"
-
-msgid "components_breadcrumbs"
-msgstr "Ruta de Navegación"
-
-msgid "components_breadcrumbs_description"
-msgstr "Muestra el lugar donde se encuentra la página actual en el Sistema"
-
 msgid "components_etypenavigation"
 msgstr "Filtar por tipo"
 
 msgid "components_etypenavigation_description"
 msgstr "Permite filtrar por tipo de entidad los resultados de una búsqueda"
 
-msgid "components_help"
-msgstr "Botón de ayuda"
-
-msgid "components_help_description"
-msgstr "El botón de ayuda, en el encabezado de la página"
-
-msgid "components_loggeduserlink"
-msgstr "Liga usuario"
-
-msgid "components_loggeduserlink_description"
-msgstr ""
-"Muestra un enlace hacia el formulario de conexión para los usuarios "
-"anónimos, o una caja que contiene los enlaces del usuario conectado. "
-
-msgid "components_logo"
-msgstr "logo"
-
-msgid "components_logo_description"
-msgstr "El logo de la aplicación, en el encabezado de página"
-
 msgid "components_navigation"
 msgstr "Navigación por página"
 
@@ -1472,6 +1441,17 @@
 msgid "conditions"
 msgstr "condiciones"
 
+msgid "config"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "config"
+msgstr ""
+
+msgctxt "CWSourceHostConfig"
+msgid "config"
+msgstr ""
+
 msgid "config mode"
 msgstr "Modo de configuración"
 
@@ -1525,45 +1505,6 @@
 msgid "content type"
 msgstr "tipo MIME"
 
-msgid "contentnavigation"
-msgstr "Componentes contextuales"
-
-msgid "contentnavigation_breadcrumbs"
-msgstr "Ruta de Navegación"
-
-msgid "contentnavigation_breadcrumbs_description"
-msgstr "Muestra la ruta que permite localizar la página actual en el Sistema"
-
-msgid "contentnavigation_metadata"
-msgstr "Metadatos de la Entidad"
-
-msgid "contentnavigation_metadata_description"
-msgstr ""
-
-msgid "contentnavigation_prevnext"
-msgstr "Elemento anterior / siguiente"
-
-msgid "contentnavigation_prevnext_description"
-msgstr ""
-"Muestra las ligas que permiten pasar de una entidad a otra en las entidades "
-"que implementan la interface \"anterior/siguiente\"."
-
-msgid "contentnavigation_seealso"
-msgstr "Vea también"
-
-msgid "contentnavigation_seealso_description"
-msgstr ""
-"sección que muestra las entidades relacionadas por la relación \"vea también"
-"\" , si la entidad soporta esta relación."
-
-msgid "contentnavigation_wfhistory"
-msgstr "Histórico del workflow."
-
-msgid "contentnavigation_wfhistory_description"
-msgstr ""
-"Sección que muestra el reporte histórico de las transiciones del workflow. "
-"Aplica solo en entidades con workflow."
-
 msgid "context"
 msgstr "Contexto"
 
@@ -1649,6 +1590,11 @@
 msgstr "Creación de la relación %(linkto)s"
 
 msgid ""
+"creating CWSourceHostConfig (CWSourceHostConfig cw_host_config_of CWSource "
+"%(linkto)s)"
+msgstr ""
+
+msgid ""
 "creating CWUniqueTogetherConstraint (CWUniqueTogetherConstraint "
 "constraint_of CWEType %(linkto)s)"
 msgstr ""
@@ -1774,6 +1720,121 @@
 msgid "csv export"
 msgstr "Exportar en CSV"
 
+msgid "ctxcomponents"
+msgstr "Componentes contextuales"
+
+msgid "ctxcomponents_anonuserlink"
+msgstr "Liga usuario"
+
+msgid "ctxcomponents_anonuserlink_description"
+msgstr ""
+"Muestra un enlace hacia el formulario de conexión para los usuarios "
+"anónimos, o una caja que contiene los enlaces del usuario conectado. "
+
+msgid "ctxcomponents_appliname"
+msgstr "Nombre de la aplicación"
+
+msgid "ctxcomponents_appliname_description"
+msgstr "Muestra el nombre de la aplicación en el encabezado de la página"
+
+msgid "ctxcomponents_bookmarks_box"
+msgstr "Caja de Favoritos"
+
+msgid "ctxcomponents_bookmarks_box_description"
+msgstr "Muestra y permite administrar los favoritos del usuario"
+
+msgid "ctxcomponents_breadcrumbs"
+msgstr "Ruta de Navegación"
+
+msgid "ctxcomponents_breadcrumbs_description"
+msgstr "Muestra la ruta que permite localizar la página actual en el Sistema"
+
+msgid "ctxcomponents_download_box"
+msgstr "Configuración de caja de descargas"
+
+msgid "ctxcomponents_download_box_description"
+msgstr "Caja que contiene los elementos descargados"
+
+msgid "ctxcomponents_edit_box"
+msgstr "Caja de Acciones"
+
+msgid "ctxcomponents_edit_box_description"
+msgstr "Muestra las acciones posibles a ejecutar para los datos seleccionados"
+
+msgid "ctxcomponents_facet.filters"
+msgstr "Filtros"
+
+msgid "ctxcomponents_facet.filters_description"
+msgstr "Muestra los filtros aplicables a una búsqueda realizada"
+
+msgid "ctxcomponents_logo"
+msgstr "logo"
+
+msgid "ctxcomponents_logo_description"
+msgstr "El logo de la aplicación, en el encabezado de página"
+
+msgid "ctxcomponents_metadata"
+msgstr "Metadatos de la Entidad"
+
+msgid "ctxcomponents_metadata_description"
+msgstr ""
+
+msgid "ctxcomponents_possible_views_box"
+msgstr "Caja de Vistas Posibles"
+
+msgid "ctxcomponents_possible_views_box_description"
+msgstr "Muestra las vistas posibles a aplicar a los datos seleccionados"
+
+msgid "ctxcomponents_prevnext"
+msgstr "Elemento anterior / siguiente"
+
+msgid "ctxcomponents_prevnext_description"
+msgstr ""
+"Muestra las ligas que permiten pasar de una entidad a otra en las entidades "
+"que implementan la interface \"anterior/siguiente\"."
+
+msgid "ctxcomponents_rss"
+msgstr "Ícono RSS"
+
+msgid "ctxcomponents_rss_description"
+msgstr "Muestra el ícono RSS para vistas RSS"
+
+msgid "ctxcomponents_search_box"
+msgstr "Caja de búsqueda"
+
+msgid "ctxcomponents_search_box_description"
+msgstr ""
+"Permite realizar una búsqueda simple para cualquier tipo de dato en la "
+"aplicación"
+
+msgid "ctxcomponents_seealso"
+msgstr "Vea también"
+
+msgid "ctxcomponents_seealso_description"
+msgstr ""
+"sección que muestra las entidades relacionadas por la relación \"vea también"
+"\" , si la entidad soporta esta relación."
+
+msgid "ctxcomponents_startup_views_box"
+msgstr "Caja Vistas de inicio"
+
+msgid "ctxcomponents_startup_views_box_description"
+msgstr "Muestra las vistas de inicio de la aplicación"
+
+msgid "ctxcomponents_userstatus"
+msgstr ""
+
+msgid "ctxcomponents_userstatus_description"
+msgstr ""
+
+msgid "ctxcomponents_wfhistory"
+msgstr "Histórico del workflow."
+
+msgid "ctxcomponents_wfhistory_description"
+msgstr ""
+"Sección que muestra el reporte histórico de las transiciones del workflow. "
+"Aplica solo en entidades con workflow."
+
 msgid "ctxtoolbar"
 msgstr "Barra de herramientas"
 
@@ -1783,6 +1844,72 @@
 msgid "custom_workflow_object"
 msgstr "Workflow de"
 
+msgid "cw_dont_cross"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_dont_cross"
+msgstr ""
+
+msgid "cw_dont_cross_object"
+msgstr ""
+
+msgctxt "CWRType"
+msgid "cw_dont_cross_object"
+msgstr ""
+
+msgid "cw_host_config_of"
+msgstr ""
+
+msgctxt "CWSourceHostConfig"
+msgid "cw_host_config_of"
+msgstr ""
+
+msgid "cw_host_config_of_object"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_host_config_of_object"
+msgstr ""
+
+msgid "cw_may_cross"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_may_cross"
+msgstr ""
+
+msgid "cw_may_cross_object"
+msgstr ""
+
+msgctxt "CWRType"
+msgid "cw_may_cross_object"
+msgstr ""
+
+msgid "cw_source"
+msgstr ""
+
+msgid "cw_source_object"
+msgstr ""
+
+msgid "cw_support"
+msgstr ""
+
+msgctxt "CWSource"
+msgid "cw_support"
+msgstr ""
+
+msgid "cw_support_object"
+msgstr ""
+
+msgctxt "CWEType"
+msgid "cw_support_object"
+msgstr ""
+
+msgctxt "CWRType"
+msgid "cw_support_object"
+msgstr ""
+
 msgid "cwetype-box"
 msgstr "Vista \"caja\""
 
@@ -2198,10 +2325,6 @@
 msgid "error while embedding page"
 msgstr "Error durante la inclusión de la página"
 
-#, python-format
-msgid "error while handling __method: %s"
-msgstr "Error ocurrido durante el tratamiento del formulario (%s)"
-
 msgid "error while publishing ReST text"
 msgstr ""
 "Se ha producido un error durante la interpretación del texto en formato ReST"
@@ -2248,6 +2371,9 @@
 msgid "external page"
 msgstr "Página externa"
 
+msgid "facet.filters"
+msgstr "Filtros"
+
 msgid "facetbox"
 msgstr "Caja de facetas"
 
@@ -2257,6 +2383,12 @@
 msgid "facets_created_by-facet_description"
 msgstr "Faceta creada por"
 
+msgid "facets_cw_source-facet"
+msgstr ""
+
+msgid "facets_cw_source-facet_description"
+msgstr ""
+
 msgid "facets_cwfinal-facet"
 msgstr "Faceta \"final\""
 
@@ -2467,8 +2599,11 @@
 msgid "has_text"
 msgstr "Contiene el texto"
 
-msgid "help"
-msgstr "Ayuda"
+msgid "header-center"
+msgstr ""
+
+msgid "header-right"
+msgstr ""
 
 msgid "hide filter form"
 msgstr "Esconder el filtro"
@@ -2793,6 +2928,9 @@
 msgid "login"
 msgstr "Usuario"
 
+msgid "login / password"
+msgstr ""
+
 msgid "login or email"
 msgstr "Usuario o dirección de correo"
 
@@ -2837,6 +2975,13 @@
 msgid "march"
 msgstr "Marzo"
 
+msgid "match_host"
+msgstr ""
+
+msgctxt "CWSourceHostConfig"
+msgid "match_host"
+msgstr ""
+
 msgid "maximum number of characters in short description"
 msgstr "Máximo de caracteres en las descripciones cortas"
 
@@ -2917,6 +3062,10 @@
 msgid "name"
 msgstr "Nombre"
 
+msgctxt "CWSource"
+msgid "name"
+msgstr ""
+
 msgctxt "State"
 msgid "name"
 msgstr "Nombre"
@@ -2943,6 +3092,9 @@
 "Nombre de las variables principales que deberían ser utilizadas en la "
 "selección de ser necesario (separarlas con comas)"
 
+msgid "name of the source"
+msgstr ""
+
 msgid "name or identifier of the permission"
 msgstr "Nombre o identificador del permiso"
 
@@ -3135,9 +3287,6 @@
 msgid "possible views"
 msgstr "Vistas posibles"
 
-msgid "powered by CubicWeb"
-msgstr "Potenciado en CubicWeb"
-
 msgid "prefered_form"
 msgstr "Forma preferida"
 
@@ -3222,6 +3371,9 @@
 msgid "read_permission_object"
 msgstr "Puede leer"
 
+msgid "regexp matching host(s) to which this config applies"
+msgstr ""
+
 msgid "registry"
 msgstr "Registro"
 
@@ -3398,6 +3550,9 @@
 msgid "security"
 msgstr "Seguridad"
 
+msgid "see more"
+msgstr ""
+
 msgid "see them all"
 msgstr "Ver todos"
 
@@ -3500,6 +3655,11 @@
 msgid "sorry, the server is unable to handle this query"
 msgstr "Lo sentimos, el servidor no puede manejar esta consulta"
 
+msgid ""
+"source's configuration. One key=value per line, authorized keys depending on "
+"the source's type"
+msgstr ""
+
 msgid "sparql xml"
 msgstr "XML Sparql"
 
@@ -3823,6 +3983,10 @@
 msgid "type"
 msgstr "Tipo"
 
+msgctxt "CWSource"
+msgid "type"
+msgstr ""
+
 msgctxt "Transition"
 msgid "type"
 msgstr "Tipo"
@@ -3834,6 +3998,9 @@
 msgid "type here a sparql query"
 msgstr "Escriba aquí su consulta en Sparql"
 
+msgid "type of the source"
+msgstr ""
+
 msgid "ui"
 msgstr "Interfaz Genérica"
 
@@ -4186,23 +4353,5 @@
 msgid "you should probably delete that property"
 msgstr "Debería probablamente suprimir esta propriedad"
 
-#~ msgid "add_perm"
-#~ msgstr "Agregado"
-
-#~ msgid "delete_perm"
-#~ msgstr "Eliminar"
-
 #~ msgid "edition"
 #~ msgstr "Edición"
-
-#~ msgid "graphical workflow for %s"
-#~ msgstr "Gráfica del workflow por %s"
-
-#~ msgid "personnal informations"
-#~ msgstr "Información personal"
-
-#~ msgid "read_perm"
-#~ msgstr "Lectura"
-
-#~ msgid "update_perm"
-#~ msgstr "Permiso de Modificar"
--- a/i18n/fr.po	Wed Oct 13 08:37:09 2010 +0200
+++ b/i18n/fr.po	Wed Oct 13 08:37:21 2010 +0200
@@ -52,6 +52,10 @@
 msgstr "la valeur %(value)r ne satisfait pas la contrainte %(cstr)s"
 
 #, python-format
+msgid "%(etype)s by %(author)s"
+msgstr "%(etype)s par %(author)s"
+
+#, python-format
 msgid "%(firstname)s %(surname)s"
 msgstr "%(firstname)s %(surname)s"
 
@@ -207,6 +211,9 @@
 msgid "AND"
 msgstr "ET"
 
+msgid "About this site"
+msgstr "À propos de ce site"
+
 msgid "Any"
 msgstr "N'importe"
 
@@ -327,6 +334,18 @@
 msgid "CWRelation_plural"
 msgstr "Relations"
 
+msgid "CWSource"
+msgstr "Source de données"
+
+msgid "CWSourceHostConfig"
+msgstr "Configuration de source"
+
+msgid "CWSourceHostConfig_plural"
+msgstr "Configurations de source"
+
+msgid "CWSource_plural"
+msgstr "Source de données"
+
 msgid "CWUniqueTogetherConstraint"
 msgstr "Contrainte unique_together"
 
@@ -360,8 +379,8 @@
 "Can't restore relation %(rtype)s of entity %(eid)s, this relation does not "
 "exists anymore in the schema."
 msgstr ""
-"Ne peut restaurer la relation %(rtype)s de l'entité %(eid)s, cette "
-"relationn'existe plus dans le schéma"
+"Ne peut restaurer la relation %(rtype)s de l'entité %(eid)s, cette relation "
+"n'existe plus dans le schéma"
 
 #, python-format
 msgid ""
@@ -524,6 +543,12 @@
 msgid "New CWRelation"
 msgstr "Nouvelle définition de relation non finale"
 
+msgid "New CWSource"
+msgstr "Nouvelle source"
+
+msgid "New CWSourceHostConfig"
+msgstr "Nouvelle configuration de source"
+
 msgid "New CWUniqueTogetherConstraint"
 msgstr "Nouvelle contrainte unique_together"
 
@@ -588,6 +613,9 @@
 msgid "Please note that this is only a shallow copy"
 msgstr "Attention, cela n'effectue qu'une copie de surface"
 
+msgid "Powered by CubicWeb"
+msgstr "Construit avec CubicWeb"
+
 msgid "RQLConstraint"
 msgstr "contrainte rql"
 
@@ -634,6 +662,15 @@
 msgid "SizeConstraint"
 msgstr "contrainte de taille"
 
+msgid ""
+"Source's configuration for a particular host. One key=value per line, "
+"authorized keys depending on the source's type, overriding values defined on "
+"the source."
+msgstr ""
+"Configuration de la source pour un hôte spécifique. Une clé=valeur par "
+"ligne, les clés autorisées dépendantes du type de source. Les valeur "
+"surchargent celles définies sur la source."
+
 msgid "Startup views"
 msgstr "Vues de départ"
 
@@ -717,6 +754,12 @@
 msgid "This CWRelation"
 msgstr "Cette définition de relation"
 
+msgid "This CWSource"
+msgstr "Cette source"
+
+msgid "This CWSourceHostConfig"
+msgstr "Cette configuration de source"
+
 msgid "This CWUniqueTogetherConstraint"
 msgstr "Cette contrainte unique_together"
 
@@ -869,9 +912,6 @@
 "Pour récupérer un cache, il faut utiliser utiliser la méthode\n"
 "get_cache(cachename)."
 
-msgid "about this site"
-msgstr "à propos de ce site"
-
 msgid "abstract base class for transitions"
 msgstr "classe de base abstraite pour les transitions"
 
@@ -935,6 +975,9 @@
 msgid "add CWRelation relation_type CWRType object"
 msgstr "définition de relation"
 
+msgid "add CWSourceHostConfig cw_host_config_of CWSource object"
+msgstr "configuration d'hôte"
+
 msgid "add CWUniqueTogetherConstraint constraint_of CWEType object"
 msgstr "contrainte unique_together"
 
@@ -1125,6 +1168,14 @@
 msgstr "avril"
 
 #, python-format
+msgid "archive for %(author)s"
+msgstr "archive pour l'auteur %(author)s"
+
+#, python-format
+msgid "archive for %(month)s/%(year)s"
+msgstr "archive pour le mois %(month)s/%(year)s"
+
+#, python-format
 msgid "at least one relation %(rtype)s is required on %(etype)s (%(eid)s)"
 msgstr ""
 "l'entité #%(eid)s de type %(etype)s doit nécessairement être reliée à une\n"
@@ -1184,55 +1235,6 @@
 msgid "boxes"
 msgstr "boîtes"
 
-msgid "boxes_bookmarks_box"
-msgstr "boîte signets"
-
-msgid "boxes_bookmarks_box_description"
-msgstr "boîte contenant les signets de l'utilisateur"
-
-msgid "boxes_download_box"
-msgstr "boîte de téléchargement"
-
-msgid "boxes_download_box_description"
-msgstr "boîte contenant un lien permettant de télécharger la ressource"
-
-msgid "boxes_edit_box"
-msgstr "boîte d'actions"
-
-msgid "boxes_edit_box_description"
-msgstr ""
-"boîte affichant les différentes actions possibles sur les données affichées"
-
-msgid "boxes_filter_box"
-msgstr "filtrer"
-
-msgid "boxes_filter_box_description"
-msgstr "boîte permettant de filtrer parmi les résultats d'une recherche"
-
-msgid "boxes_possible_views_box"
-msgstr "boîte des vues possibles"
-
-msgid "boxes_possible_views_box_description"
-msgstr "boîte affichant les vues possibles pour les données courantes"
-
-msgid "boxes_rss"
-msgstr "icône RSS"
-
-msgid "boxes_rss_description"
-msgstr "l'icône RSS permettant de récupérer la vue RSS des données affichées"
-
-msgid "boxes_search_box"
-msgstr "boîte de recherche"
-
-msgid "boxes_search_box_description"
-msgstr "boîte avec un champ de recherche simple"
-
-msgid "boxes_startup_views_box"
-msgstr "boîte des vues de départs"
-
-msgid "boxes_startup_views_box_description"
-msgstr "boîte affichant les vues de départs de l'application"
-
 msgid "bug report sent"
 msgstr "rapport d'erreur envoyé"
 
@@ -1327,6 +1329,9 @@
 "ne peut mettre 'inlined' = %(inlined)s, %(stype)s %(rtype)s %(otype)s a pour "
 "cardinalité %(card)s"
 
+msgid "cancel"
+msgstr "annuler"
+
 msgid "cancel select"
 msgstr "annuler la sélection"
 
@@ -1386,46 +1391,12 @@
 msgid "components"
 msgstr "composants"
 
-msgid "components_appliname"
-msgstr "titre de l'application"
-
-msgid "components_appliname_description"
-msgstr "affiche le titre de l'application dans l'en-tête de page"
-
-msgid "components_breadcrumbs"
-msgstr "fil d'ariane"
-
-msgid "components_breadcrumbs_description"
-msgstr ""
-"affiche un chemin permettant de localiser la page courante dans le site"
-
 msgid "components_etypenavigation"
 msgstr "filtrage par type"
 
 msgid "components_etypenavigation_description"
 msgstr "permet de filtrer par type d'entité les résultats d'une recherche"
 
-msgid "components_help"
-msgstr "bouton aide"
-
-msgid "components_help_description"
-msgstr "le bouton d'aide, dans l'en-tête de page"
-
-msgid "components_loggeduserlink"
-msgstr "lien utilisateur"
-
-msgid "components_loggeduserlink_description"
-msgstr ""
-"affiche un lien vers le formulaire d'authentification pour les utilisateurs "
-"anonymes, sinon une boite contenant notamment des liens propres à "
-"l'utilisateur connectés"
-
-msgid "components_logo"
-msgstr "logo"
-
-msgid "components_logo_description"
-msgstr "le logo de l'application, dans l'en-tête de page"
-
 msgid "components_navigation"
 msgstr "navigation par page"
 
@@ -1472,6 +1443,17 @@
 msgid "conditions"
 msgstr "conditions"
 
+msgid "config"
+msgstr "configuration"
+
+msgctxt "CWSource"
+msgid "config"
+msgstr "configuration"
+
+msgctxt "CWSourceHostConfig"
+msgid "config"
+msgstr "configuration"
+
 msgid "config mode"
 msgstr "mode de configuration"
 
@@ -1525,46 +1507,6 @@
 msgid "content type"
 msgstr "type MIME"
 
-msgid "contentnavigation"
-msgstr "composants contextuels"
-
-msgid "contentnavigation_breadcrumbs"
-msgstr "fil d'ariane"
-
-msgid "contentnavigation_breadcrumbs_description"
-msgstr ""
-"affiche un chemin permettant de localiser la page courante dans le site"
-
-msgid "contentnavigation_metadata"
-msgstr "méta-données de l'entité"
-
-msgid "contentnavigation_metadata_description"
-msgstr ""
-
-msgid "contentnavigation_prevnext"
-msgstr "élément précedent / suivant"
-
-msgid "contentnavigation_prevnext_description"
-msgstr ""
-"affiche des liens permettant de passer d'une entité à une autre sur les "
-"entités implémentant l'interface \"précédent/suivant\"."
-
-msgid "contentnavigation_seealso"
-msgstr "voir aussi"
-
-msgid "contentnavigation_seealso_description"
-msgstr ""
-"section affichant les entités liées par la relation \"voir aussi\" si "
-"l'entité supporte cette relation."
-
-msgid "contentnavigation_wfhistory"
-msgstr "historique du workflow."
-
-msgid "contentnavigation_wfhistory_description"
-msgstr ""
-"section affichant l'historique du workflow pour les entités ayant un "
-"workflow."
-
 msgid "context"
 msgstr "contexte"
 
@@ -1651,6 +1593,11 @@
 msgstr "création relation %(linkto)s"
 
 msgid ""
+"creating CWSourceHostConfig (CWSourceHostConfig cw_host_config_of CWSource "
+"%(linkto)s)"
+msgstr "création d'une configuration d'hôte pour la source %(linkto)s"
+
+msgid ""
 "creating CWUniqueTogetherConstraint (CWUniqueTogetherConstraint "
 "constraint_of CWEType %(linkto)s)"
 msgstr "création d'une contrainte unique_together sur %(linkto)s"
@@ -1776,6 +1723,124 @@
 msgid "csv export"
 msgstr "export CSV"
 
+msgid "ctxcomponents"
+msgstr "composants contextuels"
+
+msgid "ctxcomponents_anonuserlink"
+msgstr "lien utilisateur"
+
+msgid "ctxcomponents_anonuserlink_description"
+msgstr ""
+"affiche un lien vers le formulaire d'authentification pour les utilisateurs "
+"anonymes, sinon une boite contenant notamment des liens propres à "
+"l'utilisateur connectés"
+
+msgid "ctxcomponents_appliname"
+msgstr "titre de l'application"
+
+msgid "ctxcomponents_appliname_description"
+msgstr "affiche le titre de l'application dans l'en-tête de page"
+
+msgid "ctxcomponents_bookmarks_box"
+msgstr "boîte signets"
+
+msgid "ctxcomponents_bookmarks_box_description"
+msgstr "boîte contenant les signets de l'utilisateur"
+
+msgid "ctxcomponents_breadcrumbs"
+msgstr "fil d'ariane"
+
+msgid "ctxcomponents_breadcrumbs_description"
+msgstr ""
+"affiche un chemin permettant de localiser la page courante dans le site"
+
+msgid "ctxcomponents_download_box"
+msgstr "boîte de téléchargement"
+
+msgid "ctxcomponents_download_box_description"
+msgstr "boîte contenant un lien permettant de télécharger la ressource"
+
+msgid "ctxcomponents_edit_box"
+msgstr "boîte d'actions"
+
+msgid "ctxcomponents_edit_box_description"
+msgstr ""
+"boîte affichant les différentes actions possibles sur les données affichées"
+
+msgid "ctxcomponents_facet.filters"
+msgstr "boîte à facettes"
+
+msgid "ctxcomponents_facet.filters_description"
+msgstr ""
+"boîte permettant de filtrer parmi les résultats d'une recherche à l'aide de "
+"facettes"
+
+msgid "ctxcomponents_logo"
+msgstr "logo"
+
+msgid "ctxcomponents_logo_description"
+msgstr "le logo de l'application, dans l'en-tête de page"
+
+msgid "ctxcomponents_metadata"
+msgstr "méta-données de l'entité"
+
+msgid "ctxcomponents_metadata_description"
+msgstr ""
+
+msgid "ctxcomponents_possible_views_box"
+msgstr "boîte des vues possibles"
+
+msgid "ctxcomponents_possible_views_box_description"
+msgstr "boîte affichant les vues possibles pour les données courantes"
+
+msgid "ctxcomponents_prevnext"
+msgstr "élément précedent / suivant"
+
+msgid "ctxcomponents_prevnext_description"
+msgstr ""
+"affiche des liens permettant de passer d'une entité à une autre sur les "
+"entités implémentant l'interface \"précédent/suivant\"."
+
+msgid "ctxcomponents_rss"
+msgstr "icône RSS"
+
+msgid "ctxcomponents_rss_description"
+msgstr "l'icône RSS permettant de récupérer la vue RSS des données affichées"
+
+msgid "ctxcomponents_search_box"
+msgstr "boîte de recherche"
+
+msgid "ctxcomponents_search_box_description"
+msgstr "boîte avec un champ de recherche simple"
+
+msgid "ctxcomponents_seealso"
+msgstr "voir aussi"
+
+msgid "ctxcomponents_seealso_description"
+msgstr ""
+"section affichant les entités liées par la relation \"voir aussi\" si "
+"l'entité supporte cette relation."
+
+msgid "ctxcomponents_startup_views_box"
+msgstr "boîte des vues de départs"
+
+msgid "ctxcomponents_startup_views_box_description"
+msgstr "boîte affichant les vues de départs de l'application"
+
+msgid "ctxcomponents_userstatus"
+msgstr "état de l'utilisateur"
+
+msgid "ctxcomponents_userstatus_description"
+msgstr ""
+
+msgid "ctxcomponents_wfhistory"
+msgstr "historique du workflow."
+
+msgid "ctxcomponents_wfhistory_description"
+msgstr ""
+"section affichant l'historique du workflow pour les entités ayant un "
+"workflow."
+
 msgid "ctxtoolbar"
 msgstr "barre d'outils"
 
@@ -1785,6 +1850,72 @@
 msgid "custom_workflow_object"
 msgstr "workflow de"
 
+msgid "cw_dont_cross"
+msgstr "don't cross"
+
+msgctxt "CWSource"
+msgid "cw_dont_cross"
+msgstr "don't cross"
+
+msgid "cw_dont_cross_object"
+msgstr "can't be crossed with"
+
+msgctxt "CWRType"
+msgid "cw_dont_cross_object"
+msgstr "can't be crossed with"
+
+msgid "cw_host_config_of"
+msgstr "host configuration of"
+
+msgctxt "CWSourceHostConfig"
+msgid "cw_host_config_of"
+msgstr "host configuration of"
+
+msgid "cw_host_config_of_object"
+msgstr "has host configuration"
+
+msgctxt "CWSource"
+msgid "cw_host_config_of_object"
+msgstr "has host configuration"
+
+msgid "cw_may_cross"
+msgstr "may cross"
+
+msgctxt "CWSource"
+msgid "cw_may_cross"
+msgstr "may cross"
+
+msgid "cw_may_cross_object"
+msgstr "may be crossed with"
+
+msgctxt "CWRType"
+msgid "cw_may_cross_object"
+msgstr "may be crossed with"
+
+msgid "cw_source"
+msgstr "from data source"
+
+msgid "cw_source_object"
+msgstr "entities"
+
+msgid "cw_support"
+msgstr "support"
+
+msgctxt "CWSource"
+msgid "cw_support"
+msgstr "support"
+
+msgid "cw_support_object"
+msgstr "supported by"
+
+msgctxt "CWEType"
+msgid "cw_support_object"
+msgstr "supported by"
+
+msgctxt "CWRType"
+msgid "cw_support_object"
+msgstr "supported by"
+
 msgid "cwetype-box"
 msgstr "vue \"boîte\""
 
@@ -2195,10 +2326,6 @@
 msgid "error while embedding page"
 msgstr "erreur pendant l'inclusion de la page"
 
-#, python-format
-msgid "error while handling __method: %s"
-msgstr "erreur survenue lors du traitement de formulaire (%s)"
-
 msgid "error while publishing ReST text"
 msgstr ""
 "une erreur s'est produite lors de l'interprétation du texte au format ReST"
@@ -2245,6 +2372,9 @@
 msgid "external page"
 msgstr "page externe"
 
+msgid "facet.filters"
+msgstr "facettes"
+
 msgid "facetbox"
 msgstr "boîte à facettes"
 
@@ -2254,6 +2384,12 @@
 msgid "facets_created_by-facet_description"
 msgstr ""
 
+msgid "facets_cw_source-facet"
+msgstr "facette \"source de données\""
+
+msgid "facets_cw_source-facet_description"
+msgstr ""
+
 msgid "facets_cwfinal-facet"
 msgstr "facette \"type d'entité ou de relation final\""
 
@@ -2465,8 +2601,11 @@
 msgid "has_text"
 msgstr "contient le texte"
 
-msgid "help"
-msgstr "aide"
+msgid "header-center"
+msgstr "en-tête (centre)"
+
+msgid "header-right"
+msgstr "en-tête (droite)"
 
 msgid "hide filter form"
 msgstr "cacher le filtre"
@@ -2791,6 +2930,9 @@
 msgid "login"
 msgstr "identifiant"
 
+msgid "login / password"
+msgstr "identifiant / mot de passe"
+
 msgid "login or email"
 msgstr "identifiant ou email"
 
@@ -2835,6 +2977,13 @@
 msgid "march"
 msgstr "mars"
 
+msgid "match_host"
+msgstr "pour l'hôte"
+
+msgctxt "CWSourceHostConfig"
+msgid "match_host"
+msgstr "pour l'hôte"
+
 msgid "maximum number of characters in short description"
 msgstr "nombre maximum de caractères dans les descriptions courtes"
 
@@ -2915,6 +3064,10 @@
 msgid "name"
 msgstr "nom"
 
+msgctxt "CWSource"
+msgid "name"
+msgstr "nom"
+
 msgctxt "State"
 msgid "name"
 msgstr "nom"
@@ -2941,6 +3094,9 @@
 "nom des variables principales qui devrait être utilisées dans la sélection "
 "si nécessaire (les séparer par des virgules)"
 
+msgid "name of the source"
+msgstr "nom de la source"
+
 msgid "name or identifier of the permission"
 msgstr "nom (identifiant) de la permission"
 
@@ -3135,9 +3291,6 @@
 msgid "possible views"
 msgstr "vues possibles"
 
-msgid "powered by CubicWeb"
-msgstr "construit avec CubicWeb"
-
 msgid "prefered_form"
 msgstr "forme préférée"
 
@@ -3222,6 +3375,10 @@
 msgid "read_permission_object"
 msgstr "peut lire"
 
+msgid "regexp matching host(s) to which this config applies"
+msgstr ""
+"expression régulière des noms d'hôtes auxquels cette configuration s'applique"
+
 msgid "registry"
 msgstr "registre"
 
@@ -3399,6 +3556,9 @@
 msgid "security"
 msgstr "sécurité"
 
+msgid "see more"
+msgstr "voir plus"
+
 msgid "see them all"
 msgstr "les voir toutes"
 
@@ -3500,6 +3660,14 @@
 msgid "sorry, the server is unable to handle this query"
 msgstr "désolé, le serveur ne peut traiter cette requête"
 
+msgid ""
+"source's configuration. One key=value per line, authorized keys depending on "
+"the source's type"
+msgstr ""
+"Configuration de la source. Une clé=valeur par ligne, les clés autorisées "
+"dépendantes du type de source. Les valeur surchargent celles définies sur la "
+"source."
+
 msgid "sparql xml"
 msgstr "XML Sparql"
 
@@ -3824,6 +3992,10 @@
 msgid "type"
 msgstr "type"
 
+msgctxt "CWSource"
+msgid "type"
+msgstr "type"
+
 msgctxt "Transition"
 msgid "type"
 msgstr "type"
@@ -3835,6 +4007,9 @@
 msgid "type here a sparql query"
 msgstr "Tapez une requête sparql"
 
+msgid "type of the source"
+msgstr "type de la source"
+
 msgid "ui"
 msgstr "propriétés génériques de l'interface"
 
@@ -4185,27 +4360,3 @@
 
 msgid "you should probably delete that property"
 msgstr "vous devriez probablement supprimer cette propriété"
-
-#~ msgid "add_perm"
-#~ msgstr "ajout"
-
-#~ msgid "delete_perm"
-#~ msgstr "suppression"
-
-#~ msgid "edition"
-#~ msgstr "édition"
-
-#~ msgid "graphical workflow for %s"
-#~ msgstr "graphique du workflow pour %s"
-
-#~ msgid "personnal informations"
-#~ msgstr "informations personnelles"
-
-#~ msgid "read_perm"
-#~ msgstr "lecture"
-
-#~ msgid "update_perm"
-#~ msgstr "modification"
-
-#~ msgid "yams type, rdf type or mime type of the object"
-#~ msgstr "type yams, vocabulaire rdf ou type mime de l'objet"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.10.0_Any.py	Wed Oct 13 08:37:21 2010 +0200
@@ -0,0 +1,36 @@
+from cubicweb.server.session import hooks_control
+
+for uri, cfg in config.sources().items():
+    if uri in ('system', 'admin'):
+        continue
+    repo.sources_by_uri[uri] = repo.get_source(cfg['adapter'], uri, cfg)
+
+add_entity_type('CWSource')
+add_relation_definition('CWSource', 'cw_source', 'CWSource')
+add_entity_type('CWSourceHostConfig')
+
+with hooks_control(session, session.HOOKS_ALLOW_ALL, 'cw.sources'):
+    create_entity('CWSource', type=u'native', name=u'system')
+commit()
+
+sql('INSERT INTO cw_source_relation(eid_from,eid_to) '
+    'SELECT e.eid,s.cw_eid FROM entities as e, cw_CWSource as s '
+    'WHERE s.cw_name=e.type')
+commit()
+
+for uri, cfg in config.sources().items():
+    if uri in ('system', 'admin'):
+        continue
+    repo.sources_by_uri.pop(uri)
+    config = u'\n'.join('%s=%s' % (key, value) for key, value in cfg.items()
+                        if key != 'adapter')
+    create_entity('CWSource', name=unicode(uri), type=unicode(cfg['adapter']),
+                  config=config)
+commit()
+
+# rename cwprops for boxes/contentnavigation
+for x in rql('Any X,XK WHERE X pkey XK, '
+             'X pkey ~= "boxes.%s" OR '
+             'X pkey ~= "contentnavigation.%s"').entities():
+    x.set_attributes(pkey=u'ctxcomponents.' + x.pkey.split('.', 1)[1])
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.10.0_common.py	Wed Oct 13 08:37:21 2010 +0200
@@ -0,0 +1,1 @@
+option_group_changed('cleanup-session-time', 'web', 'main')
--- a/misc/migration/postcreate.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/misc/migration/postcreate.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,9 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""cubicweb post creation script, set user's workflow
+"""cubicweb post creation script, set user's workflow"""
 
-"""
 # insert versions
 create_entity('CWProperty', pkey=u'system.version.cubicweb',
               value=unicode(config.cubicweb_version()))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/scripts/cwuser_ldap2system.py	Wed Oct 13 08:37:21 2010 +0200
@@ -0,0 +1,40 @@
+import base64
+from cubicweb.server.utils import crypt_password
+
+dbdriver  = config.sources()['system']['db-driver']
+from logilab.database import get_db_helper
+dbhelper = get_db_helper(driver)
+
+insert = ('INSERT INTO cw_cwuser (cw_creation_date,'
+          '                       cw_eid,'
+          '                       cw_modification_date,'
+          '                       cw_login,'
+          '                       cw_firstname,'
+          '                       cw_surname,'
+          '                       cw_last_login_time,' 
+          '                       cw_upassword,'
+          '                       cw_cwuri) '
+          "VALUES (%(mtime)s, %(eid)s, %(mtime)s, %(login)s, "
+          "        %(firstname)s, %(surname)s, %(mtime)s, %(pwd)s, 'foo');")
+update = "UPDATE entities SET source='system' WHERE eid=%(eid)s;"
+rset = sql("SELECT eid,type,source,extid,mtime FROM entities WHERE source!='system'", ask_confirm=False)
+for eid, type, source, extid, mtime in rset:
+    if type != 'CWUser':
+        print "don't know what to do with entity type", type
+        continue
+    if not source.lower().startswith('ldap'):
+        print "don't know what to do with source type", source
+        continue
+    extid = base64.decodestring(extid)
+    ldapinfos = [x.strip().split('=') for x in extid.split(',')]
+    login = ldapinfos[0][1]
+    firstname = login.capitalize()
+    surname = login.capitalize()
+    args = dict(eid=eid, type=type, source=source, login=login,
+                firstname=firstname, surname=surname, mtime=mtime,
+                pwd=dbhelper.binary_value(crypt_password('toto')))
+    print args
+    sql(insert, args)
+    sql(update, args)
+
+commit()
--- a/rset.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/rset.py	Wed Oct 13 08:37:21 2010 +0200
@@ -484,7 +484,7 @@
                         if attr == 'eid':
                             entity.eid = rowvalues[outerselidx]
                         else:
-                            entity[attr] = rowvalues[outerselidx]
+                            entity.cw_attr_cache[attr] = rowvalues[outerselidx]
                         continue
                 else:
                     rschema = eschema.objrels[attr]
--- a/schema.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/schema.py	Wed Oct 13 08:37:21 2010 +0200
@@ -49,16 +49,26 @@
 # set of meta-relations available for every entity types
 META_RTYPES = set((
     'owned_by', 'created_by', 'is', 'is_instance_of', 'identity',
-    'eid', 'creation_date', 'modification_date', 'has_text', 'cwuri',
+    'eid', 'creation_date', 'cw_source', 'modification_date', 'has_text', 'cwuri',
     ))
 WORKFLOW_RTYPES = set(('custom_workflow', 'in_state', 'wf_info_for'))
-SYSTEM_RTYPES = set(('require_permission',)) | WORKFLOW_RTYPES
+WORKFLOW_DEF_RTYPES = set(('workflow_of', 'state_of', 'transition_of',
+                           'initial_state', 'default_workflow',
+                           'allowed_transition', 'destination_state',
+                           'from_state', 'to_state', 'condition',
+                           'subworkflow', 'subworkflow_state', 'subworkflow_exit',
+                           ))
+SYSTEM_RTYPES = set(('in_group', 'require_group', 'require_permission',
+                     # cwproperty
+                     'for_user',
+                     )) | WORKFLOW_RTYPES
 
 # set of entity and relation types used to build the schema
 SCHEMA_TYPES = set((
     'CWEType', 'CWRType', 'CWAttribute', 'CWRelation',
     'CWConstraint', 'CWConstraintType', 'CWUniqueTogetherConstraint',
     'RQLExpression',
+    'specializes',
     'relation_type', 'from_entity', 'to_entity',
     'constrained_by', 'cstrtype',
     'constraint_of', 'relations',
@@ -70,7 +80,9 @@
                       'WorkflowTransition', 'BaseTransition',
                       'SubWorkflowExitPoint'))
 
-INTERNAL_TYPES = set(('CWProperty', 'CWPermission', 'CWCache', 'ExternalUri'))
+INTERNAL_TYPES = set(('CWProperty', 'CWPermission', 'CWCache', 'ExternalUri',
+                      'CWSource', 'CWSourceAlias',
+))
 
 
 _LOGGER = getLogger('cubicweb.schemaloader')
--- a/schemas/base.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/schemas/base.py	Wed Oct 13 08:37:21 2010 +0200
@@ -20,8 +20,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
-from yams.buildobjs import (EntityType, RelationType, SubjectRelation,
-                            String, Datetime, Password)
+from yams.buildobjs import (EntityType, RelationType, RelationDefinition,
+                            SubjectRelation, String, Datetime, Password)
 from cubicweb.schema import (
     RQLConstraint, WorkflowableEntityType, ERQLExpression, RRQLExpression,
     PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS, PUB_SYSTEM_ATTR_PERMS)
@@ -62,7 +62,7 @@
         }
 
     alias   = String(fulltextindexed=True, maxsize=56)
-    address = String(required=True, fulltextindexed=True,
+    address = String(required=True,  fulltextindexed=True,
                      indexed=True, unique=True, maxsize=128)
     prefered_form = SubjectRelation('EmailAddress', cardinality='?*',
                                     description=_('when multiple addresses are equivalent \
@@ -198,6 +198,7 @@
     uri = String(required=True, unique=True, maxsize=256,
                  description=_('the URI of the object'))
 
+
 class same_as(RelationType):
     """generic relation to specify that an external entity represent the same
     object as a local one:
@@ -216,6 +217,7 @@
     #       in the cube's schema.
     object = 'ExternalUri'
 
+
 class CWCache(EntityType):
     """a simple cache entity characterized by a name and
     a validity date.
@@ -234,12 +236,74 @@
         'delete': ('managers',),
         }
 
-    name = String(required=True, unique=True, indexed=True,  maxsize=128,
+    name = String(required=True, unique=True, maxsize=128,
                   description=_('name of the cache'))
     timestamp = Datetime(default='NOW')
 
 
-# "abtract" relation types, not used in cubicweb itself
+class CWSource(EntityType):
+    name = String(required=True, unique=True, maxsize=128,
+                  description=_('name of the source'))
+    type = String(required=True, maxsize=20, description=_('type of the source'))
+    config = String(description=_('source\'s configuration. One key=value per '
+                                  'line, authorized keys depending on the '
+                                  'source\'s type'),
+                    __permissions__={
+                        'read':   ('managers',),
+                        'update': ('managers',),
+                        })
+
+
+class CWSourceHostConfig(EntityType):
+    __permissions__ = {
+        'read':   ('managers',),
+        'add':    ('managers',),
+        'update': ('managers',),
+        'delete': ('managers',),
+        }
+    match_host = String(required=True, unique=True, maxsize=128,
+                        description=_('regexp matching host(s) to which this config applies'))
+    config = String(required=True,
+                    description=_('Source\'s configuration for a particular host. '
+                                  'One key=value per line, authorized keys '
+                                  'depending on the source\'s type, overriding '
+                                  'values defined on the source.'),
+                    __permissions__={
+                        'read':   ('managers',),
+                        'update': ('managers',),
+                        })
+
+
+class cw_host_config_of(RelationDefinition):
+    subject = 'CWSourceHostConfig'
+    object = 'CWSource'
+    cardinality = '1*'
+    composite = 'object'
+    inlined = True
+
+class cw_source(RelationDefinition):
+    __permissions__ = {
+        'read':   ('managers', 'users', 'guests'),
+        'add':    (),
+        'delete': (),
+        }
+    subject = '*'
+    object = 'CWSource'
+    cardinality = '1*'
+
+class cw_support(RelationDefinition):
+    subject = 'CWSource'
+    object = ('CWEType', 'CWRType')
+
+class cw_dont_cross(RelationDefinition):
+    subject = 'CWSource'
+    object = 'CWRType'
+
+class cw_may_cross(RelationDefinition):
+    subject = 'CWSource'
+    object = 'CWRType'
+
+# "abtract" relation types, no definition in cubicweb itself ###################
 
 class identical_to(RelationType):
     """identical to"""
--- a/selectors.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/selectors.py	Wed Oct 13 08:37:21 2010 +0200
@@ -60,9 +60,9 @@
 
 .. sourcecode:: python
 
-  class RSSIconBox(ExtResourcesBoxTemplate):
+  class RSSIconBox(box.Box):
     ''' just display the RSS icon on uniform result set '''
-    __select__ = ExtResourcesBoxTemplate.__select__ & non_final_entity()
+    __select__ = box.Box.__select__ & non_final_entity()
 
 It takes into account:
 
@@ -478,6 +478,31 @@
             return score + 0.5
         return score
 
+
+class configuration_values(Selector):
+    """Return 1 if the instance has an option set to a given value(s) in its
+    configuration file.
+    """
+    # XXX this selector could be evaluated on startup
+    def __init__(self, key, values):
+        self._key = key
+        if not isinstance(values, (tuple, list)):
+            values = (values,)
+        self._values = frozenset(values)
+
+    @lltrace
+    def __call__(self, cls, req, **kwargs):
+        try:
+            return self._score
+        except AttributeError:
+            if req is None:
+                config = kwargs['repo'].config
+            else:
+                config = req.vreg.config
+            self._score = config[self._key] in self._values
+        return self._score
+
+
 # rset selectors ##############################################################
 
 @objectify_selector
@@ -533,12 +558,12 @@
 class multi_lines_rset(Selector):
     """Return 1 if the operator expression matches between `num` elements
     in the result set and the `expected` value if defined.
-    
+
     By default, multi_lines_rset(expected) matches equality expression:
         `nb` row(s) in result set equals to expected value
     But, you can perform richer comparisons by overriding default operator:
         multi_lines_rset(expected, operator.gt)
-    
+
     If `expected` is None, return 1 if the result set contains *at least*
     two rows.
     If rset is None, return 0.
@@ -604,7 +629,7 @@
 @lltrace
 def sorted_rset(cls, req, rset=None, **kwargs):
     """Return 1 for sorted result set (e.g. from an RQL query containing an
-    :ref:ORDERBY clause), with exception that it will return 0 if the rset is
+    ORDERBY clause), with exception that it will return 0 if the rset is
     'ORDERBY FTIRANK(VAR)' (eg sorted by rank value of the has_text index).
     """
     if rset is None:
@@ -801,21 +826,6 @@
             return 1
         self.score_entity = intscore
 
-class attribute_edited(EntitySelector):
-    """Scores if the specified attribute has been edited
-    This is useful for selection of forms by the edit controller.
-    The initial use case is on a form, in conjunction with match_transition,
-    which will not score at edit time::
-
-     is_instance('Version') & (match_transition('ready') |
-                               attribute_edited('publication_date'))
-    """
-    def __init__(self, attribute, once_is_enough=False):
-        super(attribute_edited, self).__init__(once_is_enough)
-        self._attribute = attribute
-
-    def score_entity(self, entity):
-        return eid_param(role_name(self._attribute, 'subject'), entity.eid) in entity._cw.form
 
 class has_mimetype(EntitySelector):
     """Return 1 if the entity adapt to IDownloadable and has the given MIME type.
@@ -1133,9 +1143,9 @@
     def __init__(self, expression, once_is_enough=False):
         super(rql_condition, self).__init__(once_is_enough)
         if 'U' in frozenset(split_expression(expression)):
-            rql = 'Any X WHERE X eid %%(x)s, U eid %%(u)s, %s' % expression
+            rql = 'Any COUNT(X) WHERE X eid %%(x)s, U eid %%(u)s, %s' % expression
         else:
-            rql = 'Any X WHERE X eid %%(x)s, %s' % expression
+            rql = 'Any COUNT(X) WHERE X eid %%(x)s, %s' % expression
         self.rql = rql
 
     def __repr__(self):
@@ -1143,11 +1153,32 @@
 
     def score(self, req, rset, row, col):
         try:
-            return len(req.execute(self.rql, {'x': rset[row][col],
-                                              'u': req.user.eid}))
+            return req.execute(self.rql, {'x': rset[row][col],
+                                          'u': req.user.eid})[0][0]
         except Unauthorized:
             return 0
 
+
+class is_in_state(score_entity):
+    """return 1 if entity is in one of the states given as argument list
+
+    you should use this instead of your own :class:`score_entity` selector to
+    avoid some gotchas:
+
+    * possible views gives a fake entity with no state
+    * you must use the latest tr info, not entity.in_state for repository side
+      checking of the current state
+    """
+    def __init__(self, *states):
+        def score(entity, states=set(states)):
+            trinfo = entity.cw_adapt_to('IWorkflowable').latest_trinfo()
+            try:
+                return trinfo.new_state.name in states
+            except AttributeError:
+                return None
+        super(is_in_state, self).__init__(score)
+
+
 # logged user selectors ########################################################
 
 @objectify_selector
@@ -1182,7 +1213,6 @@
     """
     return ~ authenticated_user()
 
-
 class match_user_groups(ExpectedValueSelector):
     """Return a non-zero score if request's user is in at least one of the
     groups given as initializer argument. Returned score is the number of groups
@@ -1212,9 +1242,9 @@
                 score = all(user.owns(r[col]) for r in rset)
         return score
 
-
 # Web request selectors ########################################################
 
+# XXX deprecate
 @objectify_selector
 @lltrace
 def primary_view(cls, req, view=None, **kwargs):
@@ -1232,6 +1262,15 @@
     return 1
 
 
+@objectify_selector
+@lltrace
+def contextual(cls, req, view=None, **kwargs):
+    """Return 1 if view's contextual property is true"""
+    if view is not None and view.contextual:
+        return 1
+    return 0
+
+
 class match_view(ExpectedValueSelector):
     """Return 1 if a view is specified an as its registry id is in one of the
     expected view id given to the initializer.
@@ -1243,6 +1282,19 @@
         return 1
 
 
+class match_context(ExpectedValueSelector):
+
+    @lltrace
+    def __call__(self, cls, req, context=None, **kwargs):
+        try:
+            if not context in self.expected:
+                return 0
+        except AttributeError:
+            return 1 # class doesn't care about search state, accept it
+        return 1
+
+
+# XXX deprecate
 @objectify_selector
 @lltrace
 def match_context_prop(cls, req, context=None, **kwargs):
@@ -1263,8 +1315,6 @@
         return 1
     propval = req.property_value('%s.%s.context' % (cls.__registry__,
                                                     cls.__regid__))
-    if not propval:
-        propval = cls.context
     if propval and context != propval:
         return 0
     return 1
@@ -1346,13 +1396,31 @@
         return 0
 
 
+class attribute_edited(EntitySelector):
+    """Scores if the specified attribute has been edited This is useful for
+    selection of forms by the edit controller.
+
+    The initial use case is on a form, in conjunction with match_transition,
+    which will not score at edit time::
+
+     is_instance('Version') & (match_transition('ready') |
+                               attribute_edited('publication_date'))
+    """
+    def __init__(self, attribute, once_is_enough=False):
+        super(attribute_edited, self).__init__(once_is_enough)
+        self._attribute = attribute
+
+    def score_entity(self, entity):
+        return eid_param(role_name(self._attribute, 'subject'), entity.eid) in entity._cw.form
+
+
 # Other selectors ##############################################################
 
 
 class match_transition(ExpectedValueSelector):
-    """Return 1 if `transition` argument is found in the input context
-      which has a `.name` attribute matching one of the expected names
-      given to the initializer
+    """Return 1 if `transition` argument is found in the input context which has
+    a `.name` attribute matching one of the expected names given to the
+    initializer.
     """
     @lltrace
     def __call__(self, cls, req, transition=None, **kwargs):
@@ -1361,28 +1429,25 @@
             return 1
         return 0
 
-class is_in_state(score_entity):
-    """return 1 if entity is in one of the states given as argument list
-
-    you should use this instead of your own :class:`score_entity` selector to
-    avoid some gotchas:
 
-    * possible views gives a fake entity with no state
-    * you must use the latest tr info, not entity.in_state for repository side
-      checking of the current state
+class match_exception(ExpectedValueSelector):
+    """Return 1 if a view is specified an as its registry id is in one of the
+    expected view id given to the initializer.
     """
-    def __init__(self, *states):
-        def score(entity, states=set(states)):
-            trinfo = entity.cw_adapt_to('IWorkflowable').latest_trinfo()
-            try:
-                return trinfo.new_state.name in states
-            except AttributeError:
-                return None
-        super(is_in_state, self).__init__(score)
+    def __init__(self, *expected):
+        assert expected, self
+        self.expected = expected
+
+    @lltrace
+    def __call__(self, cls, req, exc=None, **kwargs):
+        if exc is not None and isinstance(exc, self.expected):
+            return 1
+        return 0
+
 
 @objectify_selector
 def debug_mode(cls, req, rset=None, **kwargs):
-    """Return 1 if running in debug mode"""
+    """Return 1 if running in debug mode."""
     return req.vreg.config.debugmode and 1 or 0
 
 ## deprecated stuff ############################################################
--- a/server/__init__.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/__init__.py	Wed Oct 13 08:37:21 2010 +0200
@@ -19,8 +19,8 @@
 (repository) side
 
 This module contains functions to initialize a new repository.
+"""
 
-"""
 from __future__ import with_statement
 
 __docformat__ = "restructuredtext en"
@@ -61,7 +61,6 @@
     else:
         DEBUG |= debugmode
 
-
 class debugged(object):
     """repository debugging context manager / decorator
 
@@ -132,7 +131,6 @@
     config.consider_user_state = False
     config.set_language = False
     # only enable the system source at initialization time
-    config.enabled_sources = ('system',)
     repo = Repository(config, vreg=vreg)
     schema = repo.schema
     sourcescfg = config.sources()
@@ -162,6 +160,12 @@
     sqlcnx.commit()
     sqlcnx.close()
     session = repo.internal_session()
+    # insert entity representing the system source
+    ssource = session.create_entity('CWSource', type=u'native', name=u'system')
+    repo.system_source.eid = ssource.eid
+    session.execute('SET X cw_source X WHERE X eid %(x)s', {'x': ssource.eid})
+    # insert base groups and default admin
+    print '-> inserting default user and default groups.'
     try:
         login = unicode(sourcescfg['admin']['login'])
         pwd = sourcescfg['admin']['password']
@@ -171,17 +175,18 @@
             login, pwd = manager_userpasswd(msg=msg, confirm=True)
         else:
             login, pwd = unicode(source['db-user']), source['db-password']
-    print '-> inserting default user and default groups.'
     # sort for eid predicatability as expected in some server tests
     for group in sorted(BASE_GROUPS):
-        session.execute('INSERT CWGroup X: X name %(name)s',
-                        {'name': unicode(group)})
-    create_user(session, login, pwd, 'managers')
+        session.create_entity('CWGroup', name=unicode(group))
+    admin = create_user(session, login, pwd, 'managers')
+    session.execute('SET X owned_by U WHERE X is IN (CWGroup,CWSource), U eid %(u)s',
+                    {'u': admin.eid})
     session.commit()
     repo.shutdown()
     # reloging using the admin user
     config._cubes = None # avoid assertion error
     repo, cnx = in_memory_cnx(config, login, password=pwd)
+    repo.system_source.eid = ssource.eid # redo this manually
     # trigger vreg initialisation of entity classes
     config.cubicweb_appobject_path = set(('entities',))
     config.cube_appobject_path = set(('entities',))
@@ -197,13 +202,7 @@
     initialize_schema(config, schema, handler)
     # yoo !
     cnx.commit()
-    config.enabled_sources = None
-    for uri, source_config in config.sources().items():
-        if uri in ('admin', 'system'):
-            # not an actual source or init_creating already called
-            continue
-        source = repo.get_source(uri, source_config)
-        source.init_creating()
+    repo.system_source.init_creating()
     cnx.commit()
     cnx.close()
     session.close()
--- a/server/hook.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/hook.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,37 +15,232 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Hooks management
+"""
+Generalities
+------------
+
+Paraphrasing the `emacs`_ documentation, let us say that hooks are an important
+mechanism for customizing an application. A hook is basically a list of
+functions to be called on some well-defined occasion (this is called `running
+the hook`).
+
+.. _`emacs`: http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html
+
+Hooks
+~~~~~
+
+In |cubicweb|, hooks are subclasses of the :class:`~cubicweb.server.hook.Hook`
+class. They are selected over a set of pre-defined `events` (and possibly more
+conditions, hooks being selectable appobjects like views and components).  They
+should implement a :meth:`~cubicweb.server.hook.Hook.__call__` method that will
+be called when the hook is triggered.
 
-This module defined the `Hook` class and registry and a set of abstract classes
-for operations.
+There are two families of events: data events (before / after any individual
+update of an entity / or a relation in the repository) and server events (such
+as server startup or shutdown).  In a typical application, most of the hooks are
+defined over data events.
+
+Also, some :class:`~cubicweb.server.hook.Operation` may be registered by hooks,
+which will be fired when the transaction is commited or rollbacked.
+
+The purpose of data event hooks is usually to complement the data model as
+defined in the schema, which is static by nature and only provide a restricted
+builtin set of dynamic constraints, with dynamic or value driven behaviours.
+For instance they can serve the following purposes:
+
+* enforcing constraints that the static schema cannot express (spanning several
+  entities/relations, exotic value ranges and cardinalities, etc.)
+
+* implement computed attributes
+
+It is functionally equivalent to a `database trigger`_, except that database
+triggers definition languages are not standardized, hence not portable (for
+instance, PL/SQL works with Oracle and PostgreSQL but not SqlServer nor Sqlite).
+
+.. _`database trigger`: http://en.wikipedia.org/wiki/Database_trigger
 
 
-Hooks are called before / after any individual update of entities / relations
-in the repository and on special events such as server startup or shutdown.
+.. hint::
+
+   It is a good practice to write unit tests for each hook. See an example in
+   :ref:`hook_test`
+
+Operations
+~~~~~~~~~~
+
+Operations are subclasses of the :class:`~cubicweb.server.hook.Operation` class
+that may be created by hooks and scheduled to happen just before (or after) the
+`precommit`, `postcommit` or `rollback` event. Hooks are being fired immediately
+on data operations, and it is sometime necessary to delay the actual work down
+to a time where all other hooks have run. Also while the order of execution of
+hooks is data dependant (and thus hard to predict), it is possible to force an
+order on operations.
+
+Operations may be used to:
+
+* implements a validation check which needs that all relations be already set on
+  an entity
+
+* process various side effects associated with a transaction such as filesystem
+  udpates, mail notifications, etc.
 
 
-Operations may be registered by hooks during a transaction, which will  be
-fired when the pool is commited or rollbacked.
+Events
+------
+
+Hooks are mostly defined and used to handle `dataflow`_ operations. It
+means as data gets in (entities added, updated, relations set or
+unset), specific events are issued and the Hooks matching these events
+are called.
+
+You can get the event that triggered a hook by accessing its :attr:event
+attribute.
+
+.. _`dataflow`: http://en.wikipedia.org/wiki/Dataflow
 
 
-Entity hooks (eg before_add_entity, after_add_entity, before_update_entity,
-after_update_entity, before_delete_entity, after_delete_entity) all have an
-`entity` attribute
+Entity modification related events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When called for one of these events, hook will have an `entity` attribute
+containing the entity instance.
+
+* 'before_add_entity', 'before_update_entity':
+
+  - on those events, you can check what attributes of the entity are modified in
+    `entity.cw_edited` (by definition the database is not yet updated in a before
+    event)
+
+  - you are allowed to further modify the entity before database operations,
+    using the dictionary notation. By doing this, you'll avoid the need for a
+    whole new rql query processing, the only difference is that the underlying
+    backend query (eg usually sql) will contains the additional data. For
+    example:
+
+    .. sourcecode:: python
+
+       self.entity.set_attributes(age=42)
+
+    will set the `age` attribute of the entity to 42. But to do so, it will
+    generate a rql query that will have to be processed, then trigger some
+    hooks, and so one (potentially leading to infinite hook loops or such
+    awkward situations..) You can avoid this by doing the modification that way:
+
+    .. sourcecode:: python
+
+       self.entity.cw_edited['age'] = 42
+
+    Here the attribute will simply be edited in the same query that the
+    one that triggered the hook.
 
-Relation (eg before_add_relation, after_add_relation, before_delete_relation,
-after_delete_relation) all have `eidfrom`, `rtype`, `eidto` attributes.
+    Similarly, removing an attribute from `cw_edited` will cancel its
+    modification.
+
+  - on 'before_update_entity' event, you can access to old and new values in
+    this hook, by using `entity.cw_edited.oldnewvalue(attr)`
+
+
+* 'after_add_entity', 'after_update_entity'
+
+  - on those events, you can still check what attributes of the entity are
+    modified in `entity.cw_edited` but you can't get anymore the old value, nor
+    modify it.
+
+* 'before_delete_entity', 'after_delete_entity'
+
+  - on those events, the entity has no `cw_edited` set.
+
+
+Relation modification related events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When called for one of these events, hook will have `eidfrom`, `rtype`, `eidto`
+attributes containing respectivly the eid of the subject entity, the relation
+type and the eid of the object entity.
+
+* 'before_add_relation', 'before_delete_relation'
+
+  - on those events, you can still get original relation by issuing a rql query
+
+* 'after_add_relation', 'after_delete_relation'
+
+This is an occasion to remind us that relations support the add / delete
+operation, but no update.
+
 
-Server start/maintenance/stop hooks (eg server_startup, server_maintenance,
-server_shutdown) have a `repo` attribute, but *their `_cw` attribute is None*.
-The `server_startup` is called on regular startup, while `server_maintenance`
-is called on cubicweb-ctl upgrade or shell commands. `server_shutdown` is
-called anyway.
+Non data events
+~~~~~~~~~~~~~~~
+
+Hooks called on server start/maintenance/stop event (eg 'server_startup',
+'server_maintenance', 'server_shutdown') have a `repo` attribute, but *their
+`_cw` attribute is None*.  The `server_startup` is called on regular startup,
+while `server_maintenance` is called on cubicweb-ctl upgrade or shell
+commands. `server_shutdown` is called anyway.
+
+Hooks called on backup/restore event (eg 'server_backup', 'server_restore') have
+a `repo` and a `timestamp` attributes, but *their `_cw` attribute is None*.
+
+Hooks called on session event (eg 'session_open', 'session_close') have no
+special attribute.
+
+
+API
+---
+
+Hooks control
+~~~~~~~~~~~~~
+
+It is sometimes convenient to explicitly enable or disable some hooks. For
+instance if you want to disable some integrity checking hook.  This can be
+controlled more finely through the `category` class attribute, which is a string
+giving a category name.  One can then uses the
+:class:`~cubicweb.server.session.hooks_control` context manager to explicitly
+enable or disable some categories.
+
+.. autoclass:: cubicweb.server.session.hooks_control
+
+
+The existing categories are:
+
+* ``security``, security checking hooks
 
-Backup/restore hooks (eg server_backup, server_restore) have a `repo` and a
-`timestamp` attributes, but *their `_cw` attribute is None*.
+* ``worfklow``, workflow handling hooks
+
+* ``metadata``, hooks setting meta-data on newly created entities
+
+* ``notification``, email notification hooks
+
+* ``integrity``, data integrity checking hooks
+
+* ``activeintegrity``, data integrity consistency hooks, that you should *never*
+  want to disable
+
+* ``syncsession``, hooks synchronizing existing sessions
+
+* ``syncschema``, hooks synchronizing instance schema (including the physical database)
+
+* ``email``, email address handling hooks
+
+* ``bookmark``, bookmark entities handling hooks
 
-Session hooks (eg session_open, session_close) have no special attribute.
+
+Nothing precludes one to invent new categories and use the
+:class:`~cubicweb.server.session.hooks_control` context manager to filter them
+in or out.
+
+
+Hooks specific selector
+~~~~~~~~~~~~~~~~~~~~~~~
+.. autoclass:: cubicweb.server.hook.match_rtype
+.. autoclass:: cubicweb.server.hook.match_rtype_sets
+
+
+Hooks and operations classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. autoclass:: cubicweb.server.hook.Hook
+.. autoclass:: cubicweb.server.hook.Operation
+.. autoclass:: cubicweb.server.hook.DataOperation
+.. autoclass:: cubicweb.server.hook.LateOperation
 """
 
 from __future__ import with_statement
@@ -61,6 +256,7 @@
 from logilab.common.logging_ext import set_log_methods
 
 from cubicweb import RegistryNotFound
+from cubicweb.vregistry import classid
 from cubicweb.cwvreg import CWRegistry, VRegistry
 from cubicweb.selectors import (objectify_selector, lltrace, ExpectedValueSelector,
                                 is_instance)
@@ -83,7 +279,7 @@
         for appobjects in self.values():
             for cls in appobjects:
                 if not cls.enabled:
-                    warn('[3.6] %s: enabled is deprecated' % cls)
+                    warn('[3.6] %s: enabled is deprecated' % classid(cls))
                     self.unregister(cls)
 
     def register(self, obj, **kwargs):
@@ -119,21 +315,9 @@
 for event in ALL_HOOKS:
     VRegistry.REGISTRY_FACTORY['%s_hooks' % event] = HooksRegistry
 
-_MARKER = object()
+@deprecated('[3.10] use entity.cw_edited.oldnewvalue(attr)')
 def entity_oldnewvalue(entity, attr):
-    """returns the couple (old attr value, new attr value)
-
-    NOTE: will only work in a before_update_entity hook
-    """
-    # get new value and remove from local dict to force a db query to
-    # fetch old value
-    newvalue = entity.pop(attr, _MARKER)
-    oldvalue = getattr(entity, attr)
-    if newvalue is not _MARKER:
-        entity[attr] = newvalue
-    else:
-        newvalue = oldvalue
-    return oldvalue, newvalue
+    return entity.cw_edited.oldnewvalue(attr)
 
 
 # some hook specific selectors #################################################
@@ -203,6 +387,29 @@
 # base class for hook ##########################################################
 
 class Hook(AppObject):
+    """Base class for hook.
+
+    Hooks being appobjects like views, they have a `__regid__` and a `__select__`
+    class attribute. Like all appobjects, hooks have the `self._cw` attribute which
+    represents the current session. In entity hooks, a `self.entity` attribute is
+    also present.
+
+    The `events` tuple is used by the base class selector to dispatch the hook
+    on the right events. It is possible to dispatch on multiple events at once
+    if needed (though take care as hook attribute may vary as described above).
+
+    .. Note::
+
+      Do not forget to extend the base class selectors as in ::
+
+      .. sourcecode:: python
+
+          class MyHook(Hook):
+            __regid__ = 'whatever'
+            __select__ = Hook.__select__ & is_instance('Person')
+
+      else your hooks will be called madly, whatever the event.
+    """
     __select__ = enabled_category()
     # set this in derivated classes
     events = None
@@ -231,16 +438,16 @@
 
     @classproperty
     def __regid__(cls):
-        warn('[3.6] %s.%s: please specify an id for your hook'
-             % (cls.__module__, cls.__name__), DeprecationWarning)
+        warn('[3.6] %s: please specify an id for your hook' % classid(cls),
+             DeprecationWarning)
         return str(id(cls))
 
     @classmethod
     def __registered__(cls, reg):
         super(Hook, cls).__registered__(reg)
         if getattr(cls, 'accepts', None):
-            warn('[3.6] %s.%s: accepts is deprecated, define proper __select__'
-                 % (cls.__module__, cls.__name__), DeprecationWarning)
+            warn('[3.6] %s: accepts is deprecated, define proper __select__'
+                 % classid(cls), DeprecationWarning)
             rtypes = []
             for ertype in cls.accepts:
                 if ertype.islower():
@@ -261,9 +468,8 @@
 
     def __call__(self):
         if hasattr(self, 'call'):
-            cls = self.__class__
-            warn('[3.6] %s.%s: call is deprecated, implement __call__'
-                 % (cls.__module__, cls.__name__), DeprecationWarning)
+            warn('[3.6] %s: call is deprecated, implement __call__'
+                 % classid(self.__class__), DeprecationWarning)
             if self.event.endswith('_relation'):
                 self.call(self._cw, self.eidfrom, self.rtype, self.eidto)
             elif 'delete' in self.event:
@@ -392,40 +598,53 @@
 # abstract classes for operation ###############################################
 
 class Operation(object):
-    """an operation is triggered on connections pool events related to
+    """Base class for operations.
+
+    Operation may be instantiated in the hooks' `__call__` method. It always
+    takes a session object as first argument (accessible as `.session` from the
+    operation instance), and optionally all keyword arguments needed by the
+    operation. These keyword arguments will be accessible as attributes from the
+    operation instance.
+
+    An operation is triggered on connections pool events related to
     commit / rollback transations. Possible events are:
 
-    precommit:
-      the pool is preparing to commit. You shouldn't do anything which
-      has to be reverted if the commit fails at this point, but you can freely
-      do any heavy computation or raise an exception if the commit can't go.
-      You can add some new operations during this phase but their precommit
-      event won't be triggered
+    * 'precommit':
 
-    commit:
-      the pool is preparing to commit. You should avoid to do to expensive
-      stuff or something that may cause an exception in this event
+      the transaction is being prepared for commit. You can freely do any heavy
+      computation, raise an exception if the commit can't go. or even add some
+      new operations during this phase. If you do anything which has to be
+      reverted if the commit fails afterwards (eg altering the file system for
+      instance), you'll have to support the 'revertprecommit' event to revert
+      things by yourself
 
-    revertcommit:
-      if an operation failed while commited, this event is triggered for
-      all operations which had their commit event already to let them
-      revert things (including the operation which made fail the commit)
+    * 'revertprecommit':
+
+      if an operation failed while being pre-commited, this event is triggered
+      for all operations which had their 'precommit' event already fired to let
+      them revert things (including the operation which made the commit fail)
+
+    * 'rollback':
 
-    rollback:
       the transaction has been either rollbacked either:
+
        * intentionaly
-       * a precommit event failed, all operations are rollbacked
-       * a commit event failed, all operations which are not been triggered for
-         commit are rollbacked
+       * a 'precommit' event failed, in which case all operations are rollbacked
+         once 'revertprecommit'' has been called
+
+    * 'postcommit':
 
-    postcommit:
-      The transaction is over. All the ORM entities are
-      invalid. If you need to work on the database, you need to stard
-      a new transaction, for instance using a new internal_session,
-      which you will need to commit (and close!).
+      the transaction is over. All the ORM entities accessed by the earlier
+      transaction are invalid. If you need to work on the database, you need to
+      start a new transaction, for instance using a new internal session, which
+      you will need to commit (and close!).
 
-    order of operations may be important, and is controlled according to
-    the insert_index's method output
+    For an operation to support an event, one has to implement the `<event
+    name>_event` method with no arguments.
+
+    Notice order of operations may be important, and is controlled according to
+    the insert_index's method output (whose implementation vary according to the
+    base hook class used).
     """
 
     def __init__(self, session, **kwargs):
@@ -455,6 +674,10 @@
 
     def handle_event(self, event):
         """delegate event handling to the opertaion"""
+        if event == 'postcommit_event' and hasattr(self, 'commit_event'):
+            warn('[3.10] %s: commit_event method has been replaced by postcommit_event'
+                 % classid(self.__class__), DeprecationWarning)
+            self.commit_event()
         getattr(self, event)()
 
     def precommit_event(self):
@@ -467,16 +690,6 @@
         been all considered if it's this operation which failed
         """
 
-    def commit_event(self):
-        """the observed connections pool is commiting"""
-
-    def revertcommit_event(self):
-        """an error went when commiting this operation or a later one
-
-        should revert commit's changes but take care, they may have not
-        been all considered if it's this operation which failed
-        """
-
     def rollback_event(self):
         """the observed connections pool has been rollbacked
 
@@ -512,21 +725,146 @@
 def _container_add(container, value):
     {set: set.add, list: list.append}[container.__class__](container, value)
 
-def set_operation(session, datakey, value, opcls, containercls=set, **opkwargs):
-    """Search for session.transaction_data[`datakey`] (expected to be a set):
+
+class DataOperationMixIn(object):
+    """Mix-in class to ease applying a single operation on a set of data,
+    avoiding to create as many as operation as they are individual modification.
+    The body of the operation must then iterate over the values that have been
+    stored in a single operation instance.
+
+    You should try to use this instead of creating on operation for each
+    `value`, since handling operations becomes costly on massive data import.
+
+    Usage looks like:
+    .. sourcecode:: python
+
+        class MyEntityHook(Hook):
+            __regid__ = 'my.entity.hook'
+            __select__ = Hook.__select__ & is_instance('MyEntity')
+            events = ('after_add_entity',)
+
+            def __call__(self):
+                MyOperation.get_instance(self._cw).add_data(self.entity)
+
+
+        class MyOperation(DataOperation, DataOperationMixIn):
+            def precommit_event(self):
+                for bucket in self.get_data():
+                    process(bucket)
 
-    * if found, simply append `value`
+    You can modify the `containercls` class attribute, which defines the
+    container class that should be instantiated to hold payloads. An instance is
+    created on instantiation, and then the :meth:`add_data` method will add the
+    given data to the existing container. Default to a `set`. Give `list` if you
+    want to keep arrival ordering. You can also use another kind of container
+    by redefining :meth:`_build_container` and :meth:`add_data`
+
+    More optional parameters can be given to the `get_instance` operation, that
+    will be given to the operation constructer (though those parameters should
+    not vary accross different calls to this method for a same operation for
+    obvious reason).
+
+    .. Note::
+        For sanity reason `get_data` will reset the operation, so that once
+        the operation has started its treatment, if some hook want to push
+        additional data to this same operation, a new instance will be created
+        (else that data has a great chance to be never treated). This implies:
+
+        * you should **always** call `get_data` when starting treatment
+
+        * you should **never** call `get_data` for another reason.
+    """
+    containercls = set
+
+    @classproperty
+    def data_key(cls):
+        return ('cw.dataops', cls.__name__)
+
+    @classmethod
+    def get_instance(cls, session, **kwargs):
+        # no need to lock: transaction_data already comes from thread's local storage
+        try:
+            return session.transaction_data[cls.data_key]
+        except KeyError:
+            op = session.transaction_data[cls.data_key] = cls(session, **kwargs)
+            return op
 
-    * else, initialize it to containercls([`value`]) and instantiate the given
-      `opcls` operation class with additional keyword arguments. `containercls`
-      is a set by default. Give `list` if you want to keep arrival ordering.
+    def __init__(self, *args, **kwargs):
+        super(DataOperationMixIn, self).__init__(*args, **kwargs)
+        self._container = self._build_container()
+        self._processed = False
+
+    def __contains__(self, value):
+        return value in self._container
+
+    def _build_container(self):
+        return self.containercls()
+
+    def add_data(self, data):
+        assert not self._processed, """Trying to add data to a closed operation.
+Iterating over operation data closed it and should be reserved to precommit /
+postcommit method of the operation."""
+        _container_add(self._container, data)
+
+    def get_data(self):
+        assert not self._processed, """Trying to get data from a closed operation.
+Iterating over operation data closed it and should be reserved to precommit /
+postcommit method of the operation."""
+        self._processed = True
+        op = self.session.transaction_data.pop(self.data_key)
+        assert op is self, "Bad handling of operation data, found %s instead of %s for key %s" % (
+            op, self, self.data_key)
+        return self._container
+
 
-    You should use this instead of creating on operation for each `value`,
+@deprecated('[3.10] use opcls.get_instance(session, **opkwargs).add_data(value)')
+def set_operation(session, datakey, value, opcls, containercls=set, **opkwargs):
+    """Function to ease applying a single operation on a set of data, avoiding
+    to create as many as operation as they are individual modification. You
+    should try to use this instead of creating on operation for each `value`,
     since handling operations becomes coslty on massive data import.
+
+    Arguments are:
+
+    * the `session` object
+
+    * `datakey`, a specially forged key that will be used as key in
+      session.transaction_data
+
+    * `value` that is the actual payload of an individual operation
+
+    * `opcls`, the class of the operation. An instance is created on the first
+      call for the given key, and then subsequent calls will simply add the
+      payload to the container (hence `opkwargs` is only used on that first
+      call)
+
+    * `containercls`, the container class that should be instantiated to hold
+      payloads.  An instance is created on the first call for the given key, and
+      then subsequent calls will add the data to the existing container. Default
+      to a set. Give `list` if you want to keep arrival ordering.
+
+    * more optional parameters to give to the operation (here the rtype which do not
+      vary accross operations).
+
+    The body of the operation must then iterate over the values that have been mapped
+    in the transaction_data dictionary to the forged key, e.g.:
+
+    .. sourcecode:: python
+
+           for value in self._cw.transaction_data.pop(datakey):
+               ...
+
+    .. Note::
+       **poping** the key from `transaction_data` is not an option, else you may
+       get unexpected data loss in some case of nested hooks.
     """
     try:
+        # Search for session.transaction_data[`datakey`] (expected to be a set):
+        # if found, simply append `value`
         _container_add(session.transaction_data[datakey], value)
     except KeyError:
+        # else, initialize it to containercls([`value`]) and instantiate the given
+        # `opcls` operation class with additional keyword arguments
         opcls(session, **opkwargs)
         session.transaction_data[datakey] = containercls()
         _container_add(session.transaction_data[datakey], value)
@@ -551,8 +889,12 @@
         return -(i + 1)
 
 
-class SingleOperation(Operation):
-    """special operation which should be called once"""
+
+class SingleLastOperation(Operation):
+    """special operation which should be called once and after all other
+    operations
+    """
+
     def register(self, session):
         """override register to handle cases where this operation has already
         been added
@@ -573,11 +915,6 @@
                 return -(i+1)
         return None
 
-
-class SingleLastOperation(SingleOperation):
-    """special operation which should be called once and after all other
-    operations
-    """
     def insert_index(self):
         return None
 
@@ -599,7 +936,7 @@
         if previous:
             self.to_send = previous.to_send + self.to_send
 
-    def commit_event(self):
+    def postcommit_event(self):
         self.session.repo.threaded_task(self.sendmails)
 
     def sendmails(self):
@@ -613,7 +950,7 @@
             execute(*rql)
 
 
-class CleanupNewEidsCacheOp(SingleLastOperation):
+class CleanupNewEidsCacheOp(DataOperationMixIn, SingleLastOperation):
     """on rollback of a insert query we have to remove from repository's
     type/source cache eids of entities added in that transaction.
 
@@ -623,28 +960,27 @@
     too expensive. Notice that there is no pb when using args to specify eids
     instead of giving them into the rql string.
     """
+    data_key = 'neweids'
 
     def rollback_event(self):
         """the observed connections pool has been rollbacked,
         remove inserted eid from repository type/source cache
         """
         try:
-            self.session.repo.clear_caches(
-                self.session.transaction_data['neweids'])
+            self.session.repo.clear_caches(self.get_data())
         except KeyError:
             pass
 
-class CleanupDeletedEidsCacheOp(SingleLastOperation):
+class CleanupDeletedEidsCacheOp(DataOperationMixIn, SingleLastOperation):
     """on commit of delete query, we have to remove from repository's
     type/source cache eids of entities deleted in that transaction.
     """
-
-    def commit_event(self):
+    data_key = 'pendingeids'
+    def postcommit_event(self):
         """the observed connections pool has been rollbacked,
         remove inserted eid from repository type/source cache
         """
         try:
-            self.session.repo.clear_caches(
-                self.session.transaction_data['pendingeids'])
+            self.session.repo.clear_caches(self.get_data())
         except KeyError:
             pass
--- a/server/migractions.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/migractions.py	Wed Oct 13 08:37:21 2010 +0200
@@ -41,6 +41,7 @@
 from glob import glob
 from copy import copy
 from warnings import warn
+from contextlib import contextmanager
 
 from logilab.common.deprecation import deprecated
 from logilab.common.decorators import cached, clear_cache
@@ -48,6 +49,7 @@
 
 from yams.constraints import SizeConstraint
 from yams.schema2sql import eschema2sql, rschema2sql
+from yams.schema import RelationDefinitionSchema
 
 from cubicweb import AuthenticationError, ExecutionError
 from cubicweb.selectors import is_instance
@@ -61,7 +63,7 @@
 from cubicweb.server import hook
 try:
     from cubicweb.server import SOURCE_TYPES, schemaserial as ss
-    from cubicweb.server.utils import manager_userpasswd, ask_source_config
+    from cubicweb.server.utils import manager_userpasswd
     from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
 except ImportError: # LAX
     pass
@@ -640,13 +642,6 @@
         for cube in newcubes:
             self.cmd_set_property('system.version.'+cube,
                                   self.config.cube_version(cube))
-            if cube in SOURCE_TYPES:
-                # don't use config.sources() in case some sources have been
-                # disabled for migration
-                sourcescfg = self.config.read_sources_file()
-                sourcescfg[cube] = ask_source_config(cube)
-                self.config.write_sources_file(sourcescfg)
-                clear_cache(self.config, 'read_sources_file')
             # ensure added cube is in config cubes
             # XXX worth restoring on error?
             if not cube in self.config._cubes:
@@ -958,8 +953,7 @@
                     # get some validation error on commit since integrity hooks
                     # may think some required relation is missing... This also ensure
                     # repository caches are properly cleanup
-                    hook.set_operation(session, 'pendingeids', eid,
-                                       hook.CleanupDeletedEidsCacheOp)
+                    CleanupDeletedEidsCacheOp.get_instance(session).add_data(eid)
                     # and don't forget to remove record from system tables
                     self.repo.system_source.delete_info(
                         session, session.entity_from_eid(eid, rdeftype),
@@ -1116,11 +1110,20 @@
         """synchronize the persistent schema against the current definition
         schema.
 
+        `ertype` can be :
+        - None, in that case everything will be synced ;
+        - a string, it should be an entity type or
+          a relation type. In that case, only the corresponding
+          entities / relations will be synced ;
+        - an rdef object to synchronize only this specific relation definition
+
         It will synch common stuff between the definition schema and the
         actual persistent schema, it won't add/remove any entity or relation.
         """
         assert syncperms or syncprops, 'nothing to do'
         if ertype is not None:
+            if isinstance(ertype, RelationDefinitionSchema):
+                ertype = ertype.as_triple()
             if isinstance(ertype, (tuple, list)):
                 assert len(ertype) == 3, 'not a relation definition'
                 self._synchronize_rdef_schema(ertype[0], ertype[1], ertype[2],
@@ -1377,6 +1380,40 @@
         """add a new entity of the given type"""
         return self.cmd_create_entity(etype, *args, **kwargs).eid
 
+    @contextmanager
+    def cmd_dropped_constraints(self, etype, attrname, cstrtype,
+                                droprequired=False):
+        """context manager to drop constraints temporarily on fs_schema
+
+        `cstrtype` should be a constraint class (or a tuple of classes)
+        and will be passed to isinstance directly
+
+        For instance::
+
+            >>> with dropped_constraints('MyType', 'myattr',
+            ...                          UniqueConstraint, droprequired=True):
+            ...     add_attribute('MyType', 'myattr')
+            ...     # + instructions to fill MyType.myattr column
+            ...
+            >>>
+
+        """
+        rdef = self.fs_schema.eschema(etype).rdef(attrname)
+        original_constraints = rdef.constraints
+        # remove constraints
+        rdef.constraints = [cstr for cstr in original_constraints
+                            if not (cstrtype and isinstance(cstr, cstrtype))]
+        if droprequired:
+            original_cardinality = rdef.cardinality
+            rdef.cardinality = '?' + rdef.cardinality[1]
+        yield
+        # restore original constraints
+        rdef.constraints = original_constraints
+        if droprequired:
+            rdef.cardinality = original_cardinality
+        # update repository schema
+        self.cmd_sync_schema_props_perms(rdef, syncperms=False)
+
     def sqlexec(self, sql, args=None, ask_confirm=True):
         """execute the given sql if confirmed
 
--- a/server/msplanner.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/msplanner.py	Wed Oct 13 08:37:21 2010 +0200
@@ -84,9 +84,8 @@
   1. return the result of Any X WHERE X owned_by Y from system source, that's
      enough (optimization of the sql querier will avoid join on CWUser, so we
      will directly get local eids)
-
+"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from itertools import imap, ifilterfalse
@@ -94,6 +93,7 @@
 from logilab.common.compat import any
 from logilab.common.decorators import cached
 
+from rql import BadRQLQuery
 from rql.stmts import Union, Select
 from rql.nodes import (VariableRef, Comparison, Relation, Constant, Variable,
                        Not, Exists, SortTerm, Function)
@@ -434,11 +434,14 @@
         # add source for relations
         rschema = self._schema.rschema
         termssources = {}
+        sourcerels = []
         for rel in self.rqlst.iget_nodes(Relation):
             # process non final relations only
             # note: don't try to get schema for 'is' relation (not available
             # during bootstrap)
-            if not (rel.is_types_restriction() or rschema(rel.r_type).final):
+            if rel.r_type == 'cw_source':
+                sourcerels.append(rel)
+            elif not (rel.is_types_restriction() or rschema(rel.r_type).final):
                 # nothing to do if relation is not supported by multiple sources
                 # or if some source has it listed in its cross_relations
                 # attribute
@@ -469,6 +472,64 @@
                 self._handle_cross_relation(rel, relsources, termssources)
                 self._linkedterms.setdefault(lhsv, set()).add((rhsv, rel))
                 self._linkedterms.setdefault(rhsv, set()).add((lhsv, rel))
+        # extract information from cw_source relation
+        for srel in sourcerels:
+            vref = srel.children[1].children[0]
+            sourceeids, sourcenames = [], []
+            if isinstance(vref, Constant):
+                # simplified variable
+                sourceeids = None, (vref.eval(self.plan.args),)
+            else:
+                var = vref.variable
+                for rel in var.stinfo['relations'] - var.stinfo['rhsrelations']:
+                    if rel.r_type in ('eid', 'name'):
+                        if rel.r_type == 'eid':
+                            slist = sourceeids
+                        else:
+                            slist = sourcenames
+                        sources = [cst.eval(self.plan.args)
+                                   for cst in rel.children[1].get_nodes(Constant)]
+                        if sources:
+                            if slist:
+                                # don't attempt to do anything
+                                sourcenames = sourceeids = None
+                                break
+                            slist[:] = (rel, sources)
+            if sourceeids:
+                rel, values = sourceeids
+                sourcesdict = self._repo.sources_by_eid
+            elif sourcenames:
+                rel, values = sourcenames
+                sourcesdict = self._repo.sources_by_uri
+            else:
+                sourcesdict = None
+            if sourcesdict is not None:
+                lhs = srel.children[0]
+                try:
+                    sources = [sourcesdict[key] for key in values]
+                except KeyError:
+                    raise BadRQLQuery('source conflict for term %s' % lhs.as_string())
+                if isinstance(lhs, Constant):
+                    source = self._session.source_from_eid(lhs.eval(self.plan.args))
+                    if not source in sources:
+                        raise BadRQLQuery('source conflict for term %s' % lhs.as_string())
+                else:
+                    lhs = getattr(lhs, 'variable', lhs)
+                # XXX NOT NOT
+                neged = srel.neged(traverse_scope=True) or (rel and rel.neged(strict=True))
+                if neged:
+                    for source in sources:
+                        self._remove_source_term(source, lhs, check=True)
+                else:
+                    for source, terms in sourcesterms.items():
+                        if lhs in terms and not source in sources:
+                            self._remove_source_term(source, lhs, check=True)
+                if rel is None:
+                    self._remove_source_term(self.system_source, vref)
+                    srel.parent.remove(srel)
+                elif len(var.stinfo['relations']) == 2 and not var.stinfo['selected']:
+                    self._remove_source_term(self.system_source, var)
+                    self.rqlst.undefine_variable(var)
         return termssources
 
     def _handle_cross_relation(self, rel, relsources, termssources):
@@ -713,9 +774,18 @@
                 assert isinstance(term, (rqlb.BaseNode, Variable)), repr(term)
                 continue # may occur with subquery column alias
             if not sourcesterms[source][term]:
-                del sourcesterms[source][term]
-                if not sourcesterms[source]:
-                    del sourcesterms[source]
+                self._remove_source_term(source, term)
+
+    def _remove_source_term(self, source, term, check=False):
+        poped = self._sourcesterms[source].pop(term, None)
+        if not self._sourcesterms[source]:
+            del self._sourcesterms[source]
+        if poped is not None and check:
+            for terms in self._sourcesterms.itervalues():
+                if term in terms:
+                    break
+            else:
+                raise BadRQLQuery('source conflict for term %s' % term.as_string())
 
     def crossed_relation(self, source, relation):
         return relation in self._crossrelations.get(source, ())
--- a/server/pool.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/pool.py	Wed Oct 13 08:37:21 2010 +0200
@@ -34,7 +34,7 @@
         # dictionnary of (source, connection), indexed by sources'uri
         self.source_cnxs = {}
         for source in sources:
-            self.source_cnxs[source.uri] = (source, source.get_connection())
+            self.add_source(source)
         if not 'system' in self.source_cnxs:
             self.source_cnxs['system'] = self.source_cnxs[sources[0].uri]
         self._cursors = {}
@@ -50,6 +50,15 @@
                 self._cursors[uri] = cursor
         return cursor
 
+    def add_source(self, source):
+        assert not source.uri in self.source_cnxs
+        self.source_cnxs[source.uri] = (source, source.get_connection())
+
+    def remove_source(self, source):
+        source, cnx = self.source_cnxs.pop(source.uri)
+        cnx.close()
+        self._cursors.pop(source.uri, None)
+
     def commit(self):
         """commit the current transaction for this user"""
         # FIXME: what happends if a commit fail
@@ -144,11 +153,9 @@
         self._cursors.pop(source.uri, None)
 
 
-from cubicweb.server.hook import (Operation, LateOperation, SingleOperation,
-                                  SingleLastOperation)
+from cubicweb.server.hook import Operation, LateOperation, SingleLastOperation
 from logilab.common.deprecation import class_moved, class_renamed
 Operation = class_moved(Operation)
 PreCommitOperation = class_renamed('PreCommitOperation', Operation)
 LateOperation = class_moved(LateOperation)
-SingleOperation = class_moved(SingleOperation)
 SingleLastOperation = class_moved(SingleLastOperation)
--- a/server/querier.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/querier.py	Wed Oct 13 08:37:21 2010 +0200
@@ -38,7 +38,7 @@
 
 from cubicweb.server.utils import cleanup_solutions
 from cubicweb.server.rqlannotation import SQLGenAnnotator, set_qdata
-from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction
+from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction, EditedEntity
 from cubicweb.server.session import security_enabled
 
 def empty_rset(rql, args, rqlst=None):
@@ -450,7 +450,7 @@
         # save originaly selected variable, we may modify this
         # dictionary for substitution (query parameters)
         self.selected = rqlst.selection
-        # list of new or updated entities definition (utils.Entity)
+        # list of rows of entities definition (ssplanner.EditedEntity)
         self.e_defs = [[]]
         # list of new relation definition (3-uple (from_eid, r_type, to_eid)
         self.r_defs = set()
@@ -461,7 +461,6 @@
 
     def add_entity_def(self, edef):
         """add an entity definition to build"""
-        edef.querier_pending_relations = {}
         self.e_defs[-1].append(edef)
 
     def add_relation_def(self, rdef):
@@ -493,8 +492,9 @@
             self.e_defs[i][colidx] = edefs[0]
             samplerow = self.e_defs[i]
             for edef_ in edefs[1:]:
-                row = samplerow[:]
-                row[colidx] = edef_
+                row = [ed.clone() for i, ed in enumerate(samplerow)
+                       if i != colidx]
+                row.insert(colidx, edef_)
                 self.e_defs.append(row)
         # now, see if this entity def is referenced as subject in some relation
         # definition
@@ -560,15 +560,16 @@
             if isinstance(subj, basestring):
                 subj = typed_eid(subj)
             elif not isinstance(subj, (int, long)):
-                subj = subj.eid
+                subj = subj.entity.eid
             if isinstance(obj, basestring):
                 obj = typed_eid(obj)
             elif not isinstance(obj, (int, long)):
-                obj = obj.eid
+                obj = obj.entity.eid
             if repo.schema.rschema(rtype).inlined:
                 entity = session.entity_from_eid(subj)
-                entity[rtype] = obj
-                repo.glob_update_entity(session, entity, set((rtype,)))
+                edited = EditedEntity(entity)
+                edited.edited_attribute(rtype, obj)
+                repo.glob_update_entity(session, edited)
             else:
                 repo.glob_add_relation(session, subj, rtype, obj)
 
@@ -601,9 +602,7 @@
         self._parse = rqlhelper.parse
         self._annotate = rqlhelper.annotate
         # rql planner
-        # note: don't use repo.sources, may not be built yet, and also "admin"
-        #       isn't an actual source
-        if len([uri for uri in repo.config.sources() if uri != 'admin']) < 2:
+        if len(repo.sources) < 2:
             from cubicweb.server.ssplanner import SSPlanner
             self._planner = SSPlanner(schema, rqlhelper)
         else:
@@ -612,6 +611,14 @@
         # sql generation annotator
         self.sqlgen_annotate = SQLGenAnnotator(schema).annotate
 
+    def set_planner(self):
+        if len(self._repo.sources) < 2:
+            from cubicweb.server.ssplanner import SSPlanner
+            self._planner = SSPlanner(self.schema, self._repo.vreg.rqlhelper)
+        else:
+            from cubicweb.server.msplanner import MSPlanner
+            self._planner = MSPlanner(self.schema, self._repo.vreg.rqlhelper)
+
     def parse(self, rql, annotate=False):
         """return a rql syntax tree for the given rql"""
         try:
--- a/server/repository.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/repository.py	Wed Oct 13 08:37:21 2010 +0200
@@ -34,17 +34,19 @@
 import sys
 import threading
 import Queue
+from itertools import chain
 from os.path import join
 from datetime import datetime
 from time import time, localtime, strftime
 
-from logilab.common.decorators import cached
+from logilab.common.decorators import cached, clear_cache
 from logilab.common.compat import any
 from logilab.common import flatten
 
 from yams import BadSchemaDefinition
 from yams.schema import role_name
 from rql import RQLSyntaxError
+from rql.utils import rqlvar_maker
 
 from cubicweb import (CW_SOFTWARE_ROOT, CW_MIGRATION_MAP, QueryError,
                       UnknownEid, AuthenticationError, ExecutionError,
@@ -55,7 +57,29 @@
 from cubicweb.server import utils, hook, pool, querier, sources
 from cubicweb.server.session import Session, InternalSession, InternalManager, \
      security_enabled
-_ = unicode
+from cubicweb.server.ssplanner import EditedEntity
+
+def prefill_entity_caches(entity, relations):
+    session = entity._cw
+    # prefill entity relation caches
+    for rschema in entity.e_schema.subject_relations():
+        rtype = str(rschema)
+        if rtype in schema.VIRTUAL_RTYPES:
+            continue
+        if rschema.final:
+            entity.cw_attr_cache.setdefault(rtype, None)
+        else:
+            entity.cw_set_relation_cache(rtype, 'subject',
+                                         session.empty_rset())
+    for rschema in entity.e_schema.object_relations():
+        rtype = str(rschema)
+        if rtype in schema.VIRTUAL_RTYPES:
+            continue
+        entity.cw_set_relation_cache(rtype, 'object', session.empty_rset())
+    # set inlined relation cache before call to after_add_entity
+    for attr, value in relations:
+        session.update_rel_cache_add(entity.eid, attr, value)
+        del_existing_rel_if_needed(session, entity.eid, attr, value)
 
 def del_existing_rel_if_needed(session, eidfrom, rtype, eidto):
     """delete existing relation when adding a new one if card is 1 or ?
@@ -120,27 +144,15 @@
         # initial schema, should be build or replaced latter
         self.schema = schema.CubicWebSchema(config.appid)
         self.vreg.schema = self.schema # until actual schema is loaded...
-        # querier helper, need to be created after sources initialization
-        self.querier = querier.QuerierHelper(self, self.schema)
-        # sources
-        self.sources = []
-        self.sources_by_uri = {}
         # shutdown flag
         self.shutting_down = False
-        # FIXME: store additional sources info in the system database ?
-        # FIXME: sources should be ordered (add_entity priority)
-        for uri, source_config in config.sources().items():
-            if uri == 'admin':
-                # not an actual source
-                continue
-            source = self.get_source(uri, source_config)
-            self.sources_by_uri[uri] = source
-            if config.source_enabled(uri):
-                self.sources.append(source)
-        self.system_source = self.sources_by_uri['system']
-        # ensure system source is the first one
-        self.sources.remove(self.system_source)
-        self.sources.insert(0, self.system_source)
+        # sources (additional sources info in the system database)
+        self.system_source = self.get_source('native', 'system',
+                                             config.sources()['system'])
+        self.sources = [self.system_source]
+        self.sources_by_uri = {'system': self.system_source}
+        # querier helper, need to be created after sources initialization
+        self.querier = querier.QuerierHelper(self, self.schema)
         # cache eid -> type / source
         self._type_source_cache = {}
         # cache (extid, source uri) -> eid
@@ -192,6 +204,7 @@
             config.bootstrap_cubes()
             self.set_schema(config.load_schema())
         if not config.creating:
+            self.init_sources_from_database()
             if 'CWProperty' in self.schema:
                 self.vreg.init_properties(self.properties())
             # call source's init method to complete their initialisation if
@@ -208,7 +221,7 @@
         # close initialization pool and reopen fresh ones for proper
         # initialization now that we know cubes
         self._get_pool().close(True)
-        # list of available pools (we can't iterated on Queue instance)
+        # list of available pools (we can't iterate on Queue instance)
         self.pools = []
         for i in xrange(config['connections-pool-size']):
             self.pools.append(pool.ConnectionsPool(self.sources))
@@ -219,9 +232,60 @@
 
     # internals ###############################################################
 
-    def get_source(self, uri, source_config):
+    def init_sources_from_database(self):
+        self.sources_by_eid = {}
+        if not 'CWSource' in self.schema:
+            # 3.10 migration
+            return
+        session = self.internal_session()
+        try:
+            # FIXME: sources should be ordered (add_entity priority)
+            for sourceent in session.execute(
+                'Any S, SN, SA, SC WHERE S is CWSource, '
+                'S name SN, S type SA, S config SC').entities():
+                if sourceent.name == 'system':
+                    self.system_source.eid = sourceent.eid
+                    self.sources_by_eid[sourceent.eid] = self.system_source
+                    continue
+                self.add_source(sourceent, add_to_pools=False)
+        finally:
+            session.close()
+
+    def _clear_planning_caches(self):
+        for cache in ('source_defs', 'is_multi_sources_relation',
+                      'can_cross_relation', 'rel_type_sources'):
+            clear_cache(self, cache)
+
+    def add_source(self, sourceent, add_to_pools=True):
+        source = self.get_source(sourceent.type, sourceent.name,
+                                 sourceent.host_config)
+        source.eid = sourceent.eid
+        self.sources_by_eid[sourceent.eid] = source
+        self.sources_by_uri[sourceent.name] = source
+        if self.config.source_enabled(source):
+            self.sources.append(source)
+            self.querier.set_planner()
+            if add_to_pools:
+                for pool in self.pools:
+                    pool.add_source(source)
+        self._clear_planning_caches()
+
+    def remove_source(self, uri):
+        source = self.sources_by_uri.pop(uri)
+        del self.sources_by_eid[source.eid]
+        if self.config.source_enabled(source):
+            self.sources.remove(source)
+            self.querier.set_planner()
+            for pool in self.pools:
+                pool.remove_source(source)
+        self._clear_planning_caches()
+
+    def get_source(self, type, uri, source_config):
+        # set uri and type in source config so it's available through
+        # source_defs()
         source_config['uri'] = uri
-        return sources.get_source(source_config, self.schema, self)
+        source_config['type'] = type
+        return sources.get_source(type, source_config, self)
 
     def set_schema(self, schema, resetvreg=True, rebuildinfered=True):
         if rebuildinfered:
@@ -270,7 +334,10 @@
             # call instance level initialisation hooks
             self.hm.call_hooks('server_startup', repo=self)
             # register a task to cleanup expired session
-            self.looping_task(self.config['session-time']/3., self.clean_sessions)
+            self.cleanup_session_time = self.config['cleanup-session-time'] or 60 * 60 * 24
+            assert self.cleanup_session_time > 0
+            cleanup_session_interval = min(60*60, self.cleanup_session_time / 3)
+            self.looping_task(cleanup_session_interval, self.clean_sessions)
         assert isinstance(self._looping_tasks, list), 'already started'
         for i, (interval, func, args) in enumerate(self._looping_tasks):
             self._looping_tasks[i] = task = utils.LoopTask(interval, func, args)
@@ -520,14 +587,10 @@
 
         This is a public method, not requiring a session id.
         """
-        sources = self.config.sources().copy()
-        # remove manager information
-        sources.pop('admin', None)
+        sources = {}
         # remove sensitive information
-        for uri, sourcedef in sources.iteritems():
-            sourcedef = sourcedef.copy()
-            self.sources_by_uri[uri].remove_sensitive_information(sourcedef)
-            sources[uri] = sourcedef
+        for uri, source in self.sources_by_uri.iteritems():
+            sources[uri] = source.cfg
         return sources
 
     def properties(self):
@@ -568,8 +631,7 @@
                 password = password.encode('UTF8')
             kwargs['login'] = login
             kwargs['upassword'] = password
-            user.update(kwargs)
-            self.glob_add_entity(session, user)
+            self.glob_add_entity(session, EditedEntity(user, **kwargs))
             session.execute('SET X in_group G WHERE X eid %(x)s, G name "users"',
                             {'x': user.eid})
             if email or '@' in login:
@@ -586,6 +648,39 @@
             session.close()
         return True
 
+    def find_users(self, fetch_attrs, **query_attrs):
+        """yield user attributes for cwusers matching the given query_attrs
+        (the result set cannot survive this method call)
+
+        This can be used by low-privileges account (anonymous comes to
+        mind).
+
+        `fetch_attrs`: tuple of attributes to be fetched
+        `query_attrs`: dict of attr/values to restrict the query
+        """
+        assert query_attrs
+        if not hasattr(self, '_cwuser_attrs'):
+            cwuser = self.schema['CWUser']
+            self._cwuser_attrs = set(str(rschema)
+                                     for rschema, _eschema in cwuser.attribute_definitions()
+                                     if not rschema.meta)
+        cwuserattrs = self._cwuser_attrs
+        for k in chain(fetch_attrs, query_attrs.iterkeys()):
+            if k not in cwuserattrs:
+                raise Exception('bad input for find_user')
+        session = self.internal_session()
+        try:
+            varmaker = rqlvar_maker()
+            vars = [(attr, varmaker.next()) for attr in fetch_attrs]
+            rql = 'Any %s WHERE X is CWUser, ' % ','.join(var[1] for var in vars)
+            rql += ','.join('X %s %s' % (var[0], var[1]) for var in vars) + ','
+            rset = session.execute(rql + ','.join('X %s %%(%s)s' % (attr, attr)
+                                                  for attr in query_attrs.iterkeys()),
+                                   query_attrs)
+            return rset.rows
+        finally:
+            session.close()
+
     def connect(self, login, **kwargs):
         """open a connection for a given user
 
@@ -660,24 +755,32 @@
             session.reset_pool()
 
     def check_session(self, sessionid):
-        """raise `BadConnectionId` if the connection is no more valid"""
-        self._get_session(sessionid, setpool=False)
+        """raise `BadConnectionId` if the connection is no more valid, else
+        return its latest activity timestamp.
+        """
+        return self._get_session(sessionid, setpool=False).timestamp
+
+    def get_shared_data(self, sessionid, key, default=None, pop=False, txdata=False):
+        """return value associated to key in the session's data dictionary or
+        session's transaction's data if `txdata` is true.
 
-    def get_shared_data(self, sessionid, key, default=None, pop=False):
-        """return the session's data dictionary"""
+        If pop is True, value will be removed from the dictionnary.
+
+        If key isn't defined in the dictionnary, value specified by the
+        `default` argument will be returned.
+        """
         session = self._get_session(sessionid, setpool=False)
-        return session.get_shared_data(key, default, pop)
+        return session.get_shared_data(key, default, pop, txdata)
 
-    def set_shared_data(self, sessionid, key, value, querydata=False):
+    def set_shared_data(self, sessionid, key, value, txdata=False):
         """set value associated to `key` in shared data
 
-        if `querydata` is true, the value will be added to the repository
-        session's query data which are cleared on commit/rollback of the current
-        transaction, and won't be available through the connexion, only on the
-        repository side.
+        if `txdata` is true, the value will be added to the repository session's
+        transaction's data which are cleared on commit/rollback of the current
+        transaction.
         """
         session = self._get_session(sessionid, setpool=False)
-        session.set_shared_data(key, value, querydata)
+        session.set_shared_data(key, value, txdata)
 
     def commit(self, sessionid, txid=None):
         """commit transaction for the session with the given id"""
@@ -809,7 +912,7 @@
         """close sessions not used since an amount of time specified in the
         configuration
         """
-        mintime = time() - self.config['session-time']
+        mintime = time() - self.cleanup_session_time
         self.debug('cleaning session unused since %s',
                    strftime('%T', localtime(mintime)))
         nbclosed = 0
@@ -964,7 +1067,6 @@
             self._extid_cache[cachekey] = eid
             self._type_source_cache[eid] = (etype, source.uri, extid)
             entity = source.before_entity_insertion(session, extid, etype, eid)
-            entity.edited_attributes = set(entity.cw_attr_cache)
             if source.should_call_hooks:
                 self.hm.call_hooks('before_add_entity', session, entity=entity)
             # XXX call add_info with complete=False ?
@@ -972,10 +1074,6 @@
             source.after_entity_insertion(session, extid, entity)
             if source.should_call_hooks:
                 self.hm.call_hooks('after_add_entity', session, entity=entity)
-            else:
-                # minimal meta-data
-                session.execute('SET X is E WHERE X eid %(x)s, E name %(name)s',
-                                {'x': entity.eid, 'name': entity.__regid__})
             session.commit(reset_pool)
             return eid
         except:
@@ -987,8 +1085,7 @@
         and index the entity with the full text index
         """
         # begin by inserting eid/type/source/extid into the entities table
-        hook.set_operation(session, 'neweids', entity.eid,
-                           hook.CleanupNewEidsCacheOp)
+        hook.CleanupNewEidsCacheOp.get_instance(session).add_data(entity.eid)
         self.system_source.add_info(session, entity, source, extid, complete)
 
     def delete_info(self, session, entity, sourceuri, extid):
@@ -997,8 +1094,7 @@
         """
         # mark eid as being deleted in session info and setup cache update
         # operation
-        hook.set_operation(session, 'pendingeids', entity.eid,
-                           hook.CleanupDeletedEidsCacheOp)
+        hook.CleanupDeletedEidsCacheOp.get_instance(session).add_data(entity.eid)
         self._delete_info(session, entity, sourceuri, extid)
 
     def _delete_info(self, session, entity, sourceuri, extid):
@@ -1067,15 +1163,16 @@
         self._type_source_cache[entity.eid] = (entity.__regid__, suri, extid)
         return extid
 
-    def glob_add_entity(self, session, entity):
+    def glob_add_entity(self, session, edited):
         """add an entity to the repository
 
         the entity eid should originaly be None and a unique eid is assigned to
         the entity instance
         """
-        # init edited_attributes before calling before_add_entity hooks
+        entity = edited.entity
         entity._cw_is_saved = False # entity has an eid but is not yet saved
-        entity.edited_attributes = set(entity.cw_attr_cache) # XXX cw_edited_attributes
+        # init edited_attributes before calling before_add_entity hooks
+        entity.cw_edited = edited
         eschema = entity.e_schema
         source = self.locate_etype_source(entity.__regid__)
         # allocate an eid to the entity before calling hooks
@@ -1083,49 +1180,26 @@
         # set caches asap
         extid = self.init_entity_caches(session, entity, source)
         if server.DEBUG & server.DBG_REPO:
-            print 'ADD entity', self, entity.__regid__, entity.eid, entity.cw_attr_cache
+            print 'ADD entity', self, entity.__regid__, entity.eid, edited
         relations = []
         if source.should_call_hooks:
             self.hm.call_hooks('before_add_entity', session, entity=entity)
-        # XXX use entity.keys here since edited_attributes is not updated for
-        # inline relations XXX not true, right? (see edited_attributes
-        # affectation above)
-        for attr in entity.cw_attr_cache.iterkeys():
+        for attr in edited.iterkeys():
             rschema = eschema.subjrels[attr]
             if not rschema.final: # inlined relation
-                relations.append((attr, entity[attr]))
-        entity._cw_set_defaults()
+                relations.append((attr, edited[attr]))
+        edited.set_defaults()
         if session.is_hook_category_activated('integrity'):
-            entity._cw_check(creation=True)
+            edited.check(creation=True)
+        prefill_entity_caches(entity, relations)
         try:
             source.add_entity(session, entity)
         except UniqueTogetherError, exc:
-            etype, rtypes = exc.args
-            problems = {}
-            for col in rtypes:
-                problems[col] = _('violates unique_together constraints (%s)') % (','.join(rtypes))
-            raise ValidationError(entity.eid, problems)
+            userhdlr = session.vreg['adapters'].select(
+                'IUserFriendlyError', session, entity=entity, exc=exc)
+            userhdlr.raise_user_exception()
         self.add_info(session, entity, source, extid, complete=False)
-        entity._cw_is_saved = True # entity has an eid and is saved
-        # prefill entity relation caches
-        for rschema in eschema.subject_relations():
-            rtype = str(rschema)
-            if rtype in schema.VIRTUAL_RTYPES:
-                continue
-            if rschema.final:
-                entity.setdefault(rtype, None)
-            else:
-                entity.cw_set_relation_cache(rtype, 'subject',
-                                             session.empty_rset())
-        for rschema in eschema.object_relations():
-            rtype = str(rschema)
-            if rtype in schema.VIRTUAL_RTYPES:
-                continue
-            entity.cw_set_relation_cache(rtype, 'object', session.empty_rset())
-        # set inlined relation cache before call to after_add_entity
-        for attr, value in relations:
-            session.update_rel_cache_add(entity.eid, attr, value)
-            del_existing_rel_if_needed(session, entity.eid, attr, value)
+        edited.saved = entity._cw_is_saved = True
         # trigger after_add_entity after after_add_relation
         if source.should_call_hooks:
             self.hm.call_hooks('after_add_entity', session, entity=entity)
@@ -1137,23 +1211,24 @@
                                     eidfrom=entity.eid, rtype=attr, eidto=value)
         return entity.eid
 
-    def glob_update_entity(self, session, entity, edited_attributes):
+    def glob_update_entity(self, session, edited):
         """replace an entity in the repository
         the type and the eid of an entity must not be changed
         """
+        entity = edited.entity
         if server.DEBUG & server.DBG_REPO:
             print 'UPDATE entity', entity.__regid__, entity.eid, \
-                  entity.cw_attr_cache, edited_attributes
+                  entity.cw_attr_cache, edited
         hm = self.hm
         eschema = entity.e_schema
         session.set_entity_cache(entity)
-        orig_edited_attributes = getattr(entity, 'edited_attributes', None)
-        entity.edited_attributes = edited_attributes
+        orig_edited = getattr(entity, 'cw_edited', None)
+        entity.cw_edited = edited
         try:
             only_inline_rels, need_fti_update = True, False
             relations = []
             source = self.source_from_eid(entity.eid, session)
-            for attr in list(edited_attributes):
+            for attr in list(edited):
                 if attr == 'eid':
                     continue
                 rschema = eschema.subjrels[attr]
@@ -1166,13 +1241,13 @@
                     previous_value = entity.related(attr) or None
                     if previous_value is not None:
                         previous_value = previous_value[0][0] # got a result set
-                        if previous_value == entity[attr]:
+                        if previous_value == entity.cw_attr_cache[attr]:
                             previous_value = None
                         elif source.should_call_hooks:
                             hm.call_hooks('before_delete_relation', session,
                                           eidfrom=entity.eid, rtype=attr,
                                           eidto=previous_value)
-                    relations.append((attr, entity[attr], previous_value))
+                    relations.append((attr, edited[attr], previous_value))
             if source.should_call_hooks:
                 # call hooks for inlined relations
                 for attr, value, _t in relations:
@@ -1181,16 +1256,16 @@
                 if not only_inline_rels:
                     hm.call_hooks('before_update_entity', session, entity=entity)
             if session.is_hook_category_activated('integrity'):
-                entity._cw_check()
+                edited.check()
             try:
                 source.update_entity(session, entity)
+                edited.saved = True
             except UniqueTogetherError, exc:
                 etype, rtypes = exc.args
                 problems = {}
                 for col in rtypes:
-                    problems[col] = _('violates unique_together constraints (%s)') % (','.join(rtypes))
+                    problems[col] = session._('violates unique_together constraints (%s)') % (','.join(rtypes))
                 raise ValidationError(entity.eid, problems)
-
             self.system_source.update_info(session, entity, need_fti_update)
             if source.should_call_hooks:
                 if not only_inline_rels:
@@ -1212,8 +1287,8 @@
                     hm.call_hooks('after_add_relation', session,
                                   eidfrom=entity.eid, rtype=attr, eidto=value)
         finally:
-            if orig_edited_attributes is not None:
-                entity.edited_attributes = orig_edited_attributes
+            if orig_edited is not None:
+                entity.cw_edited = orig_edited
 
     def glob_delete_entity(self, session, eid):
         """delete an entity and all related entities from the repository"""
--- a/server/serverconfig.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/serverconfig.py	Wed Oct 13 08:37:21 2010 +0200
@@ -19,10 +19,11 @@
 
 __docformat__ = "restructuredtext en"
 
+import sys
 from os.path import join, exists
+from StringIO import StringIO
 
-from logilab.common.configuration import REQUIRED, Method, Configuration, \
-     ini_format_section
+import logilab.common.configuration as lgconfig
 from logilab.common.decorators import wproperty, cached
 
 from cubicweb.toolsutils import read_config, restrict_perms_to_user
@@ -38,13 +39,13 @@
                'level': 0,
                }),
     ('password', {'type' : 'password',
-                  'default': REQUIRED,
+                  'default': lgconfig.REQUIRED,
                   'help': "cubicweb manager account's password",
                   'level': 0,
                   }),
     )
 
-class SourceConfiguration(Configuration):
+class SourceConfiguration(lgconfig.Configuration):
     def __init__(self, appconfig, options):
         self.appconfig = appconfig # has to be done before super call
         super(SourceConfiguration, self).__init__(options=options)
@@ -54,54 +55,36 @@
         return self.appconfig.appid
 
     def input_option(self, option, optdict, inputlevel):
-        if self['db-driver'] == 'sqlite':
-            if option in ('db-user', 'db-password'):
-                return
-            if option == 'db-name':
-                optdict = optdict.copy()
-                optdict['help'] = 'path to the sqlite database'
-                optdict['default'] = join(self.appconfig.appdatahome,
-                                          self.appconfig.appid + '.sqlite')
+        try:
+            dbdriver = self['db-driver']
+        except lgconfig.OptionError:
+            pass
+        else:
+            if dbdriver == 'sqlite':
+                if option in ('db-user', 'db-password'):
+                    return
+                if option == 'db-name':
+                    optdict = optdict.copy()
+                    optdict['help'] = 'path to the sqlite database'
+                    optdict['default'] = join(self.appconfig.appdatahome,
+                                              self.appconfig.appid + '.sqlite')
         super(SourceConfiguration, self).input_option(option, optdict, inputlevel)
 
 
-def generate_sources_file(appconfig, sourcesfile, sourcescfg, keys=None):
-    """serialize repository'sources configuration into a INI like file
+
+def ask_source_config(appconfig, type, inputlevel=0):
+    options = SOURCE_TYPES[type].options
+    sconfig = SourceConfiguration(appconfig, options=options)
+    sconfig.input_config(inputlevel=inputlevel)
+    return sconfig
 
-    the `keys` parameter may be used to sort sections
-    """
-    if keys is None:
-        keys = sourcescfg.keys()
-    else:
-        for key in sourcescfg:
-            if not key in keys:
-                keys.append(key)
-    stream = open(sourcesfile, 'w')
-    for uri in keys:
-        sconfig = sourcescfg[uri]
-        if isinstance(sconfig, dict):
-            # get a Configuration object
-            if uri == 'admin':
-                options = USER_OPTIONS
-            else:
-                options = SOURCE_TYPES[sconfig['adapter']].options
-            _sconfig = SourceConfiguration(appconfig, options=options)
-            for attr, val in sconfig.items():
-                if attr == 'uri':
-                    continue
-                if attr == 'adapter':
-                    _sconfig.adapter = val
-                else:
-                    _sconfig.set_option(attr, val)
-            sconfig = _sconfig
-        optsbysect = list(sconfig.options_by_section())
-        assert len(optsbysect) == 1, 'all options for a source should be in the same group'
-        ini_format_section(stream, uri, optsbysect[0][1])
-        if hasattr(sconfig, 'adapter'):
-            print >> stream
-            print >> stream, '# adapter for this source (YOU SHOULD NOT CHANGE THIS)'
-            print >> stream, 'adapter=%s' % sconfig.adapter
-        print >> stream
+def generate_source_config(sconfig):
+    """serialize a repository source configuration as text"""
+    stream = StringIO()
+    optsbysect = list(sconfig.options_by_section())
+    assert len(optsbysect) == 1, 'all options for a source should be in the same group'
+    lgconfig.ini_format(stream, optsbysect[0][1], sys.stdin.encoding)
+    return stream.getvalue()
 
 
 class ServerConfiguration(CubicWebConfiguration):
@@ -121,7 +104,7 @@
           }),
         ('pid-file',
          {'type' : 'string',
-          'default': Method('default_pid_file'),
+          'default': lgconfig.Method('default_pid_file'),
           'help': 'repository\'s pid file',
           'group': 'main', 'level': 2,
           }),
@@ -132,10 +115,16 @@
 the repository rather than the user running the command',
           'group': 'main', 'level': (CubicWebConfiguration.mode == 'installed') and 0 or 1,
           }),
-        ('session-time',
+        ('cleanup-session-time',
          {'type' : 'time',
-          'default': '30min',
-          'help': 'session expiration time, default to 30 minutes',
+          'default': '24h',
+          'help': 'duration of inactivity after which a session '
+          'will be closed, to limit memory consumption (avoid sessions that '
+          'never expire and cause memory leak when http-session-time is 0, or '
+          'because of bad client that never closes their connection). '
+          'So notice that even if http-session-time is 0 and the user don\'t '
+          'close his browser, he will have to reauthenticate after this time '
+          'of inactivity. Default to 24h.',
           'group': 'main', 'level': 3,
           }),
         ('connections-pool-size',
@@ -276,16 +265,43 @@
         """
         return self.read_sources_file()
 
-    def source_enabled(self, uri):
-        return not self.enabled_sources or uri in self.enabled_sources
+    def source_enabled(self, source):
+        if self.sources_mode is not None:
+            if 'migration' in self.sources_mode:
+                assert len(self.sources_mode) == 1
+                if source.connect_for_migration:
+                    return True
+                print 'not connecting to source', uri, 'during migration'
+                return False
+            if 'all' in self.sources_mode:
+                assert len(self.sources_mode) == 1
+                return True
+            return source.uri in self.sources_mode
+        if self.quick_start:
+            return False
+        return (not source.disabled and (
+            not self.enabled_sources or source.uri in self.enabled_sources))
 
     def write_sources_file(self, sourcescfg):
+        """serialize repository'sources configuration into a INI like file"""
         sourcesfile = self.sources_file()
         if exists(sourcesfile):
             import shutil
             shutil.copy(sourcesfile, sourcesfile + '.bak')
-        generate_sources_file(self, sourcesfile, sourcescfg,
-                              ['admin', 'system'])
+        stream = open(sourcesfile, 'w')
+        for section in ('admin', 'system'):
+            sconfig = sourcescfg[section]
+            if isinstance(sconfig, dict):
+                # get a Configuration object
+                assert section == 'system'
+                _sconfig = SourceConfiguration(
+                    self, options=SOURCE_TYPES['native'].options)
+                for attr, val in sconfig.items():
+                    _sconfig.set_option(attr, val)
+                sconfig = _sconfig
+            print >> stream, '[%s]' % section
+            print >> stream, generate_source_config(sconfig)
+            print >> stream
         restrict_perms_to_user(sourcesfile)
 
     def pyro_enabled(self):
@@ -312,27 +328,9 @@
         schema.name = 'bootstrap'
         return schema
 
+    sources_mode = None
     def set_sources_mode(self, sources):
-        if 'migration' in sources:
-            from cubicweb.server.sources import source_adapter
-            assert len(sources) == 1
-            enabled_sources = []
-            for uri, config in self.sources().iteritems():
-                if uri == 'admin':
-                    continue
-                if source_adapter(config).connect_for_migration:
-                    enabled_sources.append(uri)
-                else:
-                    print 'not connecting to source', uri, 'during migration'
-        elif 'all' in sources:
-            assert len(sources) == 1
-            enabled_sources = None
-        else:
-            known_sources = self.sources()
-            for uri in sources:
-                assert uri in known_sources, uri
-            enabled_sources = sources
-        self.enabled_sources = enabled_sources
+        self.sources_mode = sources
 
     def migration_handler(self, schema=None, interactive=True,
                           cnx=None, repo=None, connect=True, verbosity=None):
--- a/server/serverctl.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/serverctl.py	Wed Oct 13 08:37:21 2010 +0200
@@ -32,8 +32,9 @@
 from cubicweb.toolsutils import Command, CommandHandler, underline_title
 from cubicweb.cwctl import CWCTL
 from cubicweb.server import SOURCE_TYPES
-from cubicweb.server.serverconfig import (USER_OPTIONS, ServerConfiguration,
-                                          SourceConfiguration)
+from cubicweb.server.serverconfig import (
+    USER_OPTIONS, ServerConfiguration, SourceConfiguration,
+    ask_source_config, generate_source_config)
 
 # utility functions ###########################################################
 
@@ -161,7 +162,6 @@
         """create an instance by copying files from the given cube and by asking
         information necessary to build required configuration files
         """
-        from cubicweb.server.utils import ask_source_config
         config = self.config
         print underline_title('Configuring the repository')
         config.input_config('email', inputlevel)
@@ -176,37 +176,9 @@
         # defs (in native.py)
         sconfig = SourceConfiguration(config,
                                       options=SOURCE_TYPES['native'].options)
-        sconfig.adapter = 'native'
         sconfig.input_config(inputlevel=inputlevel)
         sourcescfg = {'system': sconfig}
-        for cube in cubes:
-            # if a source is named as the cube containing it, we need the
-            # source to use the cube, so add it.
-            if cube in SOURCE_TYPES:
-                sourcescfg[cube] = ask_source_config(cube, inputlevel)
         print
-        while ASK.confirm('Enter another source ?', default_is_yes=False):
-            available = sorted(stype for stype in SOURCE_TYPES
-                               if not stype in cubes)
-            while True:
-                sourcetype = raw_input('source type (%s): ' % ', '.join(available))
-                if sourcetype in available:
-                    break
-                print '-> unknown source type, use one of the available types.'
-            while True:
-                sourceuri = raw_input('source identifier (a unique name used to tell sources apart): ').strip()
-                if sourceuri != 'admin' and sourceuri not in sourcescfg:
-                    break
-                print '-> uri already used, choose another one.'
-            sourcescfg[sourceuri] = ask_source_config(sourcetype, inputlevel)
-            sourcemodule = SOURCE_TYPES[sourcetype].module
-            if not sourcemodule.startswith('cubicweb.'):
-                # module names look like cubes.mycube.themodule
-                sourcecube = SOURCE_TYPES[sourcetype].module.split('.', 2)[1]
-                # if the source adapter is coming from an external component,
-                # ensure it's specified in used cubes
-                if not sourcecube in cubes:
-                    cubes.append(sourcecube)
         sconfig = Configuration(options=USER_OPTIONS)
         sconfig.input_config(inputlevel=inputlevel)
         sourcescfg['admin'] = sconfig
@@ -294,7 +266,7 @@
 
     You will be prompted for a login / password to use to connect to
     the system database.  The given user should have almost all rights
-    on the database (ie a super user on the dbms allowed to create
+    on the database (ie a super user on the DBMS allowed to create
     database, users, languages...).
 
     <instance>
@@ -383,9 +355,8 @@
 class InitInstanceCommand(Command):
     """Initialize the system database of an instance (run after 'db-create').
 
-    You will be prompted for a login / password to use to connect to
-    the system database.  The given user should have the create tables,
-    and grant permissions.
+    Notice this will be done using user specified in the sources files, so this
+    user should have the create tables grant permissions on the database.
 
     <instance>
       the identifier of the instance to initialize.
@@ -422,6 +393,63 @@
                 'the %s file. Resolve this first (error: %s).'
                 % (config.sources_file(), str(ex).strip()))
         init_repository(config, drop=self.config.drop)
+        while ASK.confirm('Enter another source ?', default_is_yes=False):
+            CWCTL.run(['add-source', config.appid])
+
+
+class AddSourceCommand(Command):
+    """Add a data source to an instance.
+
+    <instance>
+      the identifier of the instance to initialize.
+    """
+    name = 'add-source'
+    arguments = '<instance>'
+    min_args = max_args = 1
+    options = ()
+
+    def run(self, args):
+        appid = args[0]
+        config = ServerConfiguration.config_for(appid)
+        config.quick_start = True
+        repo, cnx = repo_cnx(config)
+        req = cnx.request()
+        used = set(n for n, in req.execute('Any SN WHERE S is CWSource, S name SN'))
+        cubes = repo.get_cubes()
+        while True:
+            type = raw_input('source type (%s): '
+                                % ', '.join(sorted(SOURCE_TYPES)))
+            if type not in SOURCE_TYPES:
+                print '-> unknown source type, use one of the available types.'
+                continue
+            sourcemodule = SOURCE_TYPES[type].module
+            if not sourcemodule.startswith('cubicweb.'):
+                # module names look like cubes.mycube.themodule
+                sourcecube = SOURCE_TYPES[type].module.split('.', 2)[1]
+                # if the source adapter is coming from an external component,
+                # ensure it's specified in used cubes
+                if not sourcecube in cubes:
+                    print ('-> this source type require the %s cube which is '
+                           'not used by the instance.')
+                    continue
+            break
+        while True:
+            sourceuri = raw_input('source identifier (a unique name used to '
+                                  'tell sources apart): ').strip()
+            if not sourceuri:
+                print '-> mandatory.'
+            else:
+                sourceuri = unicode(sourceuri, sys.stdin.encoding)
+                if sourceuri in used:
+                    print '-> uri already used, choose another one.'
+                else:
+                    break
+        # XXX configurable inputlevel
+        sconfig = ask_source_config(config, type, inputlevel=0)
+        cfgstr = unicode(generate_source_config(sconfig), sys.stdin.encoding)
+        req.create_entity('CWSource', name=sourceuri,
+                          type=unicode(type), config=cfgstr)
+        cnx.commit()
 
 
 class GrantUserOnInstanceCommand(Command):
@@ -486,6 +514,9 @@
             print '-> Error: could not get cubicweb administrator login.'
             sys.exit(1)
         cnx = source_cnx(sourcescfg['system'])
+        driver = sourcescfg['system']['db-driver']
+        from logilab.database import get_db_helper
+        dbhelper = get_db_helper(driver)
         cursor = cnx.cursor()
         # check admin exists
         cursor.execute("SELECT * FROM cw_CWUser WHERE cw_login=%(l)s",
@@ -501,7 +532,7 @@
                                        passwdmsg='new password for %s' % adminlogin)
         try:
             cursor.execute("UPDATE cw_CWUser SET cw_upassword=%(p)s WHERE cw_login=%(l)s",
-                           {'p': buffer(crypt_password(passwd)), 'l': adminlogin})
+                           {'p': dbhelper.binary_value(crypt_password(passwd)), 'l': adminlogin})
             sconfig = Configuration(options=USER_OPTIONS)
             sconfig['login'] = adminlogin
             sconfig['password'] = passwd
@@ -897,7 +928,7 @@
                  GrantUserOnInstanceCommand, ResetAdminPasswordCommand,
                  StartRepositoryCommand,
                  DBDumpCommand, DBRestoreCommand, DBCopyCommand,
-                 CheckRepositoryCommand, RebuildFTICommand,
+                 AddSourceCommand, CheckRepositoryCommand, RebuildFTICommand,
                  SynchronizeInstanceSchemaCommand,
                  CheckMappingCommand,
                  ):
--- a/server/session.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/session.py	Wed Oct 13 08:37:21 2010 +0200
@@ -46,6 +46,7 @@
 # anyway in the later case
 NO_UNDO_TYPES.add('is')
 NO_UNDO_TYPES.add('is_instance_of')
+NO_UNDO_TYPES.add('cw_source')
 # XXX rememberme,forgotpwd,apycot,vcsfile
 
 def _make_description(selected, args, solution):
@@ -64,6 +65,14 @@
 
     If mode is session.`HOOKS_ALLOW_ALL`, given hooks categories will
     be disabled.
+
+    .. sourcecode:: python
+
+       with hooks_control(self.session, self.session.HOOKS_ALLOW_ALL, 'integrity'):
+           # ... do stuff with all but 'integrity' hooks activated
+
+       with hooks_control(self.session, self.session.HOOKS_DENY_ALL, 'integrity'):
+           # ... do stuff with none but 'integrity' hooks activated
     """
     def __init__(self, session, mode, *categories):
         self.session = session
@@ -618,16 +627,20 @@
 
     # shared data handling ###################################################
 
-    def get_shared_data(self, key, default=None, pop=False):
+    def get_shared_data(self, key, default=None, pop=False, txdata=False):
         """return value associated to `key` in session data"""
-        if pop:
-            return self.data.pop(key, default)
+        if txdata:
+            data = self.transaction_data
         else:
-            return self.data.get(key, default)
+            data = self.data
+        if pop:
+            return data.pop(key, default)
+        else:
+            return data.get(key, default)
 
-    def set_shared_data(self, key, value, querydata=False):
+    def set_shared_data(self, key, value, txdata=False):
         """set value associated to `key` in session data"""
-        if querydata:
+        if txdata:
             self.transaction_data[key] = value
         else:
             self.data[key] = value
@@ -738,51 +751,50 @@
         try:
             # by default, operations are executed with security turned off
             with security_enabled(self, False, False):
-                for trstate in ('precommit', 'commit'):
-                    processed = []
-                    self.commit_state = trstate
-                    try:
-                        while self.pending_operations:
-                            operation = self.pending_operations.pop(0)
-                            operation.processed = trstate
-                            processed.append(operation)
-                            operation.handle_event('%s_event' % trstate)
-                        self.pending_operations[:] = processed
-                        self.debug('%s session %s done', trstate, self.id)
-                    except:
-                        # if error on [pre]commit:
-                        #
-                        # * set .failed = True on the operation causing the failure
-                        # * call revert<event>_event on processed operations
-                        # * call rollback_event on *all* operations
-                        #
-                        # that seems more natural than not calling rollback_event
-                        # for processed operations, and allow generic rollback
-                        # instead of having to implements rollback, revertprecommit
-                        # and revertcommit, that will be enough in mont case.
-                        operation.failed = True
-                        for operation in reversed(processed):
-                            try:
-                                operation.handle_event('revert%s_event' % trstate)
-                            except:
-                                self.critical('error while reverting %sing', trstate,
-                                              exc_info=True)
-                        # XXX use slice notation since self.pending_operations is a
-                        # read-only property.
-                        self.pending_operations[:] = processed + self.pending_operations
-                        self.rollback(reset_pool)
-                        raise
+                processed = []
+                self.commit_state = 'precommit'
+                try:
+                    while self.pending_operations:
+                        operation = self.pending_operations.pop(0)
+                        operation.processed = 'precommit'
+                        processed.append(operation)
+                        operation.handle_event('precommit_event')
+                    self.pending_operations[:] = processed
+                    self.debug('precommit session %s done', self.id)
+                except:
+                    # if error on [pre]commit:
+                    #
+                    # * set .failed = True on the operation causing the failure
+                    # * call revert<event>_event on processed operations
+                    # * call rollback_event on *all* operations
+                    #
+                    # that seems more natural than not calling rollback_event
+                    # for processed operations, and allow generic rollback
+                    # instead of having to implements rollback, revertprecommit
+                    # and revertcommit, that will be enough in mont case.
+                    operation.failed = True
+                    for operation in reversed(processed):
+                        try:
+                            operation.handle_event('revertprecommit_event')
+                        except:
+                            self.critical('error while reverting precommit',
+                                          exc_info=True)
+                    # XXX use slice notation since self.pending_operations is a
+                    # read-only property.
+                    self.pending_operations[:] = processed + self.pending_operations
+                    self.rollback(reset_pool)
+                    raise
                 self.pool.commit()
-                self.commit_state = trstate = 'postcommit'
+                self.commit_state = 'postcommit'
                 while self.pending_operations:
                     operation = self.pending_operations.pop(0)
-                    operation.processed = trstate
+                    operation.processed = 'postcommit'
                     try:
-                        operation.handle_event('%s_event' % trstate)
+                        operation.handle_event('postcommit_event')
                     except:
-                        self.critical('error while %sing', trstate,
+                        self.critical('error while postcommit',
                                       exc_info=sys.exc_info())
-                self.debug('%s session %s done', trstate, self.id)
+                self.debug('postcommit session %s done', self.id)
                 return self.transaction_uuid(set=False)
         finally:
             self._touch()
--- a/server/sources/__init__.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/sources/__init__.py	Wed Oct 13 08:37:21 2010 +0200
@@ -26,6 +26,7 @@
 from cubicweb import set_log_methods, server
 from cubicweb.schema import VIRTUAL_RTYPES
 from cubicweb.server.sqlutils import SQL_PREFIX
+from cubicweb.server.ssplanner import EditedEntity
 
 
 def dbg_st_search(uri, union, varmap, args, cachekey=None, prefix='rql for'):
@@ -98,13 +99,18 @@
     dont_cross_relations = ()
     cross_relations = ()
 
+    # force deactivation (configuration error for instance)
+    disabled = False
 
-    def __init__(self, repo, appschema, source_config, *args, **kwargs):
+    def __init__(self, repo, source_config, *args, **kwargs):
         self.repo = repo
         self.uri = source_config['uri']
         set_log_methods(self, getLogger('cubicweb.sources.'+self.uri))
-        self.set_schema(appschema)
+        self.set_schema(repo.schema)
         self.support_relations['identity'] = False
+        self.eid = None
+        self.cfg = source_config.copy()
+        self.remove_sensitive_information(self.cfg)
 
     def init_creating(self):
         """method called by the repository once ready to create a new instance"""
@@ -218,7 +224,7 @@
     def extid2eid(self, value, etype, session=None, **kwargs):
         return self.repo.extid2eid(self, value, etype, session, **kwargs)
 
-    PUBLIC_KEYS = ('adapter', 'uri')
+    PUBLIC_KEYS = ('type', 'uri')
     def remove_sensitive_information(self, sourcedef):
         """remove sensitive information such as login / password from source
         definition
@@ -343,6 +349,7 @@
         """
         entity = self.repo.vreg['etypes'].etype_class(etype)(session)
         entity.eid = eid
+        entity.cw_edited = EditedEntity(entity)
         return entity
 
     def after_entity_insertion(self, session, lid, entity):
@@ -506,17 +513,17 @@
     def cursor(self):
         return None # no actual cursor support
 
+
 from cubicweb.server import SOURCE_TYPES
 
-def source_adapter(source_config):
-    adapter_type = source_config['adapter'].lower()
+def source_adapter(source_type):
     try:
-        return SOURCE_TYPES[adapter_type]
+        return SOURCE_TYPES[source_type]
     except KeyError:
-        raise RuntimeError('Unknown adapter %r' % adapter_type)
+        raise RuntimeError('Unknown source type %r' % source_type)
 
-def get_source(source_config, global_schema, repo):
+def get_source(type, source_config, repo):
     """return a source adapter according to the adapter field in the
     source's configuration
     """
-    return source_adapter(source_config)(repo, global_schema, source_config)
+    return source_adapter(type)(repo, source_config)
--- a/server/sources/ldapuser.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/sources/ldapuser.py	Wed Oct 13 08:37:21 2010 +0200
@@ -162,9 +162,8 @@
 
     )
 
-    def __init__(self, repo, appschema, source_config, *args, **kwargs):
-        AbstractSource.__init__(self, repo, appschema, source_config,
-                                *args, **kwargs)
+    def __init__(self, repo, source_config, *args, **kwargs):
+        AbstractSource.__init__(self, repo, source_config, *args, **kwargs)
         self.host = source_config['host']
         self.protocol = source_config.get('protocol', 'ldap')
         self.authmode = source_config.get('auth-mode', 'simple')
@@ -574,7 +573,7 @@
         entity = super(LDAPUserSource, self).before_entity_insertion(session, lid, etype, eid)
         res = self._search(session, lid, BASE)[0]
         for attr in entity.e_schema.indexable_attributes():
-            entity[attr] = res[self.user_rev_attrs[attr]]
+            entity.cw_edited[attr] = res[self.user_rev_attrs[attr]]
         return entity
 
     def after_entity_insertion(self, session, dn, entity):
--- a/server/sources/native.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/sources/native.py	Wed Oct 13 08:37:21 2010 +0200
@@ -55,6 +55,7 @@
 from cubicweb.server.rqlannotation import set_qdata
 from cubicweb.server.hook import CleanupDeletedEidsCacheOp
 from cubicweb.server.session import hooks_control, security_enabled
+from cubicweb.server.ssplanner import EditedEntity
 from cubicweb.server.sources import AbstractSource, dbg_st_search, dbg_results
 from cubicweb.server.sources.rql2sql import SQLGenerator
 
@@ -262,13 +263,12 @@
           }),
     )
 
-    def __init__(self, repo, appschema, source_config, *args, **kwargs):
+    def __init__(self, repo, source_config, *args, **kwargs):
         SQLAdapterMixIn.__init__(self, source_config)
         self.authentifiers = [LoginPasswordAuthentifier(self)]
-        AbstractSource.__init__(self, repo, appschema, source_config,
-                                *args, **kwargs)
+        AbstractSource.__init__(self, repo, source_config, *args, **kwargs)
         # sql generator
-        self._rql_sqlgen = self.sqlgen_class(appschema, self.dbhelper,
+        self._rql_sqlgen = self.sqlgen_class(self.schema, self.dbhelper,
                                              ATTR_MAP.copy())
         # full text index helper
         self.do_fti = not repo.config['delay-full-text-indexation']
@@ -551,21 +551,20 @@
         etype = entity.__regid__
         for attr, storage in self._storages.get(etype, {}).items():
             try:
-                edited = entity.edited_attributes
+                edited = entity.cw_edited
             except AttributeError:
                 assert event == 'deleted'
                 getattr(storage, 'entity_deleted')(entity, attr)
             else:
                 if attr in edited:
                     handler = getattr(storage, 'entity_%s' % event)
-                    real_value = handler(entity, attr)
-                    restore_values[attr] = real_value
+                    restore_values[attr] = handler(entity, attr)
         try:
             yield # 2/ execute the source's instructions
         finally:
             # 3/ restore original values
             for attr, value in restore_values.items():
-                entity[attr] = value
+                entity.cw_edited.edited_attribute(attr, value)
 
     def add_entity(self, session, entity):
         """add a new entity to the source"""
@@ -880,6 +879,21 @@
         attrs = {'type': entity.__regid__, 'eid': entity.eid, 'extid': extid,
                  'source': source.uri, 'mtime': datetime.now()}
         self.doexec(session, self.sqlgen.insert('entities', attrs), attrs)
+        # insert core relations: is, is_instance_of and cw_source
+        if not hasattr(entity, '_cw_recreating'):
+            try:
+                self.doexec(session, 'INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)'
+                            % (entity.eid, eschema_eid(session, entity.e_schema)))
+            except IndexError:
+                # during schema serialization, skip
+                pass
+            else:
+                for eschema in entity.e_schema.ancestors() + [entity.e_schema]:
+                    self.doexec(session, 'INSERT INTO is_instance_of_relation(eid_from,eid_to) VALUES (%s,%s)'
+                               % (entity.eid, eschema_eid(session, eschema)))
+            if 'CWSource' in self.schema and source.eid is not None: # else, cw < 3.10
+                self.doexec(session, 'INSERT INTO cw_source_relation(eid_from,eid_to) '
+                            'VALUES (%s,%s)' % (entity.eid, source.eid))
         # now we can update the full text index
         if self.do_fti and self.need_fti_indexation(entity.__regid__):
             if complete:
@@ -926,7 +940,7 @@
         """
         for etype in etypes:
             if not etype in self.multisources_etypes:
-                self.critical('%s not listed as a multi-sources entity types. '
+                self.error('%s not listed as a multi-sources entity types. '
                               'Modify your configuration' % etype)
                 self.multisources_etypes.add(etype)
         modsql = _modified_sql('entities', etypes)
@@ -1127,6 +1141,7 @@
             err("can't restore entity %s of type %s, type no more supported"
                 % (eid, etype))
             return errors
+        entity.cw_edited = edited = EditedEntity(entity)
         # check for schema changes, entities linked through inlined relation
         # still exists, rewrap binary values
         eschema = entity.e_schema
@@ -1143,27 +1158,19 @@
                 assert value is None
             elif eschema.destination(rtype) in ('Bytes', 'Password'):
                 action.changes[column] = self._binary(value)
-                entity[rtype] = Binary(value)
+                edited[rtype] = Binary(value)
             elif isinstance(value, str):
-                entity[rtype] = unicode(value, session.encoding, 'replace')
+                edited[rtype] = unicode(value, session.encoding, 'replace')
             else:
-                entity[rtype] = value
+                edited[rtype] = value
         entity.eid = eid
         session.repo.init_entity_caches(session, entity, self)
-        entity.edited_attributes = set(entity)
-        entity._cw_check()
+        edited.check()
         self.repo.hm.call_hooks('before_add_entity', session, entity=entity)
         # restore the entity
         action.changes['cw_eid'] = eid
         sql = self.sqlgen.insert(SQL_PREFIX + etype, action.changes)
         self.doexec(session, sql, action.changes)
-        # add explicitly is / is_instance_of whose deletion is not recorded for
-        # consistency with addition (done by sql in hooks)
-        self.doexec(session, 'INSERT INTO is_relation(eid_from, eid_to) '
-                    'VALUES(%s, %s)' % (eid, eschema_eid(session, eschema)))
-        for eschema in entity.e_schema.ancestors() + [entity.e_schema]:
-            self.doexec(session, 'INSERT INTO is_instance_of_relation(eid_from,'
-                        'eid_to) VALUES(%s, %s)' % (eid, eschema_eid(session, eschema)))
         # restore record in entities (will update fti if needed)
         self.add_info(session, entity, self, None, True)
         # remove record from deleted_entities if entity's type is multi-sources
@@ -1220,13 +1227,13 @@
                 "no more supported" % {'eid': eid, 'etype': etype})]
         entity.eid = eid
         # for proper eid/type cache update
-        hook.set_operation(session, 'pendingeids', eid,
-                           CleanupDeletedEidsCacheOp)
+        CleanupDeletedEidsCacheOp.get_instance(session).add_data(eid)
         self.repo.hm.call_hooks('before_delete_entity', session, entity=entity)
         # remove is / is_instance_of which are added using sql by hooks, hence
         # unvisible as transaction action
         self.doexec(session, 'DELETE FROM is_relation WHERE eid_from=%s' % eid)
         self.doexec(session, 'DELETE FROM is_instance_of_relation WHERE eid_from=%s' % eid)
+        self.doexec(session, 'DELETE FROM cw_source_relation WHERE eid_from=%s' % self.eid)
         # XXX check removal of inlined relation?
         # delete the entity
         attrs = {'cw_eid': eid}
@@ -1288,7 +1295,7 @@
         """create an operation to [re]index textual content of the given entity
         on commit
         """
-        hook.set_operation(session, 'ftindex', entity.eid, FTIndexEntityOp)
+        FTIndexEntityOp.get_instance(session).add_data(entity.eid)
 
     def fti_unindex_entity(self, session, eid):
         """remove text content for entity with the given eid from the full text
@@ -1313,7 +1320,7 @@
             self.exception('error while reindexing %s', entity)
 
 
-class FTIndexEntityOp(hook.LateOperation):
+class FTIndexEntityOp(hook.DataOperationMixIn, hook.LateOperation):
     """operation to delay entity full text indexation to commit
 
     since fti indexing may trigger discovery of other entities, it should be
@@ -1326,7 +1333,7 @@
         source = session.repo.system_source
         pendingeids = session.transaction_data.get('pendingeids', ())
         done = session.transaction_data.setdefault('indexedeids', set())
-        for eid in session.transaction_data.pop('ftindex', ()):
+        for eid in self.get_data():
             if eid in pendingeids or eid in done:
                 # entity added and deleted in the same transaction or already
                 # processed
--- a/server/sources/pyrorql.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/sources/pyrorql.py	Wed Oct 13 08:37:21 2010 +0200
@@ -64,7 +64,7 @@
     assert not unknown, 'unknown mapping attribute(s): %s' % unknown
     # relations that are necessarily not crossed
     mapping['dont_cross_relations'] |= set(('owned_by', 'created_by'))
-    for rtype in ('is', 'is_instance_of'):
+    for rtype in ('is', 'is_instance_of', 'cw_source'):
         assert rtype not in mapping['dont_cross_relations'], \
                '%s relation should not be in dont_cross_relations' % rtype
         assert rtype not in mapping['support_relations'], \
@@ -146,17 +146,26 @@
     PUBLIC_KEYS = AbstractSource.PUBLIC_KEYS + ('base-url',)
     _conn = None
 
-    def __init__(self, repo, appschema, source_config, *args, **kwargs):
-        AbstractSource.__init__(self, repo, appschema, source_config,
-                                *args, **kwargs)
+    def __init__(self, repo, source_config, *args, **kwargs):
+        AbstractSource.__init__(self, repo, source_config, *args, **kwargs)
         mappingfile = source_config['mapping-file']
         if not mappingfile[0] == '/':
             mappingfile = join(repo.config.apphome, mappingfile)
-        mapping = load_mapping_file(mappingfile)
-        self.support_entities = mapping['support_entities']
-        self.support_relations = mapping['support_relations']
-        self.dont_cross_relations = mapping['dont_cross_relations']
-        self.cross_relations = mapping['cross_relations']
+        try:
+            mapping = load_mapping_file(mappingfile)
+        except IOError:
+            self.disabled = True
+            self.error('cant read mapping file %s, source disabled',
+                       mappingfile)
+            self.support_entities = {}
+            self.support_relations = {}
+            self.dont_cross_relations = set()
+            self.cross_relations = set()
+        else:
+            self.support_entities = mapping['support_entities']
+            self.support_relations = mapping['support_relations']
+            self.dont_cross_relations = mapping['dont_cross_relations']
+            self.cross_relations = mapping['cross_relations']
         baseurl = source_config.get('base-url')
         if baseurl and not baseurl.endswith('/'):
             source_config['base-url'] += '/'
--- a/server/sources/storages.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/sources/storages.py	Wed Oct 13 08:37:21 2010 +0200
@@ -24,6 +24,8 @@
 
 from cubicweb import Binary, ValidationError
 from cubicweb.server import hook
+from cubicweb.server.ssplanner import EditedEntity
+
 
 def set_attribute_storage(repo, etype, attr, storage):
     repo.system_source.set_storage(etype, attr, storage)
@@ -31,6 +33,7 @@
 def unset_attribute_storage(repo, etype, attr):
     repo.system_source.unset_storage(etype, attr)
 
+
 class Storage(object):
     """abstract storage
 
@@ -126,14 +129,14 @@
     def entity_added(self, entity, attr):
         """an entity using this storage for attr has been added"""
         if entity._cw.transaction_data.get('fs_importing'):
-            binary = Binary(file(entity[attr].getvalue(), 'rb').read())
+            binary = Binary(file(entity.cw_edited[attr].getvalue(), 'rb').read())
         else:
-            binary = entity.pop(attr)
+            binary = entity.cw_edited.pop(attr)
             fpath = self.new_fs_path(entity, attr)
             # bytes storage used to store file's path
-            entity[attr] = Binary(fpath)
+            entity.cw_edited.edited_attribute(attr, Binary(fpath))
             file(fpath, 'wb').write(binary.getvalue())
-            hook.set_operation(entity._cw, 'bfss_added', fpath, AddFileOp)
+            AddFileOp.get_instance(entity._cw).add_data(fpath)
         return binary
 
     def entity_updated(self, entity, attr):
@@ -144,7 +147,7 @@
             # If we are importing from the filesystem, the file already exists.
             # We do not need to create it but we need to fetch the content of
             # the file as the actual content of the attribute
-            fpath = entity[attr].getvalue()
+            fpath = entity.cw_edited[attr].getvalue()
             binary = Binary(file(fpath, 'rb').read())
         else:
             # We must store the content of the attributes
@@ -156,7 +159,7 @@
             # went ok.
             #
             # fetch the current attribute value in memory
-            binary = entity.pop(attr)
+            binary = entity.cw_edited.pop(attr)
             # Get filename for it
             fpath = self.new_fs_path(entity, attr)
             assert not osp.exists(fpath)
@@ -164,20 +167,19 @@
             file(fpath, 'wb').write(binary.getvalue())
             # Mark the new file as added during the transaction.
             # The file will be removed on rollback
-            hook.set_operation(entity._cw, 'bfss_added', fpath, AddFileOp)
+            AddFileOp.get_instance(entity._cw).add_data(fpath)
         if oldpath != fpath:
             # register the new location for the file.
-            entity[attr] = Binary(fpath)
+            entity.cw_edited.edited_attribute(attr, Binary(fpath))
             # Mark the old file as useless so the file will be removed at
             # commit.
-            hook.set_operation(entity._cw, 'bfss_deleted', oldpath,
-                               DeleteFileOp)
+            DeleteFileOp.get_instance(entity._cw).add_data(oldpath)
         return binary
 
     def entity_deleted(self, entity, attr):
         """an entity using this storage for attr has been deleted"""
         fpath = self.current_fs_path(entity, attr)
-        hook.set_operation(entity._cw, 'bfss_deleted', fpath, DeleteFileOp)
+        DeleteFileOp.get_instance(entity._cw).add_data(fpath)
 
     def new_fs_path(self, entity, attr):
         # We try to get some hint about how to name the file using attribute's
@@ -209,7 +211,7 @@
 
     def migrate_entity(self, entity, attribute):
         """migrate an entity attribute to the storage"""
-        entity.edited_attributes = set()
+        entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache)
         self.entity_added(entity, attribute)
         session = entity._cw
         source = session.repo.system_source
@@ -217,19 +219,20 @@
         sql = source.sqlgen.update('cw_' + entity.__regid__, attrs,
                                    ['cw_eid'])
         source.doexec(session, sql, attrs)
+        entity.cw_edited = None
 
 
-class AddFileOp(hook.Operation):
+class AddFileOp(hook.DataOperationMixIn, hook.Operation):
     def rollback_event(self):
-        for filepath in self.session.transaction_data.pop('bfss_added'):
+        for filepath in self.get_data():
             try:
                 unlink(filepath)
             except Exception, ex:
                 self.error('cant remove %s: %s' % (filepath, ex))
 
-class DeleteFileOp(hook.Operation):
-    def commit_event(self):
-        for filepath in self.session.transaction_data.pop('bfss_deleted'):
+class DeleteFileOp(hook.DataOperationMixIn, hook.Operation):
+    def postcommit_event(self):
+        for filepath in self.get_data():
             try:
                 unlink(filepath)
             except Exception, ex:
--- a/server/sqlutils.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/sqlutils.py	Wed Oct 13 08:37:21 2010 +0200
@@ -165,7 +165,7 @@
         self.OperationalError = dbapi_module.OperationalError
         self.InterfaceError = dbapi_module.InterfaceError
         self.DbapiError = dbapi_module.Error
-        self._binary = dbapi_module.Binary
+        self._binary = self.dbhelper.binary_value
         self._process_value = dbapi_module.process_value
         self._dbencoding = dbencoding
 
@@ -260,8 +260,7 @@
         """
         attrs = {}
         eschema = entity.e_schema
-        for attr in entity.edited_attributes:
-            value = entity[attr]
+        for attr, value in entity.cw_edited.iteritems():
             if value is not None and eschema.subjrels[attr].final:
                 atype = str(entity.e_schema.destination(attr))
                 if atype == 'Boolean':
--- a/server/ssplanner.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/ssplanner.py	Wed Oct 13 08:37:21 2010 +0200
@@ -21,6 +21,8 @@
 
 __docformat__ = "restructuredtext en"
 
+from copy import copy
+
 from rql.stmts import Union, Select
 from rql.nodes import Constant, Relation
 
@@ -55,11 +57,11 @@
             if isinstance(rhs, Constant) and not rhs.uid:
                 # add constant values to entity def
                 value = rhs.eval(plan.args)
-                eschema = edef.e_schema
+                eschema = edef.entity.e_schema
                 attrtype = eschema.subjrels[rtype].objects(eschema)[0]
                 if attrtype == 'Password' and isinstance(value, unicode):
                     value = value.encode('UTF8')
-                edef[rtype] = value
+                edef.edited_attribute(rtype, value)
             elif to_build.has_key(str(rhs)):
                 # create a relation between two newly created variables
                 plan.add_relation_def((edef, rtype, to_build[rhs.name]))
@@ -126,6 +128,132 @@
     return select
 
 
+_MARKER = object()
+
+class dict_protocol_catcher(object):
+    def __init__(self, entity):
+        self.__entity = entity
+    def __getitem__(self, attr):
+        return self.__entity.cw_edited[attr]
+    def __setitem__(self, attr, value):
+        self.__entity.cw_edited[attr] = value
+    def __getattr__(self, attr):
+        return getattr(self.__entity, attr)
+
+
+class EditedEntity(dict):
+    """encapsulate entities attributes being written by an RQL query"""
+    def __init__(self, entity, **kwargs):
+        dict.__init__(self, **kwargs)
+        self.entity = entity
+        self.skip_security = set()
+        self.querier_pending_relations = {}
+        self.saved = False
+
+    def __hash__(self):
+        # dict|set keyable
+        return hash(id(self))
+
+    def __cmp__(self, other):
+        # we don't want comparison by value inherited from dict
+        return cmp(id(self), id(other))
+
+    def __setitem__(self, attr, value):
+        assert attr != 'eid'
+        # don't add attribute into skip_security if already in edited
+        # attributes, else we may accidentaly skip a desired security check
+        if attr not in self:
+            self.skip_security.add(attr)
+        self.edited_attribute(attr, value)
+
+    def __delitem__(self, attr):
+        assert not self.saved, 'too late to modify edited attributes'
+        super(EditedEntity, self).__delitem__(attr)
+        self.entity.cw_attr_cache.pop(attr, None)
+
+    def pop(self, attr, *args):
+        # don't update skip_security by design (think to storage api)
+        assert not self.saved, 'too late to modify edited attributes'
+        value = super(EditedEntity, self).pop(attr, *args)
+        self.entity.cw_attr_cache.pop(attr, *args)
+        return value
+
+    def setdefault(self, attr, default):
+        assert attr != 'eid'
+        # don't add attribute into skip_security if already in edited
+        # attributes, else we may accidentaly skip a desired security check
+        if attr not in self:
+            self[attr] = default
+        return self[attr]
+
+    def update(self, values, skipsec=True):
+        if skipsec:
+            setitem = self.__setitem__
+        else:
+            setitem = self.edited_attribute
+        for attr, value in values.iteritems():
+            setitem(attr, value)
+
+    def edited_attribute(self, attr, value):
+        """attribute being edited by a rql query: should'nt be added to
+        skip_security
+        """
+        assert not self.saved, 'too late to modify edited attributes'
+        super(EditedEntity, self).__setitem__(attr, value)
+        self.entity.cw_attr_cache[attr] = value
+
+    def oldnewvalue(self, attr):
+        """returns the couple (old attr value, new attr value)
+
+        NOTE: will only work in a before_update_entity hook
+        """
+        assert not self.saved, 'too late to get the old value'
+        # get new value and remove from local dict to force a db query to
+        # fetch old value
+        newvalue = self.entity.cw_attr_cache.pop(attr, _MARKER)
+        oldvalue = getattr(self.entity, attr)
+        if newvalue is not _MARKER:
+            self.entity.cw_attr_cache[attr] = newvalue
+        else:
+            newvalue = oldvalue
+        return oldvalue, newvalue
+
+    def set_defaults(self):
+        """set default values according to the schema"""
+        for attr, value in self.entity.e_schema.defaults():
+            if not attr in self:
+                self[str(attr)] = value
+
+    def check(self, creation=False):
+        """check the entity edition against its schema. Only final relation
+        are checked here, constraint on actual relations are checked in hooks
+        """
+        entity = self.entity
+        if creation:
+            # on creations, we want to check all relations, especially
+            # required attributes
+            relations = [rschema for rschema in entity.e_schema.subject_relations()
+                         if rschema.final and rschema.type != 'eid']
+        else:
+            relations = [entity._cw.vreg.schema.rschema(rtype)
+                         for rtype in self]
+        from yams import ValidationError
+        try:
+            entity.e_schema.check(dict_protocol_catcher(entity),
+                                  creation=creation, _=entity._cw._,
+                                  relations=relations)
+        except ValidationError, ex:
+            ex.entity = self.entity
+            raise
+
+    def clone(self):
+        thecopy = EditedEntity(copy(self.entity))
+        thecopy.entity.cw_attr_cache = copy(self.entity.cw_attr_cache)
+        thecopy.entity._cw_related_cache = {}
+        thecopy.update(self, skipsec=False)
+        return thecopy
+
+
 class SSPlanner(object):
     """SingleSourcePlanner: build execution plan for rql queries
 
@@ -162,7 +290,7 @@
         etype_class = session.vreg['etypes'].etype_class
         for etype, var in rqlst.main_variables:
             # need to do this since entity class is shared w. web client code !
-            to_build[var.name] = etype_class(etype)(session)
+            to_build[var.name] = EditedEntity(etype_class(etype)(session))
             plan.add_entity_def(to_build[var.name])
         # add constant values to entity def, mark variables to be selected
         to_select = _extract_const_attributes(plan, rqlst, to_build)
@@ -177,7 +305,7 @@
         for edef, rdefs in to_select.items():
             # create a select rql st to fetch needed data
             select = Select()
-            eschema = edef.e_schema
+            eschema = edef.entity.e_schema
             for i, (rtype, term, reverse) in enumerate(rdefs):
                 if getattr(term, 'variable', None) in eidconsts:
                     value = eidconsts[term.variable]
@@ -284,10 +412,8 @@
                 rhsinfo = selectedidx[rhskey][:-1] + (None,)
             rschema = getrschema(relation.r_type)
             updatedefs.append( (lhsinfo, rhsinfo, rschema) )
-            if rschema.final or rschema.inlined:
-                attributes.add(relation.r_type)
         # the update step
-        step = UpdateStep(plan, updatedefs, attributes)
+        step = UpdateStep(plan, updatedefs)
         # when necessary add substep to fetch yet unknown values
         select = _build_substep_query(select, rqlst)
         if select is not None:
@@ -476,7 +602,7 @@
             result = [[]]
         for row in result:
             # get a new entity definition for this row
-            edef = base_edef.cw_copy()
+            edef = base_edef.clone()
             # complete this entity def using row values
             index = 0
             for rtype, rorder, value in self.rdefs:
@@ -484,7 +610,7 @@
                     value = row[index]
                     index += 1
                 if rorder == InsertRelationsStep.FINAL:
-                    edef._cw_rql_set_value(rtype, value)
+                    edef.edited_attribute(rtype, value)
                 elif rorder == InsertRelationsStep.RELATION:
                     self.plan.add_relation_def( (edef, rtype, value) )
                     edef.querier_pending_relations[(rtype, 'subject')] = value
@@ -495,6 +621,7 @@
         self.plan.substitute_entity_def(base_edef, edefs)
         return result
 
+
 class InsertStep(Step):
     """step consisting in inserting new entities / relations"""
 
@@ -524,13 +651,9 @@
         # mark eids as being deleted in session info and setup cache update
         # operation (register pending eids before actual deletion to avoid
         # multiple call to glob_delete_entity)
-        try:
-            pending = session.transaction_data['pendingeids']
-        except KeyError:
-            pending = session.transaction_data['pendingeids'] = set()
-            CleanupDeletedEidsCacheOp(session)
-        actual = todelete - pending
-        pending |= actual
+        op = CleanupDeletedEidsCacheOp.get_instance(session)
+        actual = todelete - op._container
+        op._container |= actual
         for eid in actual:
             delete(session, eid)
         return results
@@ -555,10 +678,9 @@
     definitions and from results fetched in previous step
     """
 
-    def __init__(self, plan, updatedefs, attributes):
+    def __init__(self, plan, updatedefs):
         Step.__init__(self, plan)
         self.updatedefs = updatedefs
-        self.attributes = attributes
 
     def execute(self):
         """execute this step"""
@@ -578,16 +700,17 @@
                 if rschema.final or rschema.inlined:
                     eid = typed_eid(lhsval)
                     try:
-                        edef = edefs[eid]
+                        edited = edefs[eid]
                     except KeyError:
-                        edefs[eid] = edef = session.entity_from_eid(eid)
-                    edef._cw_rql_set_value(str(rschema), rhsval)
+                        edef = session.entity_from_eid(eid)
+                        edefs[eid] = edited = EditedEntity(edef)
+                    edited.edited_attribute(str(rschema), rhsval)
                 else:
                     repo.glob_add_relation(session, lhsval, str(rschema), rhsval)
             result[i] = newrow
         # update entities
-        for eid, edef in edefs.iteritems():
-            repo.glob_update_entity(session, edef, set(self.attributes))
+        for eid, edited in edefs.iteritems():
+            repo.glob_update_entity(session, edited)
         return result
 
 def _handle_relterm(info, row, newrow):
--- a/server/test/data/migratedapp/schema.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/data/migratedapp/schema.py	Wed Oct 13 08:37:21 2010 +0200
@@ -66,6 +66,7 @@
     whatever = Int(default=2)  # keep it before `date` for unittest_migraction.test_add_attribute_int
     date = Datetime()
     type = String(maxsize=1)
+    unique_id = String(maxsize=1, required=True, unique=True)
     mydate = Date(default='TODAY')
     shortpara = String(maxsize=64)
     ecrit_par = SubjectRelation('Personne', constraints=[RQLConstraint('S concerne A, O concerne A')])
--- a/server/test/data/schema.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/data/schema.py	Wed Oct 13 08:37:21 2010 +0200
@@ -17,7 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
 from yams.buildobjs import (EntityType, RelationType, RelationDefinition,
-                            SubjectRelation, RichString, String, Int, Boolean, Datetime)
+                            SubjectRelation, RichString, String, Int, Float,
+                            Boolean, Datetime)
 from yams.constraints import SizeConstraint
 from cubicweb.schema import (WorkflowableEntityType,
                              RQLConstraint, RQLUniqueConstraint,
@@ -40,7 +41,7 @@
                        description=_('more detailed description'))
 
     duration = Int()
-    invoiced = Int()
+    invoiced = Float()
 
     depends_on = SubjectRelation('Affaire')
     require_permission = SubjectRelation('CWPermission')
--- a/server/test/data/sources	Wed Oct 13 08:37:09 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-[system]
-
-db-driver   = sqlite
-db-host     = 
-adapter     = native
-db-name     = tmpdb
-db-encoding = UTF-8
-db-user     = admin
-db-password = gingkow
-
-[admin]
-login = admin
-password = gingkow
-
--- a/server/test/data/sources_extern	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/data/sources_extern	Wed Oct 13 08:37:21 2010 +0200
@@ -1,13 +1,4 @@
 [system]
-
 db-driver   = sqlite
-db-host     = 
-adapter     = native
 db-name     = tmpdb-extern
 db-encoding = UTF-8
-db-user     = admin
-db-password = gingkow
-
-[admin]
-login = admin
-password = gingkow
--- a/server/test/data/sources_ldap1	Wed Oct 13 08:37:09 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-[system]
-adapter=native
-# database driver (postgres or sqlite)
-db-driver=sqlite
-# database host
-db-host=
-# database name
-db-name=tmpdb
-# database user
-db-user=admin
-# database password
-db-password=gingkow
-# database encoding
-db-encoding=utf8
-
-[admin]
-login = admin
-password = gingkow
-
-[ldapuser]
-adapter=ldapuser
-# ldap host
-host=ldap1
-# base DN to lookup for usres
-user-base-dn=ou=People,dc=logilab,dc=fr
-# user search scope
-user-scope=ONELEVEL
-# classes of user
-user-classes=top,posixAccount
-# attribute used as login on authentication
-user-login-attr=uid
-# name of a group in which ldap users will be by default
-user-default-group=users
-# map from ldap user attributes to cubicweb attributes
-user-attrs-map=gecos:email,uid:login
--- a/server/test/data/sources_ldap2	Wed Oct 13 08:37:09 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-[system]
-adapter=native
-# database driver (postgres or sqlite)
-db-driver=sqlite
-# database host
-db-host=
-# database name
-db-name=tmpdb
-# database user
-db-user=admin
-# database password
-db-password=gingkow
-# database encoding
-db-encoding=utf8
-
-[admin]
-login = admin
-password = gingkow
-
-[ldapuser]
-adapter=ldapuser
-# ldap host
-host=ldap1
-# base DN to lookup for usres
-user-base-dn=ou=People,dc=logilab,dc=net
-# user search scope
-user-scope=ONELEVEL
-# classes of user
-user-classes=top,OpenLDAPperson
-# attribute used as login on authentication
-user-login-attr=uid
-# name of a group in which ldap users will be by default
-user-default-group=users
-# map from ldap user attributes to cubicweb attributes
-user-attrs-map=mail:email,uid:login
--- a/server/test/data/sources_multi	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/data/sources_multi	Wed Oct 13 08:37:21 2010 +0200
@@ -1,28 +1,5 @@
 [system]
-
 db-driver   = sqlite
-db-host     = 
 adapter     = native
 db-name     = tmpdb-multi
 db-encoding = UTF-8
-db-user     = admin
-db-password = gingkow
-
-[extern]
-adapter = pyrorql
-pyro-ns-id = extern
-cubicweb-user = admin
-cubicweb-password = gingkow
-mapping-file = extern_mapping.py
-base-url=http://extern.org/
-
-[extern-multi]
-adapter = pyrorql
-pyro-ns-id = extern-multi
-cubicweb-user = admin
-cubicweb-password = gingkow
-mapping-file = extern_mapping.py
-
-[admin]
-login = admin
-password = gingkow
--- a/server/test/unittest_ldapuser.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/unittest_ldapuser.py	Wed Oct 13 08:37:21 2010 +0200
@@ -20,7 +20,6 @@
 import socket
 
 from logilab.common.testlib import TestCase, unittest_main, mock_object
-from cubicweb.devtools import TestServerConfiguration
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.devtools.repotest import RQLGeneratorTC
 
@@ -30,12 +29,26 @@
     SYT = 'syt'
     SYT_EMAIL = 'Sylvain Thenault'
     ADIM = 'adim'
-    SOURCESFILE = 'data/sources_ldap1'
+    CONFIG = u'''host=ldap1
+user-base-dn=ou=People,dc=logilab,dc=fr
+user-scope=ONELEVEL
+user-classes=top,posixAccount
+user-login-attr=uid
+user-default-group=users
+user-attrs-map=gecos:email,uid:login
+'''
 else:
     SYT = 'sthenault'
     SYT_EMAIL = 'sylvain.thenault@logilab.fr'
     ADIM = 'adimascio'
-    SOURCESFILE = 'data/sources_ldap2'
+    CONFIG = u'''host=ldap1
+user-base-dn=ou=People,dc=logilab,dc=net
+user-scope=ONELEVEL
+user-classes=top,OpenLDAPperson
+user-login-attr=uid
+user-default-group=users
+user-attrs-map=mail:email,uid:login
+'''
 
 
 def nopwd_authenticate(self, session, login, password):
@@ -57,25 +70,36 @@
     # don't check upassword !
     return self.extid2eid(user['dn'], 'CWUser', session)
 
+def setup_module(*args):
+    global repo
+    LDAPUserSourceTC._init_repo()
+    repo = LDAPUserSourceTC.repo
+    add_ldap_source(LDAPUserSourceTC.cnx)
+
+def teardown_module(*args):
+    global repo
+    repo.shutdown()
+    del repo
+
+def add_ldap_source(cnx):
+    cnx.request().create_entity('CWSource', name=u'ldapuser', type=u'ldapuser',
+                                config=CONFIG)
+    cnx.commit()
+    # XXX: need this first query else we get 'database is locked' from
+    # sqlite since it doesn't support multiple connections on the same
+    # database
+    # so doing, ldap inserted users don't get removed between each test
+    rset = cnx.cursor().execute('CWUser X')
+    # check we get some users from ldap
+    assert len(rset) > 1
 
 
 class LDAPUserSourceTC(CubicWebTC):
-    config = TestServerConfiguration('data')
-    config.sources_file = lambda: SOURCESFILE
 
     def patch_authenticate(self):
         self._orig_authenticate = LDAPUserSource.authenticate
         LDAPUserSource.authenticate = nopwd_authenticate
 
-    def setup_database(self):
-        # XXX: need this first query else we get 'database is locked' from
-        # sqlite since it doesn't support multiple connections on the same
-        # database
-        # so doing, ldap inserted users don't get removed between each test
-        rset = self.sexecute('CWUser X')
-        # check we get some users from ldap
-        self.assert_(len(rset) > 1)
-
     def tearDown(self):
         if hasattr(self, '_orig_authenticate'):
             LDAPUserSource.authenticate = self._orig_authenticate
@@ -382,19 +406,10 @@
         res = trfunc.apply([[1, 2], [2, 4], [3, 6], [1, 5]])
         self.assertEqual(res, [[1, 5], [2, 4], [3, 6]])
 
-# XXX
-LDAPUserSourceTC._init_repo()
-repo = LDAPUserSourceTC.repo
-
-def teardown_module(*args):
-    global repo
-    del repo
-    del RQL2LDAPFilterTC.schema
-
 class RQL2LDAPFilterTC(RQLGeneratorTC):
-    schema = repo.schema
 
     def setUp(self):
+        self.schema = repo.schema
         RQLGeneratorTC.setUp(self)
         ldapsource = repo.sources[-1]
         self.pool = repo._get_pool()
--- a/server/test/unittest_migractions.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/unittest_migractions.py	Wed Oct 13 08:37:21 2010 +0200
@@ -18,13 +18,17 @@
 """unit tests for module cubicweb.server.migractions
 """
 
+from __future__ import with_statement
+
 from copy import deepcopy
 from datetime import date
 from os.path import join
 
 from logilab.common.testlib import TestCase, unittest_main
 
-from cubicweb import ConfigurationError
+from yams.constraints import UniqueConstraint
+
+from cubicweb import ConfigurationError, ValidationError
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.schema import CubicWebSchemaLoader
 from cubicweb.server.sqlutils import SQL_PREFIX
@@ -130,6 +134,29 @@
         self.assertEqual(d2, testdate)
         self.mh.rollback()
 
+    def test_drop_chosen_constraints_ctxmanager(self):
+        with self.mh.cmd_dropped_constraints('Note', 'unique_id', UniqueConstraint):
+            self.mh.cmd_add_attribute('Note', 'unique_id')
+            # make sure the maxsize constraint is not dropped
+            self.assertRaises(ValidationError,
+                              self.mh.rqlexec,
+                              'INSERT Note N: N unique_id "xyz"')
+            self.mh.rollback()
+            # make sure the unique constraint is dropped
+            self.mh.rqlexec('INSERT Note N: N unique_id "x"')
+            self.mh.rqlexec('INSERT Note N: N unique_id "x"')
+            self.mh.rqlexec('DELETE Note N')
+        self.mh.rollback()
+
+    def test_drop_required_ctxmanager(self):
+        with self.mh.cmd_dropped_constraints('Note', 'unique_id', cstrtype=None,
+                                             droprequired=True):
+            self.mh.cmd_add_attribute('Note', 'unique_id')
+            self.mh.rqlexec('INSERT Note N')
+        # make sure the required=True was restored
+        self.assertRaises(ValidationError, self.mh.rqlexec, 'INSERT Note N')
+        self.mh.rollback()
+
     def test_rename_attribute(self):
         self.failIf('civility' in self.schema)
         eid1 = self.mh.rqlexec('INSERT Personne X: X nom "lui", X sexe "M"')[0][0]
@@ -164,7 +191,7 @@
         self.failUnless(self.execute('CWRType X WHERE X name "filed_under2"'))
         self.schema.rebuild_infered_relations()
         self.assertEqual(sorted(str(rs) for rs in self.schema['Folder2'].subject_relations()),
-                          ['created_by', 'creation_date', 'cwuri',
+                          ['created_by', 'creation_date', 'cw_source', 'cwuri',
                            'description', 'description_format',
                            'eid',
                            'filed_under2', 'has_text',
@@ -309,7 +336,7 @@
         migrschema['titre'].rdefs[('Personne', 'String')].description = 'title for this person'
         delete_concerne_rqlexpr = self._rrqlexpr_rset('delete', 'concerne')
         add_concerne_rqlexpr = self._rrqlexpr_rset('add', 'concerne')
-        
+
         self.mh.cmd_sync_schema_props_perms(commit=False)
 
         self.assertEqual(cursor.execute('Any D WHERE X name "Personne", X description D')[0][0],
@@ -524,7 +551,7 @@
         self.assertEqual(self.schema['Text'].specializes().type, 'Para')
         # test columns have been actually added
         text = self.execute('INSERT Text X: X para "hip", X summary "hop", X newattr "momo"').get_entity(0, 0)
-        note = self.execute('INSERT Note X: X para "hip", X shortpara "hop", X newattr "momo"').get_entity(0, 0)
+        note = self.execute('INSERT Note X: X para "hip", X shortpara "hop", X newattr "momo", X unique_id "x"').get_entity(0, 0)
         aff = self.execute('INSERT Affaire X').get_entity(0, 0)
         self.failUnless(self.execute('SET X newnotinlined Y WHERE X eid %(x)s, Y eid %(y)s',
                                      {'x': text.eid, 'y': aff.eid}))
--- a/server/test/unittest_msplanner.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/unittest_msplanner.py	Wed Oct 13 08:37:21 2010 +0200
@@ -18,6 +18,8 @@
 
 from logilab.common.decorators import clear_cache
 
+from rql import BadRQLQuery
+
 from cubicweb.devtools import init_test_database
 from cubicweb.devtools.repotest import BasePlannerTC, test_plan
 
@@ -59,8 +61,9 @@
                      {'X': 'Bookmark'}, {'X': 'CWAttribute'}, {'X': 'CWCache'},
                      {'X': 'CWConstraint'}, {'X': 'CWConstraintType'}, {'X': 'CWEType'},
                      {'X': 'CWGroup'}, {'X': 'CWPermission'}, {'X': 'CWProperty'},
-                     {'X': 'CWRType'}, {'X': 'CWRelation'}, {'X': 'CWUser'},
-                     {'X': 'CWUniqueTogetherConstraint'},
+                     {'X': 'CWRType'}, {'X': 'CWRelation'},
+                     {'X': 'CWSource'}, {'X': 'CWSourceHostConfig'},
+                     {'X': 'CWUser'}, {'X': 'CWUniqueTogetherConstraint'},
                      {'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
                      {'X': 'Email'}, {'X': 'EmailAddress'}, {'X': 'EmailPart'},
                      {'X': 'EmailThread'}, {'X': 'ExternalUri'}, {'X': 'File'},
@@ -537,7 +540,7 @@
                      [self.ldap, self.system], None,
                      {'AA': 'table0.C1', 'X': 'table0.C0', 'X.modification_date': 'table0.C1'}, []),
                     ('OneFetchStep',
-                     [('Any X,AA ORDERBY AA WHERE 5 owned_by X, X modification_date AA, X is CWUser',
+                     [('Any X,AA ORDERBY AA WHERE %s owned_by X, X modification_date AA, X is CWUser' % ueid,
                        [{'AA': 'Datetime', 'X': 'CWUser'}])],
                      None, None, [self.system],
                      {'AA': 'table0.C1', 'X': 'table0.C0', 'X.modification_date': 'table0.C1'}, []),
@@ -687,7 +690,7 @@
     def test_complex_optional(self):
         ueid = self.session.user.eid
         self._test('Any U WHERE WF wf_info_for X, X eid %(x)s, WF owned_by U?, WF from_state FS',
-                   [('OneFetchStep', [('Any U WHERE WF wf_info_for 5, WF owned_by U?, WF from_state FS',
+                   [('OneFetchStep', [('Any U WHERE WF wf_info_for %s, WF owned_by U?, WF from_state FS' % ueid,
                                        [{'WF': 'TrInfo', 'FS': 'State', 'U': 'CWUser'}])],
                      None, None, [self.system], {}, [])],
                    {'x': ueid})
@@ -695,7 +698,7 @@
     def test_complex_optional(self):
         ueid = self.session.user.eid
         self._test('Any U WHERE WF wf_info_for X, X eid %(x)s, WF owned_by U?, WF from_state FS',
-                   [('OneFetchStep', [('Any U WHERE WF wf_info_for 5, WF owned_by U?, WF from_state FS',
+                   [('OneFetchStep', [('Any U WHERE WF wf_info_for %s, WF owned_by U?, WF from_state FS' % ueid,
                                        [{'WF': 'TrInfo', 'FS': 'State', 'U': 'CWUser'}])],
                      None, None, [self.system], {}, [])],
                    {'x': ueid})
@@ -751,9 +754,10 @@
                     ])
 
     def test_not_identity(self):
-        self._test('Any X WHERE NOT X identity U, U eid %s' % self.session.user.eid,
+        ueid = self.session.user.eid
+        self._test('Any X WHERE NOT X identity U, U eid %s' % ueid,
                    [('OneFetchStep',
-                     [('Any X WHERE NOT X identity 5, X is CWUser', [{'X': 'CWUser'}])],
+                     [('Any X WHERE NOT X identity %s, X is CWUser' % ueid, [{'X': 'CWUser'}])],
                      None, None,
                      [self.ldap, self.system], {}, [])
                     ])
@@ -777,18 +781,19 @@
     def test_security_has_text(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X WHERE X has_text "bla"',
                    [('FetchStep', [('Any E WHERE E type "X", E is Note', [{'E': 'Note'}])],
                      [self.cards, self.system], None, {'E': 'table0.C0'}, []),
                     ('UnionStep', None, None,
                      [('OneFetchStep',
-                       [(u'Any X WHERE X has_text "bla", (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
+                       [(u'Any X WHERE X has_text "bla", (EXISTS(X owned_by %(ueid)s)) OR ((((EXISTS(D concerne C?, C owned_by %(ueid)s, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by %(ueid)s, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by %(ueid)s, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by %(ueid)s, X identity J, E is Note, J is Affaire))), X is Affaire' % {'ueid': ueid},
                          [{'C': 'Division', 'E': 'Note', 'D': 'Affaire', 'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire', 'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire'}])],
                        None, None, [self.system], {'E': 'table0.C0'}, []),
                       ('OneFetchStep',
-                       [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
+                       [('Any X WHERE X has_text "bla", EXISTS(X owned_by %s), X is Basket' % ueid,
                          [{'X': 'Basket'}]),
-                        ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
+                        ('Any X WHERE X has_text "bla", EXISTS(X owned_by %s), X is CWUser' % ueid,
                          [{'X': 'CWUser'}]),
                         ('Any X WHERE X has_text "bla", X is IN(Card, Comment, Division, Email, EmailThread, File, Folder, Note, Personne, Societe, SubDivision, Tag)',
                          [{'X': 'Card'}, {'X': 'Comment'},
@@ -803,18 +808,19 @@
     def test_security_has_text_limit_offset(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         # note: same as the above query but because of the subquery usage, the display differs (not printing solutions for each union)
         self._test('Any X LIMIT 10 OFFSET 10 WHERE X has_text "bla"',
                    [('FetchStep', [('Any E WHERE E type "X", E is Note', [{'E': 'Note'}])],
                       [self.cards, self.system], None, {'E': 'table1.C0'}, []),
                      ('UnionFetchStep', [
-                         ('FetchStep', [('Any X WHERE X has_text "bla", (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
+                        ('FetchStep', [('Any X WHERE X has_text "bla", (EXISTS(X owned_by %(ueid)s)) OR ((((EXISTS(D concerne C?, C owned_by %(ueid)s, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by %(ueid)s, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by %(ueid)s, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by %(ueid)s, X identity J, E is Note, J is Affaire))), X is Affaire' % {'ueid': ueid},
                                             [{'C': 'Division', 'E': 'Note', 'D': 'Affaire', 'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire', 'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire'}])],
                           [self.system], {'E': 'table1.C0'}, {'X': 'table0.C0'}, []),
                          ('FetchStep',
-                          [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
+                          [('Any X WHERE X has_text "bla", EXISTS(X owned_by %s), X is Basket' % ueid,
                             [{'X': 'Basket'}]),
-                           ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
+                           ('Any X WHERE X has_text "bla", EXISTS(X owned_by %s), X is CWUser' % ueid,
                             [{'X': 'CWUser'}]),
                            ('Any X WHERE X has_text "bla", X is IN(Card, Comment, Division, Email, EmailThread, File, Folder, Note, Personne, Societe, SubDivision, Tag)',
                             [{'X': 'Card'}, {'X': 'Comment'},
@@ -839,22 +845,24 @@
         """a guest user trying to see another user: EXISTS(X owned_by U) is automatically inserted"""
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X WHERE X login "bla"',
                    [('FetchStep',
                      [('Any X WHERE X login "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X WHERE EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
+                     [('Any X WHERE EXISTS(X owned_by %s), X is CWUser' % ueid, [{'X': 'CWUser'}])],
                      None, None, [self.system], {'X': 'table0.C0'}, [])])
 
     def test_security_complex_has_text(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X WHERE X has_text "bla", X firstname "bla"',
                    [('FetchStep', [('Any X WHERE X firstname "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C0'}, []),
                     ('UnionStep', None, None, [
-                        ('OneFetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
+                        ('OneFetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by %s), X is CWUser' % ueid, [{'X': 'CWUser'}])],
                          None, None, [self.system], {'X': 'table0.C0'}, []),
                         ('OneFetchStep', [('Any X WHERE X has_text "bla", X firstname "bla", X is Personne', [{'X': 'Personne'}])],
                          None, None, [self.system], {}, []),
@@ -864,11 +872,12 @@
     def test_security_complex_has_text_limit_offset(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X LIMIT 10 OFFSET 10 WHERE X has_text "bla", X firstname "bla"',
                    [('FetchStep', [('Any X WHERE X firstname "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table1.C0'}, []),
                     ('UnionFetchStep', [
-                        ('FetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
+                        ('FetchStep', [('Any X WHERE X has_text "bla", EXISTS(X owned_by %s), X is CWUser' % ueid, [{'X': 'CWUser'}])],
                          [self.system], {'X': 'table1.C0'}, {'X': 'table0.C0'}, []),
                         ('FetchStep', [('Any X WHERE X has_text "bla", X firstname "bla", X is Personne', [{'X': 'Personne'}])],
                          [self.system], {}, {'X': 'table0.C0'}, []),
@@ -881,26 +890,30 @@
     def test_security_complex_aggregat(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
+        ALL_SOLS = X_ALL_SOLS[:]
+        ALL_SOLS.remove({'X': 'CWSourceHostConfig'}) # not authorized
         self._test('Any MAX(X)',
                    [('FetchStep', [('Any E WHERE E type "X", E is Note', [{'E': 'Note'}])],
                      [self.cards, self.system],  None, {'E': 'table1.C0'}, []),
                     ('FetchStep', [('Any X WHERE X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table2.C0'}, []),
                     ('UnionFetchStep', [
-                        ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is Basket', [{'X': 'Basket'}])],
+                        ('FetchStep', [('Any X WHERE EXISTS(X owned_by %s), X is Basket' % ueid, [{'X': 'Basket'}])],
                           [self.system], {}, {'X': 'table0.C0'}, []),
                         ('UnionFetchStep',
                          [('FetchStep', [('Any X WHERE X is IN(Card, Note, State)',
                                           [{'X': 'Card'}, {'X': 'Note'}, {'X': 'State'}])],
                            [self.cards, self.system], {}, {'X': 'table0.C0'}, []),
                           ('FetchStep',
-                           [('Any X WHERE X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWUniqueTogetherConstraint, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
+                           [('Any X WHERE X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWSource, CWUniqueTogetherConstraint, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
                              [{'X': 'BaseTransition'}, {'X': 'Bookmark'},
                               {'X': 'CWAttribute'}, {'X': 'CWCache'},
                               {'X': 'CWConstraint'}, {'X': 'CWConstraintType'},
                               {'X': 'CWEType'}, {'X': 'CWGroup'},
                               {'X': 'CWPermission'}, {'X': 'CWProperty'},
                               {'X': 'CWRType'}, {'X': 'CWRelation'},
+                              {'X': 'CWSource'},
                               {'X': 'CWUniqueTogetherConstraint'},
                               {'X': 'Comment'}, {'X': 'Division'},
                               {'X': 'Email'}, {'X': 'EmailAddress'},
@@ -914,21 +927,24 @@
                               {'X': 'Workflow'}, {'X': 'WorkflowTransition'}])],
                            [self.system], {}, {'X': 'table0.C0'}, []),
                           ]),
-                        ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
+                        ('FetchStep', [('Any X WHERE EXISTS(X owned_by %s), X is CWUser' % ueid, [{'X': 'CWUser'}])],
                          [self.system], {'X': 'table2.C0'}, {'X': 'table0.C0'}, []),
-                        ('FetchStep', [('Any X WHERE (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
+                        ('FetchStep', [('Any X WHERE (EXISTS(X owned_by %(ueid)s)) OR ((((EXISTS(D concerne C?, C owned_by %(ueid)s, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by %(ueid)s, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by %(ueid)s, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by %(ueid)s, X identity J, E is Note, J is Affaire))), X is Affaire' % {'ueid': ueid},
                                         [{'C': 'Division', 'E': 'Note', 'D': 'Affaire', 'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire', 'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire'}])],
                          [self.system], {'E': 'table1.C0'}, {'X': 'table0.C0'}, []),
                         ]),
-                    ('OneFetchStep', [('Any MAX(X)', X_ALL_SOLS)],
+                    ('OneFetchStep', [('Any MAX(X)', ALL_SOLS)],
                      None, None, [self.system], {'X': 'table0.C0'}, [])
                     ])
 
     def test_security_complex_aggregat2(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         X_ET_ALL_SOLS = []
         for s in X_ALL_SOLS:
+            if s == {'X': 'CWSourceHostConfig'}:
+                continue # not authorized
             ets = {'ET': 'CWEType'}
             ets.update(s)
             X_ET_ALL_SOLS.append(ets)
@@ -941,28 +957,29 @@
                     ('FetchStep', [('Any X WHERE X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table3.C0'}, []),
                     ('UnionFetchStep',
-                     [('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is CWEType, X is Basket',
+                     [('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by %s), ET is CWEType, X is Basket' % ueid,
                                       [{'ET': 'CWEType', 'X': 'Basket'}])],
                        [self.system], {}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
-                      ('FetchStep', [('Any ET,X WHERE X is ET, (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), ET is CWEType, X is Affaire',
+                      ('FetchStep', [('Any ET,X WHERE X is ET, (EXISTS(X owned_by %(ueid)s)) OR ((((EXISTS(D concerne C?, C owned_by %(ueid)s, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by %(ueid)s, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by %(ueid)s, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by %(ueid)s, X identity J, E is Note, J is Affaire))), ET is CWEType, X is Affaire' % {'ueid': ueid},
                                       [{'C': 'Division', 'E': 'Note', 'D': 'Affaire',
                                         'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire',
                                         'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire',
                                         'ET': 'CWEType'}])],
                        [self.system], {'E': 'table2.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'},
                        []),
-                      ('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is CWEType, X is CWUser',
+                      ('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by %s), ET is CWEType, X is CWUser' % ueid,
                                       [{'ET': 'CWEType', 'X': 'CWUser'}])],
                        [self.system], {'X': 'table3.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
                       # extra UnionFetchStep could be avoided but has no cost, so don't care
                       ('UnionFetchStep',
-                       [('FetchStep', [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWUniqueTogetherConstraint, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
+                       [('FetchStep', [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWSource, CWUniqueTogetherConstraint, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
                                         [{'X': 'BaseTransition', 'ET': 'CWEType'},
                                          {'X': 'Bookmark', 'ET': 'CWEType'}, {'X': 'CWAttribute', 'ET': 'CWEType'},
                                          {'X': 'CWCache', 'ET': 'CWEType'}, {'X': 'CWConstraint', 'ET': 'CWEType'},
                                          {'X': 'CWConstraintType', 'ET': 'CWEType'}, {'X': 'CWEType', 'ET': 'CWEType'},
                                          {'X': 'CWGroup', 'ET': 'CWEType'}, {'X': 'CWPermission', 'ET': 'CWEType'},
                                          {'X': 'CWProperty', 'ET': 'CWEType'}, {'X': 'CWRType', 'ET': 'CWEType'},
+                                         {'X': 'CWSource', 'ET': 'CWEType'},
                                          {'X': 'CWRelation', 'ET': 'CWEType'},
                                          {'X': 'CWUniqueTogetherConstraint', 'ET': 'CWEType'},
                                          {'X': 'Comment', 'ET': 'CWEType'},
@@ -993,6 +1010,7 @@
     def test_security_3sources(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X, XT WHERE X is Card, X owned_by U, X title XT, U login "syt"',
                    [('FetchStep',
                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
@@ -1001,7 +1019,7 @@
                      [('Any U WHERE U login "syt", U is CWUser', [{'U': 'CWUser'}])],
                      [self.ldap, self.system], None, {'U': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X,XT WHERE X owned_by U, X title XT, EXISTS(U owned_by 5), U is CWUser, X is Card',
+                     [('Any X,XT WHERE X owned_by U, X title XT, EXISTS(U owned_by %s), U is CWUser, X is Card' % ueid,
                        [{'X': 'Card', 'U': 'CWUser', 'XT': 'String'}])],
                      None, None, [self.system],
                      {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1', 'U': 'table1.C0'}, [])
@@ -1011,12 +1029,13 @@
         self.restore_orig_cwuser_security()
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X, XT WHERE X is Card, X owned_by U, X title XT, U login "syt"',
                    [('FetchStep',
                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
                      [self.cards, self.system], None, {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'}, []),
                     ('OneFetchStep',
-                     [('Any X,XT WHERE X owned_by U, X title XT, U login "syt", EXISTS(U identity 5), U is CWUser, X is Card',
+                     [('Any X,XT WHERE X owned_by U, X title XT, U login "syt", EXISTS(U identity %s), U is CWUser, X is Card' % ueid,
                        [{'U': 'CWUser', 'X': 'Card', 'XT': 'String'}])],
                      None, None, [self.system], {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1'}, [])
                     ])
@@ -1025,9 +1044,10 @@
         self.restore_orig_cwuser_security()
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X,XT,U WHERE X is Card, X owned_by U?, X title XT, U login L',
                    [('FetchStep',
-                     [('Any U,L WHERE U login L, EXISTS(U identity 5), U is CWUser',
+                     [('Any U,L WHERE U login L, EXISTS(U identity %s), U is CWUser' % ueid,
                        [{'L': 'String', u'U': 'CWUser'}])],
                      [self.system], {}, {'L': 'table0.C1', 'U': 'table0.C0', 'U.login': 'table0.C1'}, []),
                     ('FetchStep',
@@ -1046,6 +1066,7 @@
     def test_security_3sources_limit_offset(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X, XT LIMIT 10 OFFSET 10 WHERE X is Card, X owned_by U, X title XT, U login "syt"',
                    [('FetchStep',
                      [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])],
@@ -1054,7 +1075,7 @@
                      [('Any U WHERE U login "syt", U is CWUser', [{'U': 'CWUser'}])],
                      [self.ldap, self.system], None, {'U': 'table1.C0'}, []),
                     ('OneFetchStep',
-                     [('Any X,XT LIMIT 10 OFFSET 10 WHERE X owned_by U, X title XT, EXISTS(U owned_by 5), U is CWUser, X is Card',
+                     [('Any X,XT LIMIT 10 OFFSET 10 WHERE X owned_by U, X title XT, EXISTS(U owned_by %s), U is CWUser, X is Card' % ueid,
                        [{'X': 'Card', 'U': 'CWUser', 'XT': 'String'}])],
                      10, 10, [self.system],
                      {'X': 'table0.C0', 'X.title': 'table0.C1', 'XT': 'table0.C1', 'U': 'table1.C0'}, [])
@@ -1150,7 +1171,7 @@
                                                   'X.login': 'table0.C1',
                                                   'X.modification_date': 'table0.C4',
                                                   'X.surname': 'table0.C3'}, []),
-                ('OneFetchStep', [('Any X,AA,AB,AC,AD ORDERBY AA WHERE X login AA, X firstname AB, X surname AC, X modification_date AD, EXISTS(((X identity 5) OR (EXISTS(X in_group C, C name IN("managers", "staff"), C is CWGroup))) OR (EXISTS(X in_group D, 5 in_group D, NOT D name "users", D is CWGroup))), X is CWUser',
+                ('OneFetchStep', [('Any X,AA,AB,AC,AD ORDERBY AA WHERE X login AA, X firstname AB, X surname AC, X modification_date AD, EXISTS(((X identity %(ueid)s) OR (EXISTS(X in_group C, C name IN("managers", "staff"), C is CWGroup))) OR (EXISTS(X in_group D, %(ueid)s in_group D, NOT D name "users", D is CWGroup))), X is CWUser' % {'ueid': ueid},
                                    [{'AA': 'String', 'AB': 'String', 'AC': 'String', 'AD': 'Datetime',
                                      'C': 'CWGroup', 'D': 'CWGroup', 'X': 'CWUser'}])],
                  None, None, [self.system],
@@ -1227,7 +1248,7 @@
         # in the source where %(x)s is not coming from and will be removed during rql
         # generation for the external source
         self._test('Any SN WHERE NOT X in_state S, X eid %(x)s, S name SN',
-                   [('OneFetchStep', [('Any SN WHERE NOT EXISTS(5 in_state S), S name SN, S is State',
+                   [('OneFetchStep', [('Any SN WHERE NOT EXISTS(%s in_state S), S name SN, S is State' % ueid,
                                        [{'S': 'State', 'SN': 'String'}])],
                      None, None, [self.cards, self.system], {}, [])],
                    {'x': ueid})
@@ -1280,12 +1301,13 @@
 
 
     def test_simplified_var(self):
+        ueid = self.session.user.eid
         repo._type_source_cache[999999] = ('Note', 'cards', 999999)
         self._test('Any U WHERE U in_group G, (G name IN ("managers", "logilab") OR (X require_permission P?, P name "bla", P require_group G)), X eid %(x)s, U eid %(u)s',
-                   [('OneFetchStep', [('Any 5 WHERE 5 in_group G, (G name IN("managers", "logilab")) OR (X require_permission P?, P name "bla", P require_group G), X eid 999999',
+                   [('OneFetchStep', [('Any %s WHERE %s in_group G, (G name IN("managers", "logilab")) OR (X require_permission P?, P name "bla", P require_group G), X eid 999999' % (ueid, ueid),
                                        [{'X': 'Note', 'G': 'CWGroup', 'P': 'CWPermission'}])],
                      None, None, [self.system], {}, [])],
-                   {'x': 999999, 'u': self.session.user.eid})
+                   {'x': 999999, 'u': ueid})
 
     def test_has_text(self):
         self._test('Card X WHERE X has_text "toto"',
@@ -1325,13 +1347,14 @@
     def test_security_has_text_orderby_rank(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X ORDERBY FTIRANK(X) WHERE X has_text "bla", X firstname "bla"',
                    [('FetchStep', [('Any X WHERE X firstname "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table1.C0'}, []),
                     ('UnionFetchStep',
                      [('FetchStep', [('Any X WHERE X firstname "bla", X is Personne', [{'X': 'Personne'}])],
                        [self.system], {}, {'X': 'table0.C0'}, []),
-                      ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
+                      ('FetchStep', [('Any X WHERE EXISTS(X owned_by %s), X is CWUser' % ueid, [{'X': 'CWUser'}])],
                        [self.system], {'X': 'table1.C0'}, {'X': 'table0.C0'}, [])]),
                     ('OneFetchStep', [('Any X ORDERBY FTIRANK(X) WHERE X has_text "bla"',
                                        [{'X': 'CWUser'}, {'X': 'Personne'}])],
@@ -1354,11 +1377,12 @@
     def test_security_has_text_select_rank(self):
         # use a guest user
         self.session = self.user_groups_session('guests')
+        ueid = self.session.user.eid
         self._test('Any X, FTIRANK(X) WHERE X has_text "bla", X firstname "bla"',
                    [('FetchStep', [('Any X,X WHERE X firstname "bla", X is CWUser', [{'X': 'CWUser'}])],
                      [self.ldap, self.system], None, {'X': 'table0.C1'}, []),
                     ('UnionStep', None, None, [
-                        ('OneFetchStep', [('Any X,FTIRANK(X) WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
+                        ('OneFetchStep', [('Any X,FTIRANK(X) WHERE X has_text "bla", EXISTS(X owned_by %s), X is CWUser' % ueid, [{'X': 'CWUser'}])],
                          None, None, [self.system], {'X': 'table0.C1'}, []),
                         ('OneFetchStep', [('Any X,FTIRANK(X) WHERE X has_text "bla", X firstname "bla", X is Personne', [{'X': 'Personne'}])],
                          None, None, [self.system], {}, []),
@@ -1436,6 +1460,7 @@
                    ])
 
     def test_subquery_1(self):
+        ueid = self.session.user.eid
         self._test('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by D), D eid %(E)s '
                    'WITH A,N BEING ((Any X,N WHERE X is Tag, X name N) UNION (Any X,T WHERE X is Bookmark, X title T))',
                    [('FetchStep', [('Any X,N WHERE X is Tag, X name N', [{'N': 'String', 'X': 'Tag'}]),
@@ -1445,7 +1470,7 @@
                     ('FetchStep',
                      [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
-                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser, A is IN(Bookmark, Tag)',
+                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by %s), B is CWUser, A is IN(Bookmark, Tag)' % ueid,
                                        [{'A': 'Bookmark', 'B': 'CWUser', 'C': 'String'},
                                         {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
                      None, None, [self.system],
@@ -1454,9 +1479,10 @@
                       'C': 'table1.C1',
                       'N': 'table0.C1'},
                      [])],
-                   {'E': self.session.user.eid})
+                   {'E': ueid})
 
     def test_subquery_2(self):
+        ueid = self.session.user.eid
         self._test('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by D), D eid %(E)s '
                    'WITH A,N BEING ((Any X,N WHERE X is Tag, X name N) UNION (Any X,T WHERE X is Card, X title T))',
                    [('UnionFetchStep',
@@ -1479,7 +1505,7 @@
                     ('FetchStep',
                      [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])],
                      [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []),
-                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser, A is IN(Card, Tag)',
+                    ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by %s), B is CWUser, A is IN(Card, Tag)' % ueid,
                                        [{'A': 'Card', 'B': 'CWUser', 'C': 'String'},
                                         {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])],
                      None, None, [self.system],
@@ -1488,7 +1514,7 @@
                       'C': 'table1.C1',
                       'N': 'table0.C1'},
                      [])],
-                   {'E': self.session.user.eid})
+                   {'E': ueid})
 
     def test_eid_dont_cross_relation_1(self):
         repo._type_source_cache[999999] = ('Personne', 'system', 999999)
@@ -1662,7 +1688,7 @@
         ueid = self.session.user.eid
         self._test('DELETE X created_by Y WHERE X eid %(x)s, NOT Y eid %(y)s',
                    [('DeleteRelationsStep', [
-                       ('OneFetchStep', [('Any 5,Y WHERE %s created_by Y, NOT Y eid %s, Y is CWUser'%(ueid, ueid),
+                       ('OneFetchStep', [('Any %s,Y WHERE %s created_by Y, NOT Y eid %s, Y is CWUser' % (ueid, ueid, ueid),
                                           [{'Y': 'CWUser'}])],
                         None, None, [self.system], {}, []),
                        ]),
@@ -1805,6 +1831,120 @@
             del self.cards.support_relations['see_also']
             self.cards.cross_relations.remove('see_also')
 
+    def test_state_of_cross(self):
+        self._test('DELETE State X WHERE NOT X state_of Y',
+                   [('DeleteEntitiesStep',
+                     [('OneFetchStep',
+                       [('Any X WHERE NOT X state_of Y, X is State, Y is Workflow',
+                         [{'X': 'State', 'Y': 'Workflow'}])],
+                       None, None, [self.system], {}, [])])]
+                   )
+
+
+    def test_source_specified_0_0(self):
+        self._test('Card X WHERE X cw_source S, S eid 1',
+                   [('OneFetchStep', [('Any X WHERE X is Card',
+                                       [{'X': 'Card'}])],
+                     None, None,
+                     [self.system],{}, [])
+                    ])
+
+    def test_source_specified_0_1(self):
+        self._test('Any X, S WHERE X is Card, X cw_source S, S eid 1',
+                   [('OneFetchStep', [('Any X,1 WHERE X is Card',
+                                       [{'X': 'Card'}])],
+                     None, None,
+                     [self.system],{}, [])
+                    ])
+
+    def test_source_specified_1_0(self):
+        self._test('Card X WHERE X cw_source S, S name "system"',
+                   [('OneFetchStep', [('Any X WHERE X is Card',
+                                       [{'X': 'Card'}])],
+                     None, None,
+                     [self.system],{}, [])
+                    ])
+
+    def test_source_specified_1_1(self):
+        self._test('Any X, SN WHERE X is Card, X cw_source S, S name "system", S name SN',
+                   [('OneFetchStep', [('Any X,SN WHERE X is Card, X cw_source S, S name "system", '
+                                       'S name SN',
+                                       [{'S': 'CWSource', 'SN': 'String', 'X': 'Card'}])],
+                     None, None, [self.system], {}, [])
+                    ])
+
+    def test_source_specified_2_0(self):
+        self._test('Card X WHERE X cw_source S, NOT S eid 1',
+                   [('OneFetchStep', [('Any X WHERE X is Card',
+                                       [{'X': 'Card'}])],
+                     None, None,
+                     [self.cards],{}, [])
+                    ])
+        self._test('Card X WHERE NOT X cw_source S, S eid 1',
+                   [('OneFetchStep', [('Any X WHERE X is Card',
+                                       [{'X': 'Card'}])],
+                     None, None,
+                     [self.cards],{}, [])
+                    ])
+
+    def test_source_specified_2_1(self):
+        self._test('Card X WHERE X cw_source S, NOT S name "system"',
+                   [('OneFetchStep', [('Any X WHERE X is Card',
+                                       [{'X': 'Card'}])],
+                     None, None,
+                     [self.cards],{}, [])
+                    ])
+        self._test('Card X WHERE NOT X cw_source S, S name "system"',
+                   [('OneFetchStep', [('Any X WHERE X is Card',
+                                       [{'X': 'Card'}])],
+                     None, None,
+                     [self.cards],{}, [])
+                    ])
+
+    def test_source_conflict_1(self):
+        self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
+        ex = self.assertRaises(BadRQLQuery,
+                               self._test, 'Any X WHERE X cw_source S, S name "system", X eid %(x)s',
+                               [], {'x': 999999})
+        self.assertEqual(str(ex), 'source conflict for term %(x)s')
+
+    def test_source_conflict_2(self):
+        ex = self.assertRaises(BadRQLQuery,
+                               self._test, 'Card X WHERE X cw_source S, S name "systeme"', [])
+        self.assertEqual(str(ex), 'source conflict for term X')
+
+    def test_source_conflict_3(self):
+        ex = self.assertRaises(BadRQLQuery,
+                               self._test, 'CWSource X WHERE X cw_source S, S name "cards"', [])
+        self.assertEqual(str(ex), 'source conflict for term X')
+
+    def test_ambigous_cross_relation_source_specified(self):
+        self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
+        self.cards.support_relations['see_also'] = True
+        self.cards.cross_relations.add('see_also')
+        try:
+            self._test('Any X,AA ORDERBY AA WHERE E eid %(x)s, E see_also X, X modification_date AA',
+                       [('AggrStep',
+                         'SELECT table0.C0, table0.C1 FROM table0 ORDER BY table0.C1',
+                         None,
+                         [('FetchStep',
+                           [('Any X,AA WHERE 999999 see_also X, X modification_date AA, X is Note',
+                             [{'AA': 'Datetime', 'X': 'Note'}])], [self.cards, self.system], {},
+                           {'AA': 'table0.C1', 'X': 'table0.C0',
+                            'X.modification_date': 'table0.C1'},
+                           []),
+                          ('FetchStep',
+                           [('Any X,AA WHERE 999999 see_also X, X modification_date AA, X is Bookmark',
+                             [{'AA': 'Datetime', 'X': 'Bookmark'}])],
+                           [self.system], {},
+                           {'AA': 'table0.C1', 'X': 'table0.C0',
+                            'X.modification_date': 'table0.C1'},
+                           [])])],
+                         {'x': 999999})
+        finally:
+            del self.cards.support_relations['see_also']
+            self.cards.cross_relations.remove('see_also')
+
     # non regression tests ####################################################
 
     def test_nonregr1(self):
@@ -1864,15 +2004,16 @@
                    )
 
     def test_nonregr4(self):
+        ueid = self.session.user.eid
         self._test('Any U ORDERBY D DESC WHERE WF wf_info_for X, WF creation_date D, WF from_state FS, '
                    'WF owned_by U?, X eid %(x)s',
                    [#('FetchStep', [('Any U WHERE U is CWUser', [{'U': 'CWUser'}])],
                     # [self.ldap, self.system], None, {'U': 'table0.C0'}, []),
-                    ('OneFetchStep', [('Any U ORDERBY D DESC WHERE WF wf_info_for 5, WF creation_date D, WF from_state FS, WF owned_by U?',
+                    ('OneFetchStep', [('Any U ORDERBY D DESC WHERE WF wf_info_for %s, WF creation_date D, WF from_state FS, WF owned_by U?' % ueid,
                                        [{'WF': 'TrInfo', 'FS': 'State', 'U': 'CWUser', 'D': 'Datetime'}])],
                      None, None,
                      [self.system], {}, [])],
-                   {'x': self.session.user.eid})
+                   {'x': ueid})
 
     def test_nonregr5(self):
         # original jpl query:
@@ -1914,7 +2055,7 @@
                    [('FetchStep', [('Any WP WHERE 999999 multisource_rel WP, WP is Note', [{'WP': 'Note'}])],
                      [self.cards], None, {'WP': u'table0.C0'}, []),
                     ('OneFetchStep', [('Any S,SUM(DUR),SUM(I),(SUM(I) - SUM(DUR)),MIN(DI),MAX(DI) GROUPBY S ORDERBY S WHERE A duration DUR, A invoiced I, A modification_date DI, A in_state S, S name SN, (EXISTS(A concerne WP, WP is Note)) OR (EXISTS(A concerne 999999)), A is Affaire, S is State',
-                                       [{'A': 'Affaire', 'DI': 'Datetime', 'DUR': 'Int', 'I': 'Int', 'S': 'State', 'SN': 'String', 'WP': 'Note'}])],
+                                       [{'A': 'Affaire', 'DI': 'Datetime', 'DUR': 'Int', 'I': 'Float', 'S': 'State', 'SN': 'String', 'WP': 'Note'}])],
                      None, None, [self.system], {'WP': u'table0.C0'}, [])],
                    {'n': 999999})
 
@@ -1997,6 +2138,7 @@
                    {'x': 999999})
 
     def test_nonregr13_1(self):
+        ueid = self.session.user.eid
         # identity wrapped into exists:
         # should'nt propagate constraint that U is in the same source as ME
         self._test('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File '
@@ -2008,7 +2150,7 @@
                      [self.ldap, self.system], None,
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
                      []),
-                    ('FetchStep', [('Any U,UL WHERE ((EXISTS(U identity 5)) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is CWGroup))) OR (EXISTS(U in_group H, 5 in_group H, NOT H name "users", H is CWGroup)), U login UL, U is CWUser',
+                    ('FetchStep', [('Any U,UL WHERE ((EXISTS(U identity %s)) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is CWGroup))) OR (EXISTS(U in_group H, %s in_group H, NOT H name "users", H is CWGroup)), U login UL, U is CWUser' % (ueid, ueid),
                                     [{'G': 'CWGroup', 'H': 'CWGroup', 'U': 'CWUser', 'UL': 'String'}])],
                      [self.system],
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
@@ -2019,7 +2161,7 @@
                      None, None, [self.system],
                      {'U': 'table1.C0', 'UL': 'table1.C1'},
                      [])],
-                   {'x': self.session.user.eid})
+                   {'x': ueid})
 
     def test_nonregr13_2(self):
         # identity *not* wrapped into exists.
@@ -2033,6 +2175,7 @@
         # explain constraint propagation rules, and so why this should be
         # wrapped in exists() if used in multi-source
         self.skipTest('take a look at me if you wish')
+        ueid = self.session.user.eid
         self._test('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File '
                    'WITH U,UL BEING (Any U,UL WHERE ME eid %(x)s, (U identity ME '
                    'OR (EXISTS(U in_group G, G name IN("managers", "staff")))) '
@@ -2042,7 +2185,7 @@
                      [self.ldap, self.system], None,
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
                      []),
-                    ('FetchStep', [('Any U,UL WHERE ((U identity 5) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is CWGroup))) OR (EXISTS(U in_group H, 5 in_group H, NOT H name "users", H is CWGroup)), U login UL, U is CWUser',
+                    ('FetchStep', [('Any U,UL WHERE ((U identity %s) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is CWGroup))) OR (EXISTS(U in_group H, %s in_group H, NOT H name "users", H is CWGroup)), U login UL, U is CWUser' % (ueid, ueid),
                                     [{'G': 'CWGroup', 'H': 'CWGroup', 'U': 'CWUser', 'UL': 'String'}])],
                      [self.system],
                      {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
@@ -2094,14 +2237,6 @@
                      None, None, [self.system], {}, [])],
                    {'x': 999999, 'u': 999998})
 
-    def test_state_of_cross(self):
-        self._test('DELETE State X WHERE NOT X state_of Y',
-                   [('DeleteEntitiesStep',
-                     [('OneFetchStep',
-                       [('Any X WHERE NOT X state_of Y, X is State, Y is Workflow',
-                         [{'X': 'State', 'Y': 'Workflow'}])],
-                       None, None, [self.system], {}, [])])]
-                   )
 
 class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
     """test planner related feature on a 3-sources repository:
@@ -2257,7 +2392,7 @@
                      None, {'X': 'table0.C0'}, []),
                     ('UnionStep', None, None,
                      [('OneFetchStep',
-                       [(u'Any X WHERE X owned_by U, U login "anon", U is CWUser, X is IN(Affaire, BaseTransition, Basket, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWUniqueTogetherConstraint, CWUser, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
+                       [(u'Any X WHERE X owned_by U, U login "anon", U is CWUser, X is IN(Affaire, BaseTransition, Basket, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWSource, CWSourceHostConfig, CWUniqueTogetherConstraint, CWUser, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
                          [{'U': 'CWUser', 'X': 'Affaire'},
                           {'U': 'CWUser', 'X': 'BaseTransition'},
                           {'U': 'CWUser', 'X': 'Basket'},
@@ -2272,6 +2407,8 @@
                           {'U': 'CWUser', 'X': 'CWProperty'},
                           {'U': 'CWUser', 'X': 'CWRType'},
                           {'U': 'CWUser', 'X': 'CWRelation'},
+                          {'U': 'CWUser', 'X': 'CWSource'},
+                          {'U': 'CWUser', 'X': 'CWSourceHostConfig'},
                           {'U': 'CWUser', 'X': 'CWUniqueTogetherConstraint'},
                           {'U': 'CWUser', 'X': 'CWUser'},
                           {'U': 'CWUser', 'X': 'Division'},
--- a/server/test/unittest_multisources.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/unittest_multisources.py	Wed Oct 13 08:37:21 2010 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+ # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -15,29 +15,29 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-from os.path import dirname, join, abspath
+
 from datetime import datetime, timedelta
 
-from logilab.common.decorators import cached
-
 from cubicweb.devtools import TestServerConfiguration, init_test_database
 from cubicweb.devtools.testlib import CubicWebTC, refresh_repo
 from cubicweb.devtools.repotest import do_monkey_patch, undo_monkey_patch
 
 
-class TwoSourcesConfiguration(TestServerConfiguration):
-    sourcefile = 'sources_multi'
-
-
 class ExternalSource1Configuration(TestServerConfiguration):
     sourcefile = 'sources_extern'
 
 class ExternalSource2Configuration(TestServerConfiguration):
-    sourcefile = 'sources_multi2'
+    sourcefile = 'sources_multi'
 
 MTIME = datetime.now() - timedelta(0, 10)
-repo2, cnx2 = init_test_database(config=ExternalSource1Configuration('data'))
-repo3, cnx3 = init_test_database(config=ExternalSource2Configuration('data'))
+
+EXTERN_SOURCE_CFG = u'''
+pyro-ns-id = extern
+cubicweb-user = admin
+cubicweb-password = gingkow
+mapping-file = extern_mapping.py
+base-url=http://extern.org/
+'''
 
 # hi-jacking
 from cubicweb.server.sources.pyrorql import PyroRQLSource
@@ -47,6 +47,13 @@
 Connection_close = Connection.close
 
 def setup_module(*args):
+    global repo2, cnx2, repo3, cnx3
+    repo2, cnx2 = init_test_database(config=ExternalSource1Configuration('data'))
+    repo3, cnx3 = init_test_database(config=ExternalSource2Configuration('data'))
+    cnx3.request().create_entity('CWSource', name=u'extern', type=u'pyrorql',
+                                 config=EXTERN_SOURCE_CFG)
+    cnx3.commit()
+
     TestServerConfiguration.no_sqlite_wrap = True
     # hi-jack PyroRQLSource.get_connection to access existing connection (no
     # pyro connection)
@@ -67,7 +74,6 @@
     TestServerConfiguration.no_sqlite_wrap = False
 
 class TwoSourcesTC(CubicWebTC):
-    config = TwoSourcesConfiguration('data')
 
     @classmethod
     def _refresh_repo(cls):
@@ -82,6 +88,8 @@
         do_monkey_patch()
 
     def tearDown(self):
+        for source in self.repo.sources[1:]:
+            self.repo.remove_source(source.uri)
         CubicWebTC.tearDown(self)
         undo_monkey_patch()
 
@@ -91,6 +99,17 @@
         cu.execute('INSERT Card X: X title "C4: Ze external card", X wikiid "zzz"')
         self.aff1 = cu.execute('INSERT Affaire X: X ref "AFFREF"')[0][0]
         cnx2.commit()
+        for uri, config in [('extern', EXTERN_SOURCE_CFG),
+                            ('extern-multi', '''
+pyro-ns-id = extern-multi
+cubicweb-user = admin
+cubicweb-password = gingkow
+mapping-file = extern_mapping.py
+''')]:
+            self.request().create_entity('CWSource', name=unicode(uri),
+                                         type=u'pyrorql',
+                                         config=unicode(config))
+        self.commit()
         # trigger discovery
         self.sexecute('Card X')
         self.sexecute('Affaire X')
@@ -112,11 +131,11 @@
         # since they are orderd by eid, we know the 3 first one is coming from the system source
         # and the others from external source
         self.assertEqual(rset.get_entity(0, 0).cw_metainformation(),
-                          {'source': {'adapter': 'native', 'uri': 'system'},
+                          {'source': {'type': 'native', 'uri': 'system'},
                            'type': u'Card', 'extid': None})
         externent = rset.get_entity(3, 0)
         metainf = externent.cw_metainformation()
-        self.assertEqual(metainf['source'], {'adapter': 'pyrorql', 'base-url': 'http://extern.org/', 'uri': 'extern'})
+        self.assertEqual(metainf['source'], {'type': 'pyrorql', 'base-url': 'http://extern.org/', 'uri': 'extern'})
         self.assertEqual(metainf['type'], 'Card')
         self.assert_(metainf['extid'])
         etype = self.sexecute('Any ETN WHERE X is ET, ET name ETN, X eid %(x)s',
@@ -184,7 +203,7 @@
     def test_simplifiable_var_2(self):
         affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0]
         rset = self.sexecute('Any E WHERE E eid %(x)s, E in_state S, NOT S name "moved"',
-                            {'x': affeid, 'u': self.session.user.eid})
+                             {'x': affeid, 'u': self.session.user.eid})
         self.assertEqual(len(rset), 1)
 
     def test_sort_func(self):
@@ -270,7 +289,6 @@
 
     def test_not_relation(self):
         states = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN'))
-        self.session.user.clear_all_caches()
         userstate = self.session.user.in_state[0]
         states.remove((userstate.eid, userstate.name))
         notstates = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s',
--- a/server/test/unittest_querier.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/unittest_querier.py	Wed Oct 13 08:37:21 2010 +0200
@@ -130,7 +130,7 @@
                                        'X': 'Affaire',
                                        'ET': 'CWEType', 'ETN': 'String'}])
         rql, solutions = partrqls[1]
-        self.assertEqual(rql,  'Any ETN,X WHERE X is ET, ET name ETN, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWUniqueTogetherConstraint, CWUser, Card, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Note, Personne, RQLExpression, Societe, State, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)')
+        self.assertEqual(rql,  'Any ETN,X WHERE X is ET, ET name ETN, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWSource, CWUniqueTogetherConstraint, CWUser, Card, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Note, Personne, RQLExpression, Societe, State, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)')
         self.assertListEqual(sorted(solutions),
                               sorted([{'X': 'BaseTransition', 'ETN': 'String', 'ET': 'CWEType'},
                                       {'X': 'Bookmark', 'ETN': 'String', 'ET': 'CWEType'},
@@ -147,6 +147,7 @@
                                       {'X': 'CWPermission', 'ETN': 'String', 'ET': 'CWEType'},
                                       {'X': 'CWProperty', 'ETN': 'String', 'ET': 'CWEType'},
                                       {'X': 'CWRType', 'ETN': 'String', 'ET': 'CWEType'},
+                                      {'X': 'CWSource', 'ETN': 'String', 'ET': 'CWEType'},
                                       {'X': 'CWUniqueTogetherConstraint', 'ETN': 'String', 'ET': 'CWEType'},
                                       {'X': 'CWUser', 'ETN': 'String', 'ET': 'CWEType'},
                                       {'X': 'Email', 'ETN': 'String', 'ET': 'CWEType'},
@@ -251,15 +252,15 @@
     def test_select_1(self):
         rset = self.execute('Any X ORDERBY X WHERE X is CWGroup')
         result, descr = rset.rows, rset.description
-        self.assertEqual(tuplify(result), [(1,), (2,), (3,), (4,)])
+        self.assertEqual(tuplify(result), [(2,), (3,), (4,), (5,)])
         self.assertEqual(descr, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
 
     def test_select_2(self):
         rset = self.execute('Any X ORDERBY N WHERE X is CWGroup, X name N')
-        self.assertEqual(tuplify(rset.rows), [(1,), (2,), (3,), (4,)])
+        self.assertEqual(tuplify(rset.rows), [(2,), (3,), (4,), (5,)])
         self.assertEqual(rset.description, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
         rset = self.execute('Any X ORDERBY N DESC WHERE X is CWGroup, X name N')
-        self.assertEqual(tuplify(rset.rows), [(4,), (3,), (2,), (1,)])
+        self.assertEqual(tuplify(rset.rows), [(5,), (4,), (3,), (2,)])
 
     def test_select_3(self):
         rset = self.execute('Any N GROUPBY N WHERE X is CWGroup, X name N')
@@ -302,7 +303,7 @@
 
     def test_select_5(self):
         rset = self.execute('Any X, TMP ORDERBY TMP WHERE X name TMP, X is CWGroup')
-        self.assertEqual(tuplify(rset.rows), [(1, 'guests',), (2, 'managers',), (3, 'owners',), (4, 'users',)])
+        self.assertEqual(tuplify(rset.rows), [(2, 'guests',), (3, 'managers',), (4, 'owners',), (5, 'users',)])
         self.assertEqual(rset.description, [('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',)])
 
     def test_select_6(self):
@@ -350,11 +351,11 @@
         self.assertEqual(len(rset.rows), 0)
 
     def test_select_nonregr_edition_not(self):
-        groupeids = set((1, 2, 3))
-        groupreadperms = set(r[0] for r in self.execute('Any Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), X read_permission Y'))
-        rset = self.execute('DISTINCT Any Y WHERE X is CWEType, X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
+        groupeids = set((2, 3, 4))
+        groupreadperms = set(r[0] for r in self.execute('Any Y WHERE X name "CWGroup", Y eid IN(2, 3, 4), X read_permission Y'))
+        rset = self.execute('DISTINCT Any Y WHERE X is CWEType, X name "CWGroup", Y eid IN(2, 3, 4), NOT X read_permission Y')
         self.assertEqual(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
-        rset = self.execute('DISTINCT Any Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
+        rset = self.execute('DISTINCT Any Y WHERE X name "CWGroup", Y eid IN(2, 3, 4), NOT X read_permission Y')
         self.assertEqual(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
 
     def test_select_outer_join(self):
@@ -493,15 +494,16 @@
         self.assertListEqual(rset.rows,
                               [[u'description_format', 12],
                                [u'description', 13],
-                               [u'name', 14],
-                               [u'created_by', 38],
-                               [u'creation_date', 38],
-                               [u'cwuri', 38],
-                               [u'in_basket', 38],
-                               [u'is', 38],
-                               [u'is_instance_of', 38],
-                               [u'modification_date', 38],
-                               [u'owned_by', 38]])
+                               [u'name', 15],
+                               [u'created_by', 40],
+                               [u'creation_date', 40],
+                               [u'cw_source', 40],
+                               [u'cwuri', 40],
+                               [u'in_basket', 40],
+                               [u'is', 40],
+                               [u'is_instance_of', 40],
+                               [u'modification_date', 40],
+                               [u'owned_by', 40]])
 
     def test_select_aggregat_having_dumb(self):
         # dumb but should not raise an error
@@ -545,6 +547,26 @@
         self.assertEqual(rset.rows[0][0], 'ADMIN')
         self.assertEqual(rset.description, [('String',)])
 
+    def test_select_float_abs(self):
+        # test positive number
+        eid = self.execute('INSERT Affaire A: A invoiced %(i)s', {'i': 1.2})[0][0]
+        rset = self.execute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
+        self.assertEqual(rset.rows[0][0], 1.2)
+        # test negative number
+        eid = self.execute('INSERT Affaire A: A invoiced %(i)s', {'i': -1.2})[0][0]
+        rset = self.execute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
+        self.assertEqual(rset.rows[0][0], 1.2)
+
+    def test_select_int_abs(self):
+        # test positive number
+        eid = self.execute('INSERT Affaire A: A duration %(d)s', {'d': 12})[0][0]
+        rset = self.execute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
+        self.assertEqual(rset.rows[0][0], 12)
+        # test negative number
+        eid = self.execute('INSERT Affaire A: A duration %(d)s', {'d': -12})[0][0]
+        rset = self.execute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
+        self.assertEqual(rset.rows[0][0], 12)
+
 ##     def test_select_simplified(self):
 ##         ueid = self.session.user.eid
 ##         rset = self.execute('Any L WHERE %s login L'%ueid)
@@ -597,15 +619,15 @@
     def test_select_no_descr(self):
         rset = self.execute('Any X WHERE X is CWGroup', build_descr=0)
         rset.rows.sort()
-        self.assertEqual(tuplify(rset.rows), [(1,), (2,), (3,), (4,)])
+        self.assertEqual(tuplify(rset.rows), [(2,), (3,), (4,), (5,)])
         self.assertEqual(rset.description, ())
 
     def test_select_limit_offset(self):
         rset = self.execute('CWGroup X ORDERBY N LIMIT 2 WHERE X name N')
-        self.assertEqual(tuplify(rset.rows), [(1,), (2,)])
+        self.assertEqual(tuplify(rset.rows), [(2,), (3,)])
         self.assertEqual(rset.description, [('CWGroup',), ('CWGroup',)])
         rset = self.execute('CWGroup X ORDERBY N LIMIT 2 OFFSET 2 WHERE X name N')
-        self.assertEqual(tuplify(rset.rows), [(3,), (4,)])
+        self.assertEqual(tuplify(rset.rows), [(4,), (5,)])
 
     def test_select_symmetric(self):
         self.execute("INSERT Personne X: X nom 'machin'")
@@ -746,14 +768,14 @@
     def test_select_constant(self):
         rset = self.execute('Any X, "toto" ORDERBY X WHERE X is CWGroup')
         self.assertEqual(rset.rows,
-                          map(list, zip((1,2,3,4), ('toto','toto','toto','toto',))))
+                          map(list, zip((2,3,4,5), ('toto','toto','toto','toto',))))
         self.assertIsInstance(rset[0][1], unicode)
         self.assertEqual(rset.description,
                           zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
                               ('String', 'String', 'String', 'String',)))
         rset = self.execute('Any X, %(value)s ORDERBY X WHERE X is CWGroup', {'value': 'toto'})
         self.assertEqual(rset.rows,
-                          map(list, zip((1,2,3,4), ('toto','toto','toto','toto',))))
+                          map(list, zip((2,3,4,5), ('toto','toto','toto','toto',))))
         self.assertIsInstance(rset[0][1], unicode)
         self.assertEqual(rset.description,
                           zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
--- a/server/test/unittest_repository.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/test/unittest_repository.py	Wed Oct 13 08:37:21 2010 +0200
@@ -95,15 +95,14 @@
         self.assertItemsEqual(person._unique_together[0],
                                            ('nom', 'prenom', 'inline2'))
 
-    def test_schema_has_owner(self):
-        repo = self.repo
-        cnxid = repo.connect(self.admlogin, password=self.admpassword)
-        self.failIf(repo.execute(cnxid, 'CWEType X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'CWRType X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'CWAttribute X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'CWRelation X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'CWConstraint X WHERE NOT X owned_by U'))
-        self.failIf(repo.execute(cnxid, 'CWConstraintType X WHERE NOT X owned_by U'))
+    def test_all_entities_have_owner(self):
+        self.failIf(self.execute('Any X WHERE NOT X owned_by U'))
+
+    def test_all_entities_have_is(self):
+        self.failIf(self.execute('Any X WHERE NOT X is ET'))
+
+    def test_all_entities_have_cw_source(self):
+        self.failIf(self.execute('Any X WHERE NOT X cw_source S'))
 
     def test_connect(self):
         self.assert_(self.repo.connect(self.admlogin, password=self.admpassword))
@@ -211,7 +210,7 @@
     def test_check_session(self):
         repo = self.repo
         cnxid = repo.connect(self.admlogin, password=self.admpassword)
-        self.assertEqual(repo.check_session(cnxid), None)
+        self.assertIsInstance(repo.check_session(cnxid), float)
         repo.close(cnxid)
         self.assertRaises(BadConnectionId, repo.check_session, cnxid)
 
@@ -288,7 +287,7 @@
         self.assertListEqual([r.type for r in schema.eschema('CWAttribute').ordered_relations()
                                if not r.type in ('eid', 'is', 'is_instance_of', 'identity',
                                                  'creation_date', 'modification_date', 'cwuri',
-                                                 'owned_by', 'created_by',
+                                                 'owned_by', 'created_by', 'cw_source',
                                                  'update_permission', 'read_permission',
                                                  'in_basket')],
                               ['relation_type',
@@ -369,25 +368,25 @@
         repo = self.repo
         cnxid = repo.connect(self.admlogin, password=self.admpassword)
         session = repo._get_session(cnxid, setpool=True)
-        self.assertEqual(repo.type_and_source_from_eid(1, session),
-                          ('CWGroup', 'system', None))
-        self.assertEqual(repo.type_from_eid(1, session), 'CWGroup')
-        self.assertEqual(repo.source_from_eid(1, session).uri, 'system')
-        self.assertEqual(repo.eid2extid(repo.system_source, 1, session), None)
+        self.assertEqual(repo.type_and_source_from_eid(2, session),
+                         ('CWGroup', 'system', None))
+        self.assertEqual(repo.type_from_eid(2, session), 'CWGroup')
+        self.assertEqual(repo.source_from_eid(2, session).uri, 'system')
+        self.assertEqual(repo.eid2extid(repo.system_source, 2, session), None)
         class dummysource: uri = 'toto'
-        self.assertRaises(UnknownEid, repo.eid2extid, dummysource, 1, session)
+        self.assertRaises(UnknownEid, repo.eid2extid, dummysource, 2, session)
 
     def test_public_api(self):
         self.assertEqual(self.repo.get_schema(), self.repo.schema)
-        self.assertEqual(self.repo.source_defs(), {'system': {'adapter': 'native', 'uri': 'system'}})
+        self.assertEqual(self.repo.source_defs(), {'system': {'type': 'native', 'uri': 'system'}})
         # .properties() return a result set
         self.assertEqual(self.repo.properties().rql, 'Any K,V WHERE P is CWProperty,P pkey K, P value V, NOT P for_user U')
 
     def test_session_api(self):
         repo = self.repo
         cnxid = repo.connect(self.admlogin, password=self.admpassword)
-        self.assertEqual(repo.user_info(cnxid), (5, 'admin', set([u'managers']), {}))
-        self.assertEqual(repo.describe(cnxid, 1), (u'CWGroup', u'system', None))
+        self.assertEqual(repo.user_info(cnxid), (6, 'admin', set([u'managers']), {}))
+        self.assertEqual(repo.describe(cnxid, 2), (u'CWGroup', u'system', None))
         repo.close(cnxid)
         self.assertRaises(BadConnectionId, repo.user_info, cnxid)
         self.assertRaises(BadConnectionId, repo.describe, cnxid, 1)
@@ -480,7 +479,7 @@
                               'EmailAddress', address=u'a@b.fr')
 
     def test_multiple_edit_set_attributes(self):
-        """make sure edited_attributes doesn't get cluttered
+        """make sure cw_edited doesn't get cluttered
         by previous entities on multiple set
         """
         # local hook
@@ -491,9 +490,9 @@
             events = ('before_update_entity',)
             def __call__(self):
                 # invoiced attribute shouldn't be considered "edited" before the hook
-                self._test.failIf('invoiced' in self.entity.edited_attributes,
-                                  'edited_attributes cluttered by previous update')
-                self.entity['invoiced'] = 10
+                self._test.failIf('invoiced' in self.entity.cw_edited,
+                                  'cw_edited cluttered by previous update')
+                self.entity.cw_edited['invoiced'] = 10
         with self.temporary_appobjects(DummyBeforeHook):
             req = self.request()
             req.create_entity('Affaire', ref=u'AFF01')
@@ -518,7 +517,7 @@
 
     def test_type_from_eid(self):
         self.session.set_pool()
-        self.assertEqual(self.repo.type_from_eid(1, self.session), 'CWGroup')
+        self.assertEqual(self.repo.type_from_eid(2, self.session), 'CWGroup')
 
     def test_type_from_eid_raise(self):
         self.session.set_pool()
--- a/server/utils.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/server/utils.py	Wed Oct 13 08:37:21 2010 +0200
@@ -24,8 +24,6 @@
 from getpass import getpass
 from random import choice
 
-from logilab.common.configuration import Configuration
-
 from cubicweb.server import SOURCE_TYPES
 
 try:
@@ -111,12 +109,6 @@
     return user, passwd
 
 
-def ask_source_config(sourcetype, inputlevel=0):
-    sconfig = Configuration(options=SOURCE_TYPES[sourcetype].options)
-    sconfig.adapter = sourcetype
-    sconfig.input_config(inputlevel=inputlevel)
-    return sconfig
-
 _MARKER=object()
 def func_name(func):
     name = getattr(func, '__name__', _MARKER)
--- a/sobjects/supervising.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/sobjects/supervising.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,10 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""some hooks and views to handle supervising of any data changes
+"""some hooks and views to handle supervising of any data changes"""
 
-
-"""
 __docformat__ = "restructuredtext en"
 
 from cubicweb import UnknownEid
@@ -185,6 +183,6 @@
         msg = format_mail(uinfo, recipients, content, view.subject(), config=config)
         self.to_send = [(msg, recipients)]
 
-    def commit_event(self):
+    def postcommit_event(self):
         self._prepare_email()
-        SendMailOp.commit_event(self)
+        SendMailOp.postcommit_event(self)
--- a/sobjects/test/unittest_notification.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/sobjects/test/unittest_notification.py	Wed Oct 13 08:37:21 2010 +0200
@@ -58,7 +58,7 @@
     def test_nonregr_empty_message_id(self):
         for eid in (1, 12, 123, 1234):
             msgid1 = construct_message_id('testapp', eid, 12)
-            self.assertNotEquals(msgid1, '<@testapp.%s>' % gethostname())
+            self.assertNotEqual(msgid1, '<@testapp.%s>' % gethostname())
 
 
 class RecipientsFinderTC(CubicWebTC):
--- a/tags.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/tags.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,9 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""helper classes to generate simple (X)HTML tags
+"""helper classes to generate simple (X)HTML tags"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from cubicweb.uilib import simple_sgml_tag, sgml_attributes
--- a/test/unittest_dbapi.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/test/unittest_dbapi.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,9 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""
+"""unittest for cubicweb.dbapi"""
 
-"""
 from __future__ import with_statement
 from copy import copy
 
@@ -30,7 +29,7 @@
     def test_public_repo_api(self):
         cnx = self.login('anon')
         self.assertEqual(cnx.get_schema(), self.repo.schema)
-        self.assertEqual(cnx.source_defs(), {'system': {'adapter': 'native', 'uri': 'system'}})
+        self.assertEqual(cnx.source_defs(), {'system': {'type': 'native', 'uri': 'system'}})
         self.restore_connection() # proper way to close cnx
         self.assertRaises(ProgrammingError, cnx.get_schema)
         self.assertRaises(ProgrammingError, cnx.source_defs)
@@ -48,7 +47,7 @@
     def test_api(self):
         cnx = self.login('anon')
         self.assertEqual(cnx.user(None).login, 'anon')
-        self.assertEqual(cnx.describe(1), (u'CWGroup', u'system', None))
+        self.assertEqual(cnx.describe(1), (u'CWSource', u'system', None))
         self.restore_connection() # proper way to close cnx
         self.assertRaises(ProgrammingError, cnx.user, None)
         self.assertRaises(ProgrammingError, cnx.describe, 1)
--- a/test/unittest_entity.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/test/unittest_entity.py	Wed Oct 13 08:37:21 2010 +0200
@@ -16,9 +16,7 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""unit tests for cubicweb.web.views.entities module
-
-"""
+"""unit tests for cubicweb.web.views.entities module"""
 
 from datetime import datetime
 
@@ -319,33 +317,33 @@
 
     def test_printable_value_string(self):
         e = self.request().create_entity('Card', title=u'rest test', content=u'du :eid:`1:*ReST*`',
-                            content_format=u'text/rest')
+                                         content_format=u'text/rest')
         self.assertEqual(e.printable_value('content'),
-                          '<p>du <a class="reference" href="http://testing.fr/cubicweb/cwgroup/guests">*ReST*</a></p>\n')
-        e['content'] = 'du <em>html</em> <ref rql="CWUser X">users</ref>'
-        e['content_format'] = 'text/html'
+                         '<p>du <a class="reference" href="http://testing.fr/cubicweb/cwsource/system">*ReST*</a></p>\n')
+        e.cw_attr_cache['content'] = 'du <em>html</em> <ref rql="CWUser X">users</ref>'
+        e.cw_attr_cache['content_format'] = 'text/html'
         self.assertEqual(e.printable_value('content'),
                           'du <em>html</em> <a href="http://testing.fr/cubicweb/view?rql=CWUser%20X">users</a>')
-        e['content'] = 'du *texte*'
-        e['content_format'] = 'text/plain'
+        e.cw_attr_cache['content'] = 'du *texte*'
+        e.cw_attr_cache['content_format'] = 'text/plain'
         self.assertEqual(e.printable_value('content'),
                           '<p>\ndu *texte*<br/>\n</p>')
-        e['title'] = 'zou'
-        e['content'] = '''\
+        e.cw_attr_cache['title'] = 'zou'
+        e.cw_attr_cache['content'] = '''\
 a title
 =======
 du :eid:`1:*ReST*`'''
-        e['content_format'] = 'text/rest'
+        e.cw_attr_cache['content_format'] = 'text/rest'
         self.assertEqual(e.printable_value('content', format='text/plain'),
-                          e['content'])
+                          e.cw_attr_cache['content'])
 
-        e['content'] = u'<b>yo (zou éà ;)</b>'
-        e['content_format'] = 'text/html'
+        e.cw_attr_cache['content'] = u'<b>yo (zou éà ;)</b>'
+        e.cw_attr_cache['content_format'] = 'text/html'
         self.assertEqual(e.printable_value('content', format='text/plain').strip(),
-                          u'**yo (zou éà ;)**')
+                         u'**yo (zou éà ;)**')
         if HAS_TAL:
-            e['content'] = '<h1 tal:content="self/title">titre</h1>'
-            e['content_format'] = 'text/cubicweb-page-template'
+            e.cw_attr_cache['content'] = '<h1 tal:content="self/title">titre</h1>'
+            e.cw_attr_cache['content_format'] = 'text/cubicweb-page-template'
             self.assertEqual(e.printable_value('content'),
                               '<h1>zou</h1>')
 
@@ -387,30 +385,30 @@
         tidy = lambda x: x.replace('\n', '')
         self.assertEqual(tidy(e.printable_value('content')),
                           '<div>R&amp;D<br/></div>')
-        e['content'] = u'yo !! R&D <div> pas fermé'
-        self.assertEqual(tidy(e.printable_value('content')),
-                          u'yo !! R&amp;D <div> pas fermé</div>')
-        e['content'] = u'R&D'
-        self.assertEqual(tidy(e.printable_value('content')), u'R&amp;D')
-        e['content'] = u'R&D;'
-        self.assertEqual(tidy(e.printable_value('content')), u'R&amp;D;')
-        e['content'] = u'yo !! R&amp;D <div> pas fermé'
+        e.cw_attr_cache['content'] = u'yo !! R&D <div> pas fermé'
         self.assertEqual(tidy(e.printable_value('content')),
                           u'yo !! R&amp;D <div> pas fermé</div>')
-        e['content'] = u'été <div> été'
+        e.cw_attr_cache['content'] = u'R&D'
+        self.assertEqual(tidy(e.printable_value('content')), u'R&amp;D')
+        e.cw_attr_cache['content'] = u'R&D;'
+        self.assertEqual(tidy(e.printable_value('content')), u'R&amp;D;')
+        e.cw_attr_cache['content'] = u'yo !! R&amp;D <div> pas fermé'
         self.assertEqual(tidy(e.printable_value('content')),
-                          u'été <div> été</div>')
-        e['content'] = u'C&apos;est un exemple s&eacute;rieux'
+                         u'yo !! R&amp;D <div> pas fermé</div>')
+        e.cw_attr_cache['content'] = u'été <div> été'
         self.assertEqual(tidy(e.printable_value('content')),
-                          u"C'est un exemple sérieux")
+                         u'été <div> été</div>')
+        e.cw_attr_cache['content'] = u'C&apos;est un exemple s&eacute;rieux'
+        self.assertEqual(tidy(e.printable_value('content')),
+                         u"C'est un exemple sérieux")
         # make sure valid xhtml is left untouched
-        e['content'] = u'<div>R&amp;D<br/></div>'
-        self.assertEqual(e.printable_value('content'), e['content'])
-        e['content'] = u'<div>été</div>'
-        self.assertEqual(e.printable_value('content'), e['content'])
-        e['content'] = u'été'
-        self.assertEqual(e.printable_value('content'), e['content'])
-        e['content'] = u'hop\r\nhop\nhip\rmomo'
+        e.cw_attr_cache['content'] = u'<div>R&amp;D<br/></div>'
+        self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
+        e.cw_attr_cache['content'] = u'<div>été</div>'
+        self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
+        e.cw_attr_cache['content'] = u'été'
+        self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
+        e.cw_attr_cache['content'] = u'hop\r\nhop\nhip\rmomo'
         self.assertEqual(e.printable_value('content'), u'hop\nhop\nhip\nmomo')
 
     def test_printable_value_bad_html_ms(self):
@@ -419,7 +417,7 @@
         e = req.create_entity('Card', title=u'bad html', content=u'<div>R&D<br>',
                             content_format=u'text/html')
         tidy = lambda x: x.replace('\n', '')
-        e['content'] = u'<div x:foo="bar">ms orifice produces weird html</div>'
+        e.cw_attr_cache['content'] = u'<div x:foo="bar">ms orifice produces weird html</div>'
         self.assertEqual(tidy(e.printable_value('content')),
                           u'<div>ms orifice produces weird html</div>')
         import tidy as tidymod # apt-get install python-tidy
@@ -435,15 +433,15 @@
 
     def test_fulltextindex(self):
         e = self.vreg['etypes'].etype_class('File')(self.request())
-        e['description'] = 'du <em>html</em>'
-        e['description_format'] = 'text/html'
-        e['data'] = Binary('some <em>data</em>')
-        e['data_name'] = 'an html file'
-        e['data_format'] = 'text/html'
-        e['data_encoding'] = 'ascii'
+        e.cw_attr_cache['description'] = 'du <em>html</em>'
+        e.cw_attr_cache['description_format'] = 'text/html'
+        e.cw_attr_cache['data'] = Binary('some <em>data</em>')
+        e.cw_attr_cache['data_name'] = 'an html file'
+        e.cw_attr_cache['data_format'] = 'text/html'
+        e.cw_attr_cache['data_encoding'] = 'ascii'
         e._cw.transaction_data = {} # XXX req should be a session
         self.assertEqual(e.cw_adapt_to('IFTIndexable').get_words(),
-                          {'C': [u'du', u'html', 'an', 'html', 'file', u'some', u'data']})
+                          {'C': ['an', 'html', 'file', 'du', 'html', 'some', 'data']})
 
 
     def test_nonregr_relation_cache(self):
@@ -461,7 +459,7 @@
             'WHERE U login "admin", S1 name "activated", S2 name "deactivated"')[0][0]
         trinfo = self.execute('Any X WHERE X eid %(x)s', {'x': eid}).get_entity(0, 0)
         trinfo.complete()
-        self.failUnless(isinstance(trinfo['creation_date'], datetime))
+        self.failUnless(isinstance(trinfo.cw_attr_cache['creation_date'], datetime))
         self.failUnless(trinfo.cw_relation_cached('from_state', 'subject'))
         self.failUnless(trinfo.cw_relation_cached('to_state', 'subject'))
         self.failUnless(trinfo.cw_relation_cached('wf_info_for', 'subject'))
@@ -499,7 +497,7 @@
         self.assertEqual(card3.rest_path(), 'card/eid/%d' % card3.eid)
         card4 = req.create_entity('Card', title=u'pod', wikiid=u'zo?bi')
         self.assertEqual(card4.rest_path(), 'card/eid/%d' % card4.eid)
-        
+
 
     def test_set_attributes(self):
         req = self.request()
@@ -515,7 +513,7 @@
         req = self.request()
         note = req.create_entity('Note', type=u'z')
         metainf = note.cw_metainformation()
-        self.assertEqual(metainf, {'source': {'adapter': 'native', 'uri': 'system'}, 'type': u'Note', 'extid': None})
+        self.assertEqual(metainf, {'source': {'type': 'native', 'uri': 'system'}, 'type': u'Note', 'extid': None})
         self.assertEqual(note.absolute_url(), 'http://testing.fr/cubicweb/note/%s' % note.eid)
         metainf['source'] = metainf['source'].copy()
         metainf['source']['base-url']  = 'http://cubicweb2.com/'
--- a/test/unittest_rset.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/test/unittest_rset.py	Wed Oct 13 08:37:21 2010 +0200
@@ -16,9 +16,7 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""unit tests for module cubicweb.utils
-
-"""
+"""unit tests for module cubicweb.utils"""
 
 from urlparse import urlsplit
 import pickle
@@ -157,13 +155,13 @@
         rs.req = self.request()
         rs.vreg = self.vreg
 
-        rs2 = rs.sorted_rset(lambda e:e['login'])
+        rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'])
         self.assertEqual(len(rs2), 3)
         self.assertEqual([login for _, login in rs2], ['adim', 'nico', 'syt'])
         # make sure rs is unchanged
         self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
 
-        rs2 = rs.sorted_rset(lambda e:e['login'], reverse=True)
+        rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'], reverse=True)
         self.assertEqual(len(rs2), 3)
         self.assertEqual([login for _, login in rs2], ['syt', 'nico', 'adim'])
         # make sure rs is unchanged
@@ -186,8 +184,7 @@
                        description=[['CWUser', 'String', 'String']] * 5)
         rs.req = self.request()
         rs.vreg = self.vreg
-
-        rsets = rs.split_rset(lambda e:e['login'])
+        rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'])
         self.assertEqual(len(rsets), 3)
         self.assertEqual([login for _, login,_ in rsets[0]], ['adim', 'adim'])
         self.assertEqual([login for _, login,_ in rsets[1]], ['syt'])
@@ -195,7 +192,7 @@
         # make sure rs is unchanged
         self.assertEqual([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
 
-        rsets = rs.split_rset(lambda e:e['login'], return_dict=True)
+        rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'], return_dict=True)
         self.assertEqual(len(rsets), 3)
         self.assertEqual([login for _, login,_ in rsets['nico']], ['nico', 'nico'])
         self.assertEqual([login for _, login,_ in rsets['adim']], ['adim', 'adim'])
@@ -230,12 +227,12 @@
         self.request().create_entity('CWUser', login=u'adim', upassword='adim',
                                      surname=u'di mascio', firstname=u'adrien')
         e = self.execute('Any X,T WHERE X login "adim", X surname T').get_entity(0, 0)
-        self.assertEqual(e['surname'], 'di mascio')
-        self.assertRaises(KeyError, e.__getitem__, 'firstname')
-        self.assertRaises(KeyError, e.__getitem__, 'creation_date')
+        self.assertEqual(e.cw_attr_cache['surname'], 'di mascio')
+        self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
+        self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'creation_date')
         self.assertEqual(pprelcachedict(e._cw_related_cache), [])
         e.complete()
-        self.assertEqual(e['firstname'], 'adrien')
+        self.assertEqual(e.cw_attr_cache['firstname'], 'adrien')
         self.assertEqual(pprelcachedict(e._cw_related_cache), [])
 
     def test_get_entity_advanced(self):
@@ -246,20 +243,20 @@
         e = rset.get_entity(0, 0)
         self.assertEqual(e.cw_row, 0)
         self.assertEqual(e.cw_col, 0)
-        self.assertEqual(e['title'], 'zou')
-        self.assertRaises(KeyError, e.__getitem__, 'path')
+        self.assertEqual(e.cw_attr_cache['title'], 'zou')
+        self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'path')
         self.assertEqual(e.view('text'), 'zou')
         self.assertEqual(pprelcachedict(e._cw_related_cache), [])
 
         e = rset.get_entity(0, 1)
         self.assertEqual(e.cw_row, 0)
         self.assertEqual(e.cw_col, 1)
-        self.assertEqual(e['login'], 'anon')
-        self.assertRaises(KeyError, e.__getitem__, 'firstname')
+        self.assertEqual(e.cw_attr_cache['login'], 'anon')
+        self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
         self.assertEqual(pprelcachedict(e._cw_related_cache),
                           [])
         e.complete()
-        self.assertEqual(e['firstname'], None)
+        self.assertEqual(e.cw_attr_cache['firstname'], None)
         self.assertEqual(e.view('text'), 'anon')
         self.assertEqual(pprelcachedict(e._cw_related_cache),
                           [])
@@ -282,17 +279,17 @@
         rset = self.execute('Any X,U,S,XT,UL,SN WHERE X created_by U, U in_state S, '
                             'X title XT, S name SN, U login UL, X eid %s' % e.eid)
         e = rset.get_entity(0, 0)
-        self.assertEqual(e['title'], 'zou')
+        self.assertEqual(e.cw_attr_cache['title'], 'zou')
         self.assertEqual(pprelcachedict(e._cw_related_cache),
-                          [('created_by_subject', [5])])
+                          [('created_by_subject', [self.user().eid])])
         # first level of recursion
         u = e.created_by[0]
-        self.assertEqual(u['login'], 'admin')
-        self.assertRaises(KeyError, u.__getitem__, 'firstname')
+        self.assertEqual(u.cw_attr_cache['login'], 'admin')
+        self.assertRaises(KeyError, u.cw_attr_cache.__getitem__, 'firstname')
         # second level of recursion
         s = u.in_state[0]
-        self.assertEqual(s['name'], 'activated')
-        self.assertRaises(KeyError, s.__getitem__, 'description')
+        self.assertEqual(s.cw_attr_cache['name'], 'activated')
+        self.assertRaises(KeyError, s.cw_attr_cache.__getitem__, 'description')
 
 
     def test_get_entity_cache_with_left_outer_join(self):
@@ -322,7 +319,7 @@
             etype, n = expected[entity.cw_row]
             self.assertEqual(entity.__regid__, etype)
             attr = etype == 'Bookmark' and 'title' or 'name'
-            self.assertEqual(entity[attr], n)
+            self.assertEqual(entity.cw_attr_cache[attr], n)
 
     def test_related_entity_optional(self):
         e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
--- a/test/unittest_schema.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/test/unittest_schema.py	Wed Oct 13 08:37:21 2010 +0200
@@ -167,13 +167,13 @@
         schema = loader.load(config)
         self.assert_(isinstance(schema, CubicWebSchema))
         self.assertEqual(schema.name, 'data')
-        entities = [str(e) for e in schema.entities()]
-        entities.sort()
+        entities = sorted([str(e) for e in schema.entities()])
         expected_entities = ['BaseTransition', 'Bookmark', 'Boolean', 'Bytes', 'Card',
                              'Date', 'Datetime', 'Decimal',
                              'CWCache', 'CWConstraint', 'CWConstraintType', 'CWEType',
                              'CWAttribute', 'CWGroup', 'EmailAddress', 'CWRelation',
                              'CWPermission', 'CWProperty', 'CWRType',
+                             'CWSource', 'CWSourceHostConfig',
                              'CWUniqueTogetherConstraint', 'CWUser',
                              'ExternalUri', 'File', 'Float', 'Int', 'Interval', 'Note',
                              'Password', 'Personne',
@@ -182,16 +182,17 @@
                              'Tag', 'Time', 'Transition', 'TrInfo',
                              'Workflow', 'WorkflowTransition']
         self.assertListEqual(entities, sorted(expected_entities))
-        relations = [str(r) for r in schema.relations()]
-        relations.sort()
+        relations = sorted([str(r) for r in schema.relations()])
         expected_relations = ['add_permission', 'address', 'alias', 'allowed_transition',
                               'bookmarked_by', 'by_transition',
 
                               'cardinality', 'comment', 'comment_format',
-                              'composite', 'condition', 'connait',
+                              'composite', 'condition', 'config', 'connait',
                               'constrained_by', 'constraint_of',
                               'content', 'content_format',
-                              'created_by', 'creation_date', 'cstrtype', 'custom_workflow', 'cwuri',
+                              'created_by', 'creation_date', 'cstrtype', 'custom_workflow',
+                              'cwuri', 'cw_source', 'cw_host_config_of',
+                              'cw_support', 'cw_dont_cross', 'cw_may_cross',
 
                               'data', 'data_encoding', 'data_format', 'data_name', 'default_workflow', 'defaultval', 'delete_permission',
                               'description', 'description_format', 'destination_state',
@@ -207,7 +208,7 @@
 
                               'label', 'last_login_time', 'login',
 
-                              'mainvars', 'modification_date',
+                              'mainvars', 'match_host', 'modification_date',
 
                               'name', 'nom',
 
@@ -227,11 +228,12 @@
 
                               'wf_info_for', 'wikiid', 'workflow_of']
 
-        self.assertListEqual(relations, expected_relations)
+        self.assertListEqual(relations, sorted(expected_relations))
 
         eschema = schema.eschema('CWUser')
         rels = sorted(str(r) for r in eschema.subject_relations())
-        self.assertListEqual(rels, ['created_by', 'creation_date', 'custom_workflow', 'cwuri', 'eid',
+        self.assertListEqual(rels, ['created_by', 'creation_date', 'custom_workflow',
+                                    'cw_source', 'cwuri', 'eid',
                                      'evaluee', 'firstname', 'has_text', 'identity',
                                      'in_group', 'in_state', 'is',
                                      'is_instance_of', 'last_login_time',
@@ -308,7 +310,7 @@
     def test_comparison(self):
         self.assertEqual(ERQLExpression('X is CWUser', 'X', 0),
                           ERQLExpression('X is CWUser', 'X', 0))
-        self.assertNotEquals(ERQLExpression('X is CWUser', 'X', 0),
+        self.assertNotEqual(ERQLExpression('X is CWUser', 'X', 0),
                              ERQLExpression('X is CWGroup', 'X', 0))
 
 class GuessRrqlExprMainVarsTC(TestCase):
--- a/test/unittest_uilib.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/test/unittest_uilib.py	Wed Oct 13 08:37:21 2010 +0200
@@ -16,14 +16,11 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""unittests for cubicweb.uilib
-
-"""
+"""unittests for cubicweb.uilib"""
 
 __docformat__ = "restructuredtext en"
 
 from logilab.common.testlib import TestCase, unittest_main
-from logilab.common.tree import Node
 
 from cubicweb import uilib
 
--- a/test/unittest_utils.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/test/unittest_utils.py	Wed Oct 13 08:37:21 2010 +0200
@@ -33,8 +33,8 @@
 
 class MakeUidTC(TestCase):
     def test_1(self):
-        self.assertNotEquals(make_uid('xyz'), make_uid('abcd'))
-        self.assertNotEquals(make_uid('xyz'), make_uid('xyz'))
+        self.assertNotEqual(make_uid('xyz'), make_uid('abcd'))
+        self.assertNotEqual(make_uid('xyz'), make_uid('xyz'))
 
     def test_2(self):
         d = set()
@@ -140,14 +140,14 @@
 
     def test_encoding_bare_entity(self):
         e = Entity(None)
-        e['pouet'] = 'hop'
+        e.cw_attr_cache['pouet'] = 'hop'
         e.eid = 2
         self.assertEqual(json.loads(self.encode(e)),
                           {'pouet': 'hop', 'eid': 2})
 
     def test_encoding_entity_in_list(self):
         e = Entity(None)
-        e['pouet'] = 'hop'
+        e.cw_attr_cache['pouet'] = 'hop'
         e.eid = 2
         self.assertEqual(json.loads(self.encode([e])),
                           [{'pouet': 'hop', 'eid': 2}])
--- a/utils.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/utils.py	Wed Oct 13 08:37:21 2010 +0200
@@ -24,6 +24,7 @@
 import decimal
 import datetime
 import random
+from inspect import getargspec
 from itertools import repeat
 from uuid import uuid4
 from warnings import warn
@@ -64,6 +65,40 @@
                                        '__doc__': cls.__doc__,
                                        '__module__': cls.__module__})
 
+def support_args(callable, *argnames):
+    """return true if the callable support given argument names"""
+    argspec = getargspec(callable)
+    if argspec[2]:
+        return True
+    for argname in argnames:
+        if argname not in argspec[0]:
+            return False
+    return True
+
+
+class wrap_on_write(object):
+    def __init__(self, w, tag, closetag=None):
+        self.written = False
+        self.tag = unicode(tag)
+        self.closetag = closetag
+        self.w = w
+
+    def __enter__(self):
+        return self
+
+    def __call__(self, data):
+        if self.written is False:
+            self.w(self.tag)
+            self.written = True
+        self.w(data)
+
+    def __exit__(self, exctype, value, traceback):
+        if self.written is True:
+            if self.closetag:
+                self.w(unicode(self.closetag))
+            else:
+                self.w(self.tag.replace('<', '</', 1))
+
 
 # use networkX instead ?
 # http://networkx.lanl.gov/reference/algorithms.traversal.html#module-networkx.algorithms.traversal.astar
@@ -220,7 +255,7 @@
         if jsoncall is not _MARKER:
             warn('[3.7] specifying jsoncall is not needed anymore',
                  DeprecationWarning, stacklevel=2)
-        self.add_post_inline_script(u"""jQuery(CubicWeb).one('server-response', function(event) {
+        self.add_post_inline_script(u"""$(cw).one('server-response', function(event) {
 %s});""" % jscode)
 
 
--- a/view.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/view.py	Wed Oct 13 08:37:21 2010 +0200
@@ -170,7 +170,6 @@
         else:
             view_func = self.call
         stream = self.set_stream(w)
-        # stream = self.set_stream(context)
         view_func(**context)
         # return stream content if we have created it
         if stream is not None:
@@ -319,21 +318,11 @@
             clabel = vtitle
         return u'%s (%s)' % (clabel, self._cw.property_value('ui.site-title'))
 
-    def output_url_builder( self, name, url, args ):
-        self.w(u'<script language="JavaScript"><!--\n' \
-               u'function %s( %s ) {\n' % (name, ','.join(args) ) )
-        url_parts = url.split("%s")
-        self.w(u' url="%s"' % url_parts[0] )
-        for arg, part in zip(args, url_parts[1:]):
-            self.w(u'+str(%s)' % arg )
-            if part:
-                self.w(u'+"%s"' % part)
-        self.w('\n document.window.href=url;\n')
-        self.w('}\n-->\n</script>\n')
-
+    @deprecated('[3.10] use vreg["etypes"].etype_class(etype).cw_create_url(req)')
     def create_url(self, etype, **kwargs):
         """ return the url of the entity creation form for a given entity type"""
-        return self._cw.build_url('add/%s' % etype, **kwargs)
+        return self._cw.vreg["etypes"].etype_class(etype).cw_create_url(
+            self._cw, **kwargs)
 
     def field(self, label, value, row=True, show_label=True, w=None, tr=True,
               table=False):
@@ -514,8 +503,13 @@
 
     build_js = build_update_js_call # expect updatable component by default
 
+    @property
+    def domid(self):
+        return domid(self.__regid__)
+
+    @deprecated('[3.10] use .domid property')
     def div_id(self):
-        return ''
+        return self.domid
 
 
 class Component(ReloadableMixIn, View):
@@ -523,14 +517,20 @@
     __registry__ = 'components'
     __select__ = yes()
 
-    # XXX huummm, much probably useless
+    # XXX huummm, much probably useless (should be...)
     htmlclass = 'mainRelated'
+    @property
+    def cssclass(self):
+        return '%s %s' % (self.htmlclass, domid(self.__regid__))
+
+    # XXX should rely on ReloadableMixIn.domid
+    @property
+    def domid(self):
+        return '%sComponent' % domid(self.__regid__)
+
+    @deprecated('[3.10] use .cssclass property')
     def div_class(self):
-        return '%s %s' % (self.htmlclass, self.__regid__)
-
-    # XXX a generic '%s%s' % (self.__regid__, self.__registry__.capitalize()) would probably be nicer
-    def div_id(self):
-        return '%sComponent' % self.__regid__
+        return self.cssclass
 
 
 class Adapter(AppObject):
--- a/vregistry.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/vregistry.py	Wed Oct 13 08:37:21 2010 +0200
@@ -174,7 +174,7 @@
         assert len(objects) == 1, objects
         return objects[0](*args, **kwargs)
 
-    def select(self, oid, *args, **kwargs):
+    def select(self, __oid, *args, **kwargs):
         """return the most specific object among those with the given oid
         according to the given context.
 
@@ -182,14 +182,14 @@
 
         raise :exc:`NoSelectableObject` if not object apply
         """
-        return self._select_best(self[oid], *args, **kwargs)
+        return self._select_best(self[__oid], *args, **kwargs)
 
-    def select_or_none(self, oid, *args, **kwargs):
+    def select_or_none(self, __oid, *args, **kwargs):
         """return the most specific object among those with the given oid
         according to the given context, or None if no object applies.
         """
         try:
-            return self.select(oid, *args, **kwargs)
+            return self.select(__oid, *args, **kwargs)
         except (NoSelectableObject, ObjectNotFound):
             return None
     select_object = deprecated('[3.6] use select_or_none instead of select_object'
@@ -465,7 +465,7 @@
         self.load_module(module)
 
     def load_module(self, module):
-        self.info('loading %s', module)
+        self.info('loading %s from %s', module.__name__, module.__file__)
         if hasattr(module, 'registration_callback'):
             module.registration_callback(self)
         else:
--- a/web/action.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/action.py	Wed Oct 13 08:37:21 2010 +0200
@@ -45,35 +45,31 @@
         for action in self.actual_actions():
             menu.append(box.box_action(action))
 
+    def html_class(self):
+        if self._cw.selected(self.url()):
+            return 'selected'
+
+    def build_action(self, title, url, **kwargs):
+        return UnregisteredAction(self._cw, title, url, **kwargs)
+
     def url(self):
         """return the url associated with this action"""
         raise NotImplementedError
 
-    def html_class(self):
-        if self._cw.selected(self.url()):
-            return 'selected'
-        if self.category:
-            return 'box' + self.category.capitalize()
-
-    def build_action(self, title, path, **kwargs):
-        return UnregisteredAction(self._cw, self.cw_rset, title, path, **kwargs)
-
 
 class UnregisteredAction(Action):
-    """non registered action used to build boxes. Unless you set them
-    explicitly, .vreg and .schema attributes at least are None.
-    """
+    """non registered action, used to build boxes"""
     category = None
     id = None
 
-    def __init__(self, req, rset, title, path, **kwargs):
-        Action.__init__(self, req, rset=rset)
+    def __init__(self, req, title, url, **kwargs):
+        Action.__init__(self, req)
         self.title = req._(title)
-        self._path = path
+        self._url = url
         self.__dict__.update(kwargs)
 
     def url(self):
-        return self._path
+        return self._url
 
 
 class LinkToEntityAction(Action):
--- a/web/application.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/application.py	Wed Oct 13 08:37:21 2010 +0200
@@ -31,7 +31,7 @@
 from cubicweb import set_log_methods, cwvreg
 from cubicweb import (
     ValidationError, Unauthorized, AuthenticationError, NoSelectableObject,
-    RepositoryError, CW_EVENT_MANAGER)
+    RepositoryError, BadConnectionId, CW_EVENT_MANAGER)
 from cubicweb.dbapi import DBAPISession
 from cubicweb.web import LOGGER, component
 from cubicweb.web import (
@@ -48,48 +48,43 @@
 
     def __init__(self, vreg):
         self.session_time = vreg.config['http-session-time'] or None
-        if self.session_time is not None:
-            assert self.session_time > 0
-            self.cleanup_session_time = self.session_time
-        else:
-            self.cleanup_session_time = vreg.config['cleanup-session-time'] or 1440 * 60
-            assert self.cleanup_session_time > 0
-        self.cleanup_anon_session_time = vreg.config['cleanup-anonymous-session-time'] or 5 * 60
-        assert self.cleanup_anon_session_time > 0
         self.authmanager = vreg['components'].select('authmanager', vreg=vreg)
+        interval = (self.session_time or 0) / 2.
         if vreg.config.anonymous_user() is not None:
-            self.clean_sessions_interval = max(
-                5 * 60, min(self.cleanup_session_time / 2.,
-                            self.cleanup_anon_session_time / 2.))
-        else:
-            self.clean_sessions_interval = max(
-                5 * 60,
-                self.cleanup_session_time / 2.)
+            self.cleanup_anon_session_time = vreg.config['cleanup-anonymous-session-time'] or 5 * 60
+            assert self.cleanup_anon_session_time > 0
+            if self.session_time is not None:
+                self.cleanup_anon_session_time = min(self.session_time,
+                                                     self.cleanup_anon_session_time)
+            interval = self.cleanup_anon_session_time / 2.
+        # we don't want to check session more than once every 5 minutes
+        self.clean_sessions_interval = max(5 * 60, interval)
 
     def clean_sessions(self):
         """cleanup sessions which has not been unused since a given amount of
         time. Return the number of sessions which have been closed.
         """
         self.debug('cleaning http sessions')
+        session_time = self.session_time
         closed, total = 0, 0
         for session in self.current_sessions():
-            no_use_time = (time() - session.last_usage_time)
             total += 1
-            if session.anonymous_session:
-                if no_use_time >= self.cleanup_anon_session_time:
+            try:
+                last_usage_time = session.cnx.check()
+            except BadConnectionId:
+                self.close_session(session)
+                closed += 1
+            else:
+                no_use_time = (time() - last_usage_time)
+                if session.anonymous_session:
+                    if no_use_time >= self.cleanup_anon_session_time:
+                        self.close_session(session)
+                        closed += 1
+                elif session_time is not None and no_use_time >= session_time:
                     self.close_session(session)
                     closed += 1
-            elif no_use_time >= self.cleanup_session_time:
-                self.close_session(session)
-                closed += 1
         return closed, total - closed
 
-    def has_expired(self, session):
-        """return True if the web session associated to the session is expired
-        """
-        return not (self.session_time is None or
-                    time() < session.last_usage_time + self.session_time)
-
     def current_sessions(self):
         """return currently open sessions"""
         raise NotImplementedError()
@@ -213,8 +208,6 @@
                 except AuthenticationError:
                     req.remove_cookie(cookie, self.SESSION_VAR)
                     raise
-        # remember last usage time for web session tracking
-        session.last_usage_time = time()
 
     def get_session(self, req, sessionid):
         return self.session_manager.get_session(req, sessionid)
@@ -224,8 +217,6 @@
         cookie = req.get_cookie()
         cookie[self.SESSION_VAR] = session.sessionid
         req.set_cookie(cookie, self.SESSION_VAR, maxage=None)
-        # remember last usage time for web session tracking
-        session.last_usage_time = time()
         if not session.anonymous_session:
             self._postlogin(req)
         return session
@@ -233,7 +224,7 @@
     def _update_last_login_time(self, req):
         # XXX should properly detect missing permission / non writeable source
         # and avoid "except (RepositoryError, Unauthorized)" below
-        if req.user.cw_metainformation()['source']['adapter'] == 'ldapuser':
+        if req.user.cw_metainformation()['source']['type'] == 'ldapuser':
             return
         try:
             req.execute('SET X last_login_time NOW WHERE X eid %(x)s',
--- a/web/box.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/box.py	Wed Oct 13 08:37:21 2010 +0200
@@ -21,27 +21,44 @@
 _ = unicode
 
 from logilab.mtconverter import xml_escape
+from logilab.common.deprecation import class_deprecated, class_renamed
 
 from cubicweb import Unauthorized, role as get_role, target as get_target
 from cubicweb.schema import display_name
-from cubicweb.selectors import (no_cnx, one_line_rset,  primary_view,
-                                match_context_prop, partial_relation_possible,
-                                partial_has_related_entities)
-from cubicweb.view import View, ReloadableMixIn
-from cubicweb.uilib import domid, js
+from cubicweb.selectors import no_cnx, one_line_rset
+from cubicweb.view import View
 from cubicweb.web import INTERNAL_FIELD_VALUE, stdmsgs
 from cubicweb.web.htmlwidgets import (BoxLink, BoxWidget, SideBoxWidget,
                                       RawBoxItem, BoxSeparator)
 from cubicweb.web.action import UnregisteredAction
 
 
+def sort_by_category(actions, categories_in_order=None):
+    """return a list of (category, actions_sorted_by_title)"""
+    result = []
+    actions_by_cat = {}
+    for action in actions:
+        actions_by_cat.setdefault(action.category, []).append(
+            (action.title, action) )
+    for key, values in actions_by_cat.items():
+        actions_by_cat[key] = [act for title, act in sorted(values)]
+    if categories_in_order:
+        for cat in categories_in_order:
+            if cat in actions_by_cat:
+                result.append( (cat, actions_by_cat[cat]) )
+    for item in sorted(actions_by_cat.items()):
+        result.append(item)
+    return result
+
+
+# old box system, deprecated ###################################################
+
 class BoxTemplate(View):
     """base template for boxes, usually a (contextual) list of possible
-
     actions. Various classes attributes may be used to control the box
     rendering.
 
-    You may override on of the formatting callbacks is this is not necessary
+    You may override one of the formatting callbacks if this is not necessary
     for your custom box.
 
     Classes inheriting from this class usually only have to override call
@@ -49,8 +66,11 @@
 
         box.render(self.w)
     """
-    __registry__ = 'boxes'
-    __select__ = ~no_cnx() & match_context_prop()
+    __metaclass__ = class_deprecated
+    __deprecation_warning__ = '[3.10] *BoxTemplate classes are deprecated, use *CtxComponent instead (%(cls)s)'
+
+    __registry__ = 'ctxcomponents'
+    __select__ = ~no_cnx()
 
     categories_in_order = ()
     cw_property_defs = {
@@ -64,34 +84,21 @@
                            help=_('context where this box should be displayed')),
         }
     context = 'left'
-    htmlitemclass = 'boxItem'
 
     def sort_actions(self, actions):
         """return a list of (category, actions_sorted_by_title)"""
-        result = []
-        actions_by_cat = {}
-        for action in actions:
-            actions_by_cat.setdefault(action.category, []).append(
-                (action.title, action) )
-        for key, values in actions_by_cat.items():
-            actions_by_cat[key] = [act for title, act in sorted(values)]
-        for cat in self.categories_in_order:
-            if cat in actions_by_cat:
-                result.append( (cat, actions_by_cat[cat]) )
-        for item in sorted(actions_by_cat.items()):
-            result.append(item)
-        return result
+        return sort_by_category(actions, self.categories_in_order)
 
-    def mk_action(self, title, path, escape=True, **kwargs):
+    def mk_action(self, title, url, escape=True, **kwargs):
         """factory function to create dummy actions compatible with the
         .format_actions method
         """
         if escape:
             title = xml_escape(title)
-        return self.box_action(self._action(title, path, **kwargs))
+        return self.box_action(self._action(title, url, **kwargs))
 
-    def _action(self, title, path, **kwargs):
-        return UnregisteredAction(self._cw, self.cw_rset, title, path, **kwargs)
+    def _action(self, title, url, **kwargs):
+        return UnregisteredAction(self._cw, title, url, **kwargs)
 
     # formating callbacks
 
@@ -101,18 +108,14 @@
         return u''
 
     def box_action(self, action):
-        cls = getattr(action, 'html_class', lambda: None)() or self.htmlitemclass
+        klass = getattr(action, 'html_class', lambda: None)()
         return BoxLink(action.url(), self._cw._(action.title),
-                       cls, self.boxitem_link_tooltip(action))
+                       klass, self.boxitem_link_tooltip(action))
 
 
 class RQLBoxTemplate(BoxTemplate):
     """abstract box for boxes displaying the content of a rql query not
     related to the current result set.
-
-    It rely on etype, rtype (both optional, usable to control registration
-    according to application schema and display according to connected
-    user's rights) and rql attributes
     """
 
     rql  = None
@@ -148,29 +151,17 @@
 
 class EntityBoxTemplate(BoxTemplate):
     """base class for boxes related to a single entity"""
-    __select__ = BoxTemplate.__select__ & one_line_rset() & primary_view()
+    __select__ = BoxTemplate.__select__ & one_line_rset()
     context = 'incontext'
 
     def call(self, row=0, col=0, **kwargs):
         """classes inheriting from EntityBoxTemplate should define cell_call"""
         self.cell_call(row, col, **kwargs)
 
-
-class RelatedEntityBoxTemplate(EntityBoxTemplate):
-    __select__ = EntityBoxTemplate.__select__ & partial_has_related_entities()
-
-    def cell_call(self, row, col, **kwargs):
-        entity = self.cw_rset.get_entity(row, col)
-        limit = self._cw.property_value('navigation.related-limit') + 1
-        role = get_role(self)
-        self.w(u'<div class="sideBox">')
-        self.wview('sidebox', entity.related(self.rtype, role, limit=limit),
-                   title=display_name(self._cw, self.rtype, role,
-                                      context=entity.__regid__))
-        self.w(u'</div>')
+from cubicweb.web.component import AjaxEditRelationCtxComponent, EditRelationMixIn
 
 
-class EditRelationBoxTemplate(ReloadableMixIn, EntityBoxTemplate):
+class EditRelationBoxTemplate(EditRelationMixIn, EntityBoxTemplate):
     """base class for boxes which let add or remove entities linked
     by a given relation
 
@@ -181,7 +172,8 @@
     def cell_call(self, row, col, view=None, **kwargs):
         self._cw.add_js('cubicweb.ajax.js')
         entity = self.cw_rset.get_entity(row, col)
-        title = display_name(self._cw, self.rtype, get_role(self), context=entity.__regid__)
+        title = display_name(self._cw, self.rtype, get_role(self),
+                             context=entity.__regid__)
         box = SideBoxWidget(title, self.__regid__)
         related = self.related_boxitems(entity)
         unrelated = self.unrelated_boxitems(entity)
@@ -191,144 +183,13 @@
         box.extend(unrelated)
         box.render(self.w)
 
-    def div_id(self):
-        return self.__regid__
-
     def box_item(self, entity, etarget, rql, label):
-        """builds HTML link to edit relation between `entity` and `etarget`
-        """
-        role, target = get_role(self), get_target(self)
-        args = {role[0] : entity.eid, target[0] : etarget.eid}
-        url = self._cw.user_rql_callback((rql, args))
-        # for each target, provide a link to edit the relation
-        label = u'[<a href="%s">%s</a>] %s' % (xml_escape(url), label,
-                                               etarget.view('incontext'))
+        label = super(EditRelationBoxTemplate, self).box_item(
+            entity, etarget, rql, label)
         return RawBoxItem(label, liclass=u'invisible')
 
-    def related_boxitems(self, entity):
-        rql = 'DELETE S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
-        related = []
-        for etarget in self.related_entities(entity):
-            related.append(self.box_item(entity, etarget, rql, u'-'))
-        return related
-
-    def unrelated_boxitems(self, entity):
-        rql = 'SET S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
-        unrelated = []
-        for etarget in self.unrelated_entities(entity):
-            unrelated.append(self.box_item(entity, etarget, rql, u'+'))
-        return unrelated
-
-    def related_entities(self, entity):
-        return entity.related(self.rtype, get_role(self), entities=True)
-
-    def unrelated_entities(self, entity):
-        """returns the list of unrelated entities, using the entity's
-        appropriate vocabulary function
-        """
-        skip = set(unicode(e.eid) for e in entity.related(self.rtype, get_role(self),
-                                                          entities=True))
-        skip.add(None)
-        skip.add(INTERNAL_FIELD_VALUE)
-        filteretype = getattr(self, 'etype', None)
-        entities = []
-        form = self._cw.vreg['forms'].select('edition', self._cw,
-                                             rset=self.cw_rset,
-                                             row=self.cw_row or 0)
-        field = form.field_by_name(self.rtype, get_role(self), entity.e_schema)
-        for _, eid in field.vocabulary(form):
-            if eid not in skip:
-                entity = self._cw.entity_from_eid(eid)
-                if filteretype is None or entity.__regid__ == filteretype:
-                    entities.append(entity)
-        return entities
-
 
-class AjaxEditRelationBoxTemplate(EntityBoxTemplate):
-    __select__ = EntityBoxTemplate.__select__ & partial_relation_possible()
-
-    # view used to display related entties
-    item_vid = 'incontext'
-    # values separator when multiple values are allowed
-    separator = ','
-    # msgid of the message to display when some new relation has been added/removed
-    added_msg = None
-    removed_msg = None
-
-    # class attributes below *must* be set in concret classes (additionaly to
-    # rtype / role [/ target_etype]. They should correspond to js_* methods on
-    # the json controller
-
-    # function(eid)
-    # -> expected to return a list of values to display as input selector
-    #    vocabulary
-    fname_vocabulary = None
-
-    # function(eid, value)
-    # -> handle the selector's input (eg create necessary entities and/or
-    # relations). If the relation is multiple, you'll get a list of value, else
-    # a single string value.
-    fname_validate = None
-
-    # function(eid, linked entity eid)
-    # -> remove the relation
-    fname_remove = None
+AjaxEditRelationBoxTemplate = class_renamed(
+    'AjaxEditRelationBoxTemplate', AjaxEditRelationCtxComponent,
+    '[3.10] AjaxEditRelationBoxTemplate has been renamed to AjaxEditRelationCtxComponent')
 
-    def cell_call(self, row, col, **kwargs):
-        req = self._cw
-        entity = self.cw_rset.get_entity(row, col)
-        related = entity.related(self.rtype, self.role)
-        rdef = entity.e_schema.rdef(self.rtype, self.role, self.target_etype)
-        if self.role == 'subject':
-            mayadd = rdef.has_perm(req, 'add', fromeid=entity.eid)
-            maydel = rdef.has_perm(req, 'delete', fromeid=entity.eid)
-        else:
-            mayadd = rdef.has_perm(req, 'add', toeid=entity.eid)
-            maydel = rdef.has_perm(req, 'delete', toeid=entity.eid)
-        if not (related or mayadd):
-            return
-        if mayadd or maydel:
-            req.add_js(('cubicweb.ajax.js', 'cubicweb.ajax.box.js'))
-        _ = req._
-        w = self.w
-        divid = domid(self.__regid__) + unicode(entity.eid)
-        w(u'<div class="sideBox" id="%s%s">' % (domid(self.__regid__), entity.eid))
-        w(u'<div class="sideBoxTitle"><span>%s</span></div>' %
-               rdef.rtype.display_name(req, self.role, context=entity.__regid__))
-        w(u'<div class="sideBox"><div class="sideBoxBody">')
-        if related:
-            w(u'<table>')
-            for rentity in related.entities():
-                # for each related entity, provide a link to remove the relation
-                subview = rentity.view(self.item_vid)
-                if maydel:
-                    jscall = unicode(js.ajaxBoxRemoveLinkedEntity(
-                        self.__regid__, entity.eid, rentity.eid,
-                        self.fname_remove,
-                        self.removed_msg and _(self.removed_msg)))
-                    w(u'<tr><td>[<a href="javascript: %s">-</a>]</td>'
-                      '<td class="tagged">%s</td></tr>' % (xml_escape(jscall),
-                                                           subview))
-                else:
-                    w(u'<tr><td class="tagged">%s</td></tr>' % (subview))
-            w(u'</table>')
-        else:
-            w(_('no related entity'))
-        if mayadd:
-            req.add_js('jquery.autocomplete.js')
-            req.add_css('jquery.autocomplete.css')
-            multiple = rdef.role_cardinality(self.role) in '*+'
-            w(u'<table><tr><td>')
-            jscall = unicode(js.ajaxBoxShowSelector(
-                self.__regid__, entity.eid, self.fname_vocabulary,
-                self.fname_validate, self.added_msg and _(self.added_msg),
-                _(stdmsgs.BUTTON_OK[0]), _(stdmsgs.BUTTON_CANCEL[0]),
-                multiple and self.separator))
-            w('<a class="button sglink" href="javascript: %s">%s</a>' % (
-                xml_escape(jscall),
-                multiple and _('add_relation') or _('update_relation')))
-            w(u'</td><td>')
-            w(u'<div id="%sHolder"></div>' % divid)
-            w(u'</td></tr></table>')
-        w(u'</div>\n')
-        w(u'</div></div>\n')
--- a/web/component.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/component.py	Wed Oct 13 08:37:21 2010 +0200
@@ -22,58 +22,23 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
-from logilab.common.deprecation import class_renamed
+from warnings import warn
+
+from logilab.common.deprecation import class_deprecated, class_renamed
 from logilab.mtconverter import xml_escape
 
-from cubicweb import role
+from cubicweb import Unauthorized, role, tags
+from cubicweb.uilib import js, domid
 from cubicweb.utils import json_dumps
-from cubicweb.uilib import js
-from cubicweb.view import Component
-from cubicweb.selectors import (
-    paginated_rset, one_line_rset, primary_view, match_context_prop,
-    partial_has_related_entities)
+from cubicweb.view import ReloadableMixIn, Component
+from cubicweb.selectors import (no_cnx, paginated_rset, one_line_rset,
+                                non_final_entity, partial_relation_possible,
+                                partial_has_related_entities)
+from cubicweb.appobject import AppObject
+from cubicweb.web import htmlwidgets, stdmsgs
 
 
-class EntityVComponent(Component):
-    """abstract base class for additinal components displayed in content
-    headers and footer according to:
-
-    * the displayed entity's type
-    * a context (currently 'header' or 'footer')
-
-    it should be configured using .accepts, .etype, .rtype, .target and
-    .context class attributes
-    """
-
-    __registry__ = 'contentnavigation'
-    __select__ = one_line_rset() & primary_view() & match_context_prop()
-
-    cw_property_defs = {
-        _('visible'):  dict(type='Boolean', default=True,
-                            help=_('display the component or not')),
-        _('order'):    dict(type='Int', default=99,
-                            help=_('display order of the component')),
-        _('context'):  dict(type='String', default='navtop',
-                            vocabulary=(_('navtop'), _('navbottom'),
-                                        _('navcontenttop'), _('navcontentbottom'),
-                                        _('ctxtoolbar')),
-                            help=_('context where this component should be displayed')),
-    }
-
-    context = 'navcontentbottom'
-
-    def call(self, view=None):
-        if self.cw_rset is None:
-            self.entity_call(self.cw_extra_kwargs.pop('entity'))
-        else:
-            self.cell_call(0, 0, view=view)
-
-    def cell_call(self, row, col, view=None):
-        self.entity_call(self.cw_rset.get_entity(row, col), view=view)
-
-    def entity_call(self, entity, view=None):
-        raise NotImplementedError()
-
+# abstract base class for navigation components ################################
 
 class NavigationComponent(Component):
     """abstract base class for navigation components"""
@@ -183,6 +148,431 @@
         return self.next_page_link_templ % (url, title, content)
 
 
+# new contextual components system #############################################
+
+def override_ctx(cls, **kwargs):
+    cwpdefs = cls.cw_property_defs.copy()
+    cwpdefs['context']  = cwpdefs['context'].copy()
+    cwpdefs['context'].update(kwargs)
+    return cwpdefs
+
+
+class EmptyComponent(Exception):
+    """some selectable component has actually no content and should not be
+    rendered
+    """
+
+class Layout(Component):
+    __regid__ = 'layout'
+    __abstract__ = True
+
+    def init_rendering(self):
+        """init view for rendering. Return true if we should go on, false
+        if we should stop now.
+        """
+        view = self.cw_extra_kwargs['view']
+        try:
+            view.init_rendering()
+        except Unauthorized, ex:
+            self.warning("can't render %s: %s", view, ex)
+            return False
+        except EmptyComponent:
+            return False
+        return True
+
+
+class CtxComponent(AppObject):
+    """base class for contextual compontents. The following contexts are
+    predefined:
+
+    * boxes: 'left', 'incontext', 'right'
+    * section: 'navcontenttop', 'navcontentbottom', 'navtop', 'navbottom'
+    * other: 'ctxtoolbar'
+
+    The 'incontext', 'navcontenttop', 'navcontentbottom' and 'ctxtoolbar'
+    context are handled by the default primary view, others by the default main
+    template.
+
+    All subclasses may not support all those contexts (for instance if it can't
+    be displayed as box, or as a toolbar icon). You may restrict allowed context
+    as followed:
+
+    .. sourcecode:: python
+
+      class MyComponent(CtxComponent):
+          cw_property_defs = override_ctx(CtxComponent,
+                                          vocabulary=[list of contexts])
+          context = 'my default context'
+
+    You can configure default component's context by simply giving appropriate
+    value to the `context` class attribute, as seen above.
+    """
+    __registry__ = 'ctxcomponents'
+    __select__ = ~no_cnx()
+
+    categories_in_order = ()
+    cw_property_defs = {
+        _('visible'): dict(type='Boolean', default=True,
+                           help=_('display the box or not')),
+        _('order'):   dict(type='Int', default=99,
+                           help=_('display order of the box')),
+        _('context'): dict(type='String', default='left',
+                           vocabulary=(_('left'), _('incontext'), _('right'),
+                                       _('navtop'), _('navbottom'),
+                                       _('navcontenttop'), _('navcontentbottom'),
+                                       _('ctxtoolbar')),
+                           help=_('context where this component should be displayed')),
+        }
+    visible = True
+    order = 0
+    context = 'left'
+    contextual = False
+    title = None
+
+    # XXX support kwargs for compat with old boxes which gets the view as
+    # argument
+    def render(self, w, **kwargs):
+        if hasattr(self, 'call'):
+            warn('[3.10] should not anymore implements call on %s, see new CtxComponent api'
+                 % self.__class__, DeprecationWarning)
+            self.w = w
+            def wview(__vid, rset=None, __fallback_vid=None, **kwargs):
+                self._cw.view(__vid, rset, __fallback_vid, w=self.w, **kwargs)
+            self.wview = wview
+            self.call(**kwargs)
+            return
+        getlayout = self._cw.vreg['components'].select
+        try:
+            # XXX ensure context is given when the component is reloaded through
+            # ajax
+            context = self.cw_extra_kwargs['context']
+        except KeyError:
+            context = self.cw_propval('context')
+        layout = getlayout('layout', self._cw, rset=self.cw_rset,
+                           row=self.cw_row, col=self.cw_col,
+                           view=self, context=context)
+        layout.render(w)
+
+    def init_rendering(self):
+        """init rendering callback: that's the good time to check your component
+        has some content to display. If not, you can still raise
+        :exc:`EmptyComponent` to inform it should be skipped.
+
+        Also, :exc:`Unauthorized` will be catched, logged, then the component
+        will be skipped.
+        """
+        self.items = []
+
+    @property
+    def domid(self):
+        """return the HTML DOM identifier for this component"""
+        return domid(self.__regid__)
+
+    @property
+    def cssclass(self):
+        """return the CSS class name for this component"""
+        return domid(self.__regid__)
+
+    def render_title(self, w):
+        """return the title for this component"""
+        if self.title:
+            w(self._cw._(self.title))
+
+    def render_body(self, w):
+        """return the body (content) for this component"""
+        raise NotImplementedError()
+
+    def render_items(self, w, items=None, klass=u'boxListing'):
+        if items is None:
+            items = self.items
+        assert items
+        w(u'<ul class="%s">' % klass)
+        for item in items:
+            if hasattr(item, 'render'):
+                item.render(w) # XXX display <li> by itself
+            else:
+                w(u'<li>')
+                w(item)
+                w(u'</li>')
+        w(u'</ul>')
+
+    def append(self, item):
+        self.items.append(item)
+
+    def box_action(self, action): # XXX action_link
+        return self.build_link(self._cw._(action.title), action.url())
+
+    def build_link(self, title, url, **kwargs):
+        if self._cw.selected(url):
+            try:
+                kwargs['klass'] += ' selected'
+            except KeyError:
+                kwargs['klass'] = 'selected'
+        return tags.a(title, href=url, **kwargs)
+
+
+class EntityCtxComponent(CtxComponent):
+    """base class for boxes related to a single entity"""
+    __select__ = CtxComponent.__select__ & non_final_entity() & one_line_rset()
+    context = 'incontext'
+    contextual = True
+
+    def __init__(self, *args, **kwargs):
+        super(EntityCtxComponent, self).__init__(*args, **kwargs)
+        try:
+            entity = kwargs['entity']
+        except KeyError:
+            entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
+        self.entity = entity
+
+    @property
+    def domid(self):
+        return domid(self.__regid__) + unicode(self.entity.eid)
+
+
+# high level abstract classes ##################################################
+
+class RQLCtxComponent(CtxComponent):
+    """abstract box for boxes displaying the content of a rql query not
+    related to the current result set.
+    """
+    rql  = None
+
+    def to_display_rql(self):
+        assert self.rql is not None, self.__regid__
+        return (self.rql,)
+
+    def init_rendering(self):
+        rset = self._cw.execute(*self.to_display_rql())
+        if not rset:
+            raise EmptyComponent()
+        if len(rset[0]) == 2:
+            self.items = []
+            for i, (eid, label) in enumerate(rset):
+                entity = rset.get_entity(i, 0)
+                self.items.append(self.build_link(label, entity.absolute_url()))
+        else:
+            self.items = [self.build_link(e.dc_title(), e.absolute_url())
+                          for e in rset.entities()]
+
+    def render_body(self, w):
+        self.render_items(w)
+
+
+class EditRelationMixIn(ReloadableMixIn):
+    def box_item(self, entity, etarget, rql, label):
+        """builds HTML link to edit relation between `entity` and `etarget`"""
+        role, target = role(self), get_target(self)
+        args = {role[0] : entity.eid, target[0] : etarget.eid}
+        url = self._cw.user_rql_callback((rql, args))
+        # for each target, provide a link to edit the relation
+        return u'[<a href="%s">%s</a>] %s' % (xml_escape(url), label,
+                                              etarget.view('incontext'))
+
+    def related_boxitems(self, entity):
+        rql = 'DELETE S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
+        return [self.box_item(entity, etarget, rql, u'-')
+                for etarget in self.related_entities(entity)]
+
+    def related_entities(self, entity):
+        return entity.related(self.rtype, role(self), entities=True)
+
+    def unrelated_boxitems(self, entity):
+        rql = 'SET S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
+        return [self.box_item(entity, etarget, rql, u'+')
+                for etarget in self.unrelated_entities(entity)]
+
+    def unrelated_entities(self, entity):
+        """returns the list of unrelated entities, using the entity's
+        appropriate vocabulary function
+        """
+        skip = set(unicode(e.eid) for e in entity.related(self.rtype, role(self),
+                                                          entities=True))
+        skip.add(None)
+        skip.add(INTERNAL_FIELD_VALUE)
+        filteretype = getattr(self, 'etype', None)
+        entities = []
+        form = self._cw.vreg['forms'].select('edition', self._cw,
+                                             rset=self.cw_rset,
+                                             row=self.cw_row or 0)
+        field = form.field_by_name(self.rtype, role(self), entity.e_schema)
+        for _, eid in field.vocabulary(form):
+            if eid not in skip:
+                entity = self._cw.entity_from_eid(eid)
+                if filteretype is None or entity.__regid__ == filteretype:
+                    entities.append(entity)
+        return entities
+
+
+class EditRelationCtxComponent(EditRelationMixIn, EntityCtxComponent):
+    """base class for boxes which let add or remove entities linked by a given
+    relation
+
+    subclasses should define at least id, rtype and target class attributes.
+    """
+    def render_title(self, w):
+        return display_name(self._cw, self.rtype, role(self),
+                            context=self.entity.__regid__)
+
+    def render_body(self, w):
+        self._cw.add_js('cubicweb.ajax.js')
+        related = self.related_boxitems(self.entity)
+        unrelated = self.unrelated_boxitems(self.entity)
+        self.items.extend(related)
+        if related and unrelated:
+            self.items.append(htmlwidgets.BoxSeparator())
+        self.items.extend(unrelated)
+        self.render_items(w)
+
+
+class AjaxEditRelationCtxComponent(EntityCtxComponent):
+    __select__ = EntityCtxComponent.__select__ & (
+        partial_relation_possible(action='add') | partial_has_related_entities())
+
+    # view used to display related entties
+    item_vid = 'incontext'
+    # values separator when multiple values are allowed
+    separator = ','
+    # msgid of the message to display when some new relation has been added/removed
+    added_msg = None
+    removed_msg = None
+
+    # class attributes below *must* be set in concret classes (additionaly to
+    # rtype / role [/ target_etype]. They should correspond to js_* methods on
+    # the json controller
+
+    # function(eid)
+    # -> expected to return a list of values to display as input selector
+    #    vocabulary
+    fname_vocabulary = None
+
+    # function(eid, value)
+    # -> handle the selector's input (eg create necessary entities and/or
+    # relations). If the relation is multiple, you'll get a list of value, else
+    # a single string value.
+    fname_validate = None
+
+    # function(eid, linked entity eid)
+    # -> remove the relation
+    fname_remove = None
+
+    def __init__(self, *args, **kwargs):
+        super(AjaxEditRelationCtxComponent, self).__init__(*args, **kwargs)
+        self.rdef = self.entity.e_schema.rdef(self.rtype, self.role, self.target_etype)
+
+    def render_title(self, w):
+        w(self.rdef.rtype.display_name(self._cw, self.role,
+                                       context=self.entity.__regid__))
+
+    def render_body(self, w):
+        req = self._cw
+        entity = self.entity
+        related = entity.related(self.rtype, self.role)
+        if self.role == 'subject':
+            mayadd = self.rdef.has_perm(req, 'add', fromeid=entity.eid)
+            maydel = self.rdef.has_perm(req, 'delete', fromeid=entity.eid)
+        else:
+            mayadd = self.rdef.has_perm(req, 'add', toeid=entity.eid)
+            maydel = self.rdef.has_perm(req, 'delete', toeid=entity.eid)
+        if mayadd or maydel:
+            req.add_js(('jquery.ui.js', 'cubicweb.widgets.js'))
+            req.add_js(('cubicweb.ajax.js', 'cubicweb.ajax.box.js'))
+        _ = req._
+        if related:
+            w(u'<table class="ajaxEditRelationTable">')
+            for rentity in related.entities():
+                # for each related entity, provide a link to remove the relation
+                subview = rentity.view(self.item_vid)
+                if maydel:
+                    jscall = unicode(js.ajaxBoxRemoveLinkedEntity(
+                        self.__regid__, entity.eid, rentity.eid,
+                        self.fname_remove,
+                        self.removed_msg and _(self.removed_msg)))
+                    w(u'<tr><td class="dellink">[<a href="javascript: %s">-</a>]</td>'
+                      '<td class="entity"> %s</td></tr>' % (xml_escape(jscall),
+                                                            subview))
+                else:
+                    w(u'<tr><td class="entity">%s</td></tr>' % (subview))
+            w(u'</table>')
+        else:
+            w(_('no related entity'))
+        if mayadd:
+            req.add_js(('jquery.ui.js', 'cubicweb.widgets.js'))
+            req.add_css('jquery.ui.css')
+            multiple = self.rdef.role_cardinality(self.role) in '*+'
+            w(u'<table><tr><td>')
+            jscall = unicode(js.ajaxBoxShowSelector(
+                self.__regid__, entity.eid, self.fname_vocabulary,
+                self.fname_validate, self.added_msg and _(self.added_msg),
+                _(stdmsgs.BUTTON_OK[0]), _(stdmsgs.BUTTON_CANCEL[0]),
+                multiple and self.separator))
+            w('<a class="button sglink" href="javascript: %s">%s</a>' % (
+                xml_escape(jscall),
+                multiple and _('add_relation') or _('update_relation')))
+            w(u'</td><td>')
+            w(u'<div id="%sHolder"></div>' % self.domid)
+            w(u'</td></tr></table>')
+
+
+class RelatedObjectsCtxComponent(EntityCtxComponent):
+    """a contextual component to display entities related to another"""
+    __select__ = EntityCtxComponent.__select__ & partial_has_related_entities()
+    context = 'navcontentbottom'
+    rtype = None
+    role = 'subject'
+
+    vid = 'list'
+
+    def render_body(self, w):
+        rset = self.entity.related(self.rtype, role(self))
+        self._cw.view(self.vid, rset, w=w)
+
+
+# old contextual components, deprecated ########################################
+
+class EntityVComponent(Component):
+    """abstract base class for additinal components displayed in content
+    headers and footer according to:
+
+    * the displayed entity's type
+    * a context (currently 'header' or 'footer')
+
+    it should be configured using .accepts, .etype, .rtype, .target and
+    .context class attributes
+    """
+    __metaclass__ = class_deprecated
+    __deprecation_warning__ = '[3.10] *VComponent classes are deprecated, use *CtxComponent instead (%(cls)s)'
+
+    __registry__ = 'ctxcomponents'
+    __select__ = one_line_rset()
+
+    cw_property_defs = {
+        _('visible'):  dict(type='Boolean', default=True,
+                            help=_('display the component or not')),
+        _('order'):    dict(type='Int', default=99,
+                            help=_('display order of the component')),
+        _('context'):  dict(type='String', default='navtop',
+                            vocabulary=(_('navtop'), _('navbottom'),
+                                        _('navcontenttop'), _('navcontentbottom'),
+                                        _('ctxtoolbar')),
+                            help=_('context where this component should be displayed')),
+    }
+
+    context = 'navcontentbottom'
+
+    def call(self, view=None):
+        if self.cw_rset is None:
+            self.entity_call(self.cw_extra_kwargs.pop('entity'))
+        else:
+            self.cell_call(0, 0, view=view)
+
+    def cell_call(self, row, col, view=None):
+        self.entity_call(self.cw_rset.get_entity(row, col), view=view)
+
+    def entity_call(self, entity, view=None):
+        raise NotImplementedError()
+
+
 class RelatedObjectsVComponent(EntityVComponent):
     """a section to display some related entities"""
     __select__ = EntityVComponent.__select__ & partial_has_related_entities()
@@ -203,14 +593,15 @@
             rset = self._cw.execute(self.rql(), {'x': eid})
         if not rset.rowcount:
             return
-        self.w(u'<div class="%s">' % self.div_class())
+        self.w(u'<div class="%s">' % self.cssclass)
         self.w(u'<h4>%s</h4>\n' % self._cw._(self.title).capitalize())
         self.wview(self.vid, rset)
         self.w(u'</div>')
 
 
+
 VComponent = class_renamed('VComponent', Component,
-                           'VComponent is deprecated, use Component')
+                           '[3.2] VComponent is deprecated, use Component')
 SingletonVComponent = class_renamed('SingletonVComponent', Component,
-                                    'SingletonVComponent is deprecated, use '
+                                    '[3.2] SingletonVComponent is deprecated, use '
                                     'Component and explicit registration control')
Binary file web/data/actionBoxHeader.png has changed
Binary file web/data/boxHeader.png has changed
Binary file web/data/contextFreeBoxHeader.png has changed
Binary file web/data/contextualBoxHeader.png has changed
--- a/web/data/cubicweb.ajax.box.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.ajax.box.js	Wed Oct 13 08:37:21 2010 +0200
@@ -53,28 +53,23 @@
         deferred.addCallback(function (unrelated) {
             var input = INPUT({'type': 'text', 'id': inputid, 'size': 20});
             holder.append(input).show();
-            $input = $(input);
-            $input.keypress(function (event) {
-                if (event.keyCode == KEYS.KEY_ENTER) {
-                    // XXX not very user friendly: we should test that the suggestions
-                    //     aren't visible anymore
+            var $input = $(input);
+            $input.keypress(function (evt) {
+                if (evt.keyCode == $.ui.keyCode.ENTER) {
                     ajaxBoxValidateSelectorInput(boxid, eid, separator, addfname, msg);
                 }
             });
+            $input.cwautocomplete(unrelated, {multiple: true});
             var buttons = DIV({'class' : "sgformbuttons"},
-                              A({'href' : "javascript: noop();",
-                                 'onclick' : cw.utils.strFuncCall('ajaxBoxValidateSelectorInput',
+                              A({href : "javascript: noop();",
+                                 onclick : cw.utils.strFuncCall('ajaxBoxValidateSelectorInput',
                                                                   boxid, eid, separator, addfname, msg)},
-                                  oklabel),
+                                oklabel),
                               ' / ',
                               A({'href' : "javascript: noop();",
                                  'onclick' : '$("#' + holderid + '").empty()'},
                                   cancellabel));
             holder.append(buttons);
-            $input.autocomplete(unrelated, {
-                multiple: separator,
-                max: 15
-            });
             $input.focus();
         });
     }
--- a/web/data/cubicweb.ajax.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.ajax.js	Wed Oct 13 08:37:21 2010 +0200
@@ -188,7 +188,7 @@
     _loadDynamicFragments(node);
     // XXX [3.7] jQuery.one is now used instead jQuery.bind,
     // jquery.treeview.js can be unpatched accordingly.
-    jQuery(CubicWeb).trigger('server-response', [true, node]);
+    jQuery(cw).trigger('server-response', [true, node]);
     jQuery(node).trigger('server-response', [true, node]);
 }
 
@@ -296,6 +296,7 @@
             url: url,
             type: (reqtype || 'GET').toUpperCase(),
             data: form,
+            traditional: true,
             async: true,
 
             beforeSend: function(xhr) {
@@ -303,9 +304,6 @@
             },
 
             success: function(data, status) {
-                if (deferred._req.getResponseHeader("content-type") == 'application/json') {
-                    data = cw.evalJSON(data);
-                }
                 deferred.success(data);
             },
 
@@ -328,14 +326,9 @@
             url: url,
             type: (reqtype || 'GET').toUpperCase(),
             data: form,
+            traditional: true,
             async: false
         });
-        // check result.responseText instead of result to avoid error encountered with IE
-        if (result.responseText) {
-            // XXX no good reason to force json here, 
-            // it should depends on request content-type
-            result = cw.evalJSON(result.responseText);
-        }
         return result;
     }
 }
@@ -639,14 +632,15 @@
     function(fname /* ... */) {
         setProgressCursor();
         var props = {
-            'fname': fname,
-            'pageid': pageid,
-            'arg': $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
+            fname: fname,
+            pageid: pageid,
+            arg: $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
         };
         var result = jQuery.ajax({
             url: JSON_BASE_URL,
             data: props,
-            async: false
+            async: false,
+            traditional: true
         }).responseText;
         if (result) {
             result = cw.evalJSON(result);
@@ -661,9 +655,9 @@
     function(fname /* ... */) {
         setProgressCursor();
         var props = {
-            'fname': fname,
-            'pageid': pageid,
-            'arg': $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
+            fname: fname,
+            pageid: pageid,
+            arg: $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
         };
         // XXX we should inline the content of loadRemote here
         var deferred = loadRemote(JSON_BASE_URL, props, 'POST');
--- a/web/data/cubicweb.calendar.css	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.calendar.css	Wed Oct 13 08:37:21 2010 +0200
@@ -230,7 +230,7 @@
 .calendar th.month {
  font-weight:bold;
  padding-bottom:0.2em;
- background: %(actionBoxTitleBgColor)s;
+ background: %(incontextBoxBodyBgColor)s;
 }
 
 .calendar th.month a{
--- a/web/data/cubicweb.css	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.css	Wed Oct 13 08:37:21 2010 +0200
@@ -31,19 +31,22 @@
 /* h3 { font-size:1.30769em; } */
 
 /* scale traditional */
-h1 { font-size: %(h1FontSize)s; }
+h1,
+.vtitle { font-size: %(h1FontSize)s; }
 h2 { font-size: %(h2FontSize)s; }
 h3 { font-size: %(h3FontSize)s; }
 
 /* paddings */
-h1 {
+h1,
+.vtitle {
   border-bottom: %(h1BorderBottomStyle)s;
   padding: %(h1Padding)s;
   margin: %(h1Margin)s;
   color: %(h1Color)s;
 }
 
-div.tabbedprimary + h1, h1.plain {
+div.tabbedprimary + h1,
+h1.plain {
  border-bottom: none;
 }
 
@@ -100,7 +103,7 @@
 }
 
 ol ol,
-ul ul{
+ul ul {
   margin-left: 8px;
   margin-bottom : 0px;
 }
@@ -113,7 +116,7 @@
   margin-left: 1.5em;
 }
 
-img{
+img {
   border: none;
 }
 
@@ -139,7 +142,7 @@
   border: 1px inset %(headerBgColor)s;
 }
 
-hr{
+hr {
   border: none;
   border-bottom: 1px solid %(defaultColor)s;
   height: 1px;
@@ -219,6 +222,7 @@
 table#header {
   background: %(headerBgColor)s url("banner.png") repeat-x top left;
   text-align: left;
+  width: 100%;
 }
 
 table#header td {
@@ -229,6 +233,15 @@
   color: %(defaultColor)s;
 }
 
+table#header td#headtext {
+  float: left;
+}
+
+table#header td#header-right {
+  padding-top: 1em;
+  float: right;
+}
+
 table#header img#logo{
   vertical-align: middle;
 }
@@ -239,23 +252,14 @@
   white-space: nowrap;
 }
 
-table#header td#headtext {
-  width: 100%;
-}
-
 /* Popup on login box and userActionBox */
 div.popupWrapper {
   position: relative;
-  z-index: 100;
 }
 
 div.popup {
   position: absolute;
   background: #fff;
-  /* background-color: #f0eff0; */
-  /* background-image: url(popup.png); */
-  /* background-repeat: repeat-x; */
-  /* background-positon: top left; */
   border: 1px solid %(listingBorderColor)s;
   border-top: none;
   text-align: left;
@@ -273,12 +277,13 @@
   margin: %(defaultLayoutMargin)s;
 }
 
-table#mainLayout #navColumnLeft {
+table#mainLayout td#navColumnLeft {
   width: 16em;
   padding-right: %(defaultLayoutMargin)s;
+
 }
 
-table#mainLayout #navColumnRight {
+table#mainLayout td#navColumnRight {
   width: 16em;
   padding-left: %(defaultLayoutMargin)s;
 }
@@ -313,28 +318,15 @@
   color: %(defaultColor)s;
 }
 
-/* rql bar */
-
-div#rqlinput {
-  margin-bottom: %(defaultLayoutMargin)s;
-}
-
-input#rql{
-  padding: 0.25em 0.3em;
-  width: 99%;
-}
-
-/* boxes */
+/* XXX old boxes, deprecated */
 
 div.boxFrame {
   width: 100%;
 }
 
 div.boxTitle {
-  overflow: hidden;
-  font-weight: bold;
   color: #fff;
-  background: %(boxTitleBg)s;
+  background: %(contextualBoxTitleBgColor)s;
 }
 
 div.boxTitle span,
@@ -343,14 +335,7 @@
   white-space: nowrap;
 }
 
-div.searchBoxFrame div.boxTitle,
-div.greyBoxFrame div.boxTitle {
-  background: %(actionBoxTitleBg)s;
-}
-
-div.sideBoxTitle span,
-div.searchBoxFrame div.boxTitle span,
-div.greyBoxFrame div.boxTitle span {
+div.sideBoxTitle span {
   color: %(defaultColor)s;
 }
 
@@ -364,34 +349,13 @@
   border-top: none;
 }
 
-a.boxMenu {
-  display: block;
-  padding: 1px 9px 1px 3px;
-  background: transparent %(bulletDownImg)s;
-}
-
-a.boxMenu:hover {
-  background: %(sideBoxBodyBgColor)s %(bulletDownImg)s;
-  cursor: pointer;
-}
-
-a.popupMenu {
-  background: transparent url("puce_down_black.png") 2% 6px no-repeat;
-  padding-left: 2em;
-}
-
-div.searchBoxFrame div.boxContent {
-  padding: 4px 4px 3px;
-  background: #f0eff0 url("gradient-grey-up.png") left top repeat-x;
-}
-
 div.shadow{
   height: 14px;
   background: url("shadow.gif") no-repeat top right;
 }
 
 div.sideBoxTitle {
-  background: %(actionBoxTitleBg)s;
+  background: %(incontextBoxBodyBg)s;
   display: block;
   font-weight: bold;
 }
@@ -412,11 +376,11 @@
 
 div.sideBoxBody {
   padding: 0.2em 5px;
-  background: %(sideBoxBodyBg)s;
+  background: %(incontextBoxBodyBg)s;
 }
 
 div.sideBoxBody a {
-  color: %(sideBoxBodyColor)s;
+  color: %(incontextBoxBodyColor)s;
 }
 
 div.sideBoxBody a:hover {
@@ -427,6 +391,174 @@
   padding-right: 1em;
 }
 
+/* boxes */
+
+div.boxTitle {
+  overflow: hidden;
+  font-weight: bold;
+}
+
+div.boxTitle span {
+  padding: 0px 0.5em;
+  white-space: nowrap;
+}
+
+div.boxBody {
+  padding: 5px;
+  border-top: none;
+  background-color: %(leftrightBoxBodyBgColor)s;
+}
+
+div.boxBody a {
+  color: %(leftrightBoxBodyColor)s;
+}
+
+div.boxBody a:hover {
+  text-decoration: none;
+  cursor: pointer;
+  background-color: %(leftrightBoxBodyHoverBgColor)s;
+}
+
+/* boxes contextual customization */
+
+.contextFreeBox div.boxTitle {
+  background: %(contextFreeBoxTitleBg)s;
+  color: %(contextFreeBoxTitleColor)s;
+}
+
+.contextualBox div.boxTitle {
+  background: %(contextualBoxTitleBg)s;
+  color: %(contextualBoxTitleColor)s;
+}
+
+.primaryRight div.boxTitle {
+  background: %(incontextBoxTitleBg)s;
+  color: %(incontextBoxTitleColor)s;
+}
+
+.primaryRight div.boxBody {
+  padding: 0.2em 5px;
+  background: %(incontextBoxBodyBgColor)s;
+}
+
+.primaryRight div.boxBody a {
+  color: %(incontextBoxBodyColor)s;
+}
+
+.primaryRight div.boxBody a:hover {
+  background-color: %(incontextBoxBodyHoverBgColor)s;
+}
+
+.primaryRight div.boxFooter {
+  margin-bottom: 1em;
+}
+
+#navColumnLeft div.boxFooter, #navColumnRight div.boxFooter{
+  height: 14px;
+  background: url("shadow.gif") no-repeat top right;
+}
+
+/* boxes lists and menus */
+
+ul.boxListing {
+  margin: 0;
+  padding: 0;
+}
+
+ul.boxListing ul {
+  padding: 1px 3px;
+}
+
+ul.boxListing a {
+  color: %(defaultColor)s;
+  display: block;
+  padding: 1px 9px 1px 3px;
+}
+
+ul.boxListing li {
+  margin: 0px;
+  padding: 0px;
+  background-image: none;
+}
+
+ul.boxListing ul li {
+  margin: 0px;
+  padding-left: 8px;
+}
+
+ul.boxListing ul li a {
+  padding-left: 10px;
+  background-image: url("bullet_orange.png");
+  background-repeat: no-repeat;
+  background-position: 0 6px;
+}
+
+ul.boxListing .selected {
+  color: %(aColor)s;
+  font-weight: bold;
+}
+
+ul.boxListing a.boxMenu:hover {
+  border-top: medium none;
+  background: %(leftrightBoxBodyHoverBgColor)s;
+}
+
+a.boxMenu,
+ul.boxListing a.boxMenu{
+  display: block;
+  padding: 1px 3px;
+  background: transparent %(bulletDownImg)s;
+}
+
+ul.boxListing a.boxMenu:hover {
+  border-top: medium none;
+  background: %(leftrightBoxBodyHoverBgColor)s %(bulletDownImg)s;
+}
+
+a.boxMenu:hover {
+  cursor: pointer;
+}
+
+a.popupMenu {
+  background: transparent url("puce_down_black.png") 2% 6px no-repeat;
+  padding-left: 2em;
+}
+
+/* custom boxes */
+
+.search_box div.boxBody {
+  padding: 4px 4px 3px;
+  background: #f0eff0 url("gradient-grey-up.png") left top repeat-x;
+}
+
+.bookmarks_box ul.boxListing div a{
+  background: #fff;
+  display: inline;
+  padding: 0;
+}
+.bookmarks_box ul.boxListing div a:hover{
+  border-bottom: 1px solid #000;
+}
+
+.download_box div.boxTitle {
+  background : #8fbc8f !important;
+}
+
+.download_box div.boxBody {
+  background : #eefed9;
+}
+
+/* search box and rql bar */
+
+div#rqlinput {
+  margin-bottom: %(defaultLayoutMargin)s;
+}
+
+input#rql{
+  padding: 0.25em 0.3em;
+  width: 99%;
+}
+
 input.rqlsubmit{
   display: block;
   width: 20px;
@@ -436,7 +568,7 @@
 }
 
 input#norql{
-  width:13em;
+  width:155px;
   margin-right: 2px;
 }
 
@@ -447,7 +579,7 @@
 }
 
 div#userActionsBox {
-  width: 14em;
+  width: 15em;
   text-align: right;
 }
 
@@ -457,20 +589,6 @@
   padding-right: 2em;
 }
 
-/* download box XXX move to its own file? */
-div.downloadBoxTitle{
- background : #8fbc8f;
- font-weight: bold;
-}
-
-div.downloadBox{
- font-weight: bold;
-}
-
-div.downloadBox div.sideBoxBody{
- background : #eefed9;
-}
-
 /**************/
 /* navigation */
 /**************/
@@ -578,7 +696,7 @@
 
 div#appMsg {
   margin-bottom: %(defaultLayoutMargin)s;
-  border: 1px solid %(actionBoxTitleBgColor)s;
+  border: 1px solid %(incontextBoxTitleBgColor)s;
 }
 
 .message {
@@ -591,7 +709,7 @@
   padding-left: 25px;
   background: %(msgBgColor)s url("critical.png") 2px center no-repeat;
   color: %(errorMsgColor)s;
-  border: 1px solid %(actionBoxTitleBgColor)s;
+  border: 1px solid %(incontextBoxTitleBgColor)s;
 }
 
 /* search-associate message */
@@ -701,6 +819,14 @@
   margin-bottom: 0.2em; /* because vertical-align doesn't seems to have any effect */
 }
 
+
+table.ajaxEditRelationTable{
+  margin-bottom: 0.5em;
+}
+table.ajaxEditRelationTable td.entity{
+  padding-left: 0.5em;
+}
+
 /***************************************/
 /* error view (views/management.py)    */
 /***************************************/
@@ -746,7 +872,7 @@
 input.button{
   margin: 1em 1em 0px 0px;
   border: 1px solid %(buttonBorderColor)s;
-  border-color: %(buttonBorderColor)s %(actionBoxTitleBgColor)s %(actionBoxTitleBgColor)s %(buttonBorderColor)s;
+  border-color: %(buttonBorderColor)s %(incontextBoxTitleBgColor)s %(incontextBoxTitleBgColor)s %(buttonBorderColor)s;
 }
 
 /* FileItemInnerView  jquery.treeview.css */
@@ -766,74 +892,20 @@
 
 ul.startup li,
 ul.section li {
-  margin-left:0px
-}
-
-ul.boxListing {
-  margin: 0px;
-  padding: 0px 3px;
-}
-
-ul.boxListing li,
-ul.boxListing ul li {
-  margin: 0px;
-  padding: 0px;
-  background-image: none;
-}
-
-ul.boxListing ul {
-  padding: 1px 3px;
-}
-
-ul.boxListing a {
-  color: %(defaultColor)s;
-  display:block;
-  padding: 1px 9px 1px 3px;
-}
-
-ul.boxListing .selected {
-  color: %(aColor)s;
-  font-weight: bold;
-}
-
-ul.boxListing a.boxMenu:hover {
-  border-top: medium none;
-  background: %(sideBoxBodyBgColor)s %(bulletDownImg)s;
-}
-
-ul.boxListing a.boxBookmark {
-  padding-left: 3px;
-  background-image: none;
-  background:#fff;
+  margin-left: 0px
 }
 
 ul.simple li,
-ul.boxListing ul li ,
 .popupWrapper ul li {
   background: transparent url("bullet_orange.png") no-repeat 0% 6px;
 }
 
-ul.boxListing a.boxBookmark:hover,
-ul.boxListing a:hover,
-ul.boxListing ul li a:hover {
-  text-decoration: none;
-  background: %(sideBoxBodyBg)s;
-}
-
-ul.boxListing ul li a:hover{
-  background-color: transparent;
-}
-
-ul.boxListing ul li a {
-  padding: 1px 3px 0px 10px;
-}
-
 ul.simple li {
   padding-left: 8px;
 }
 
 .popupWrapper ul {
-  padding:0.2em 0.3em;
+  padding: 0.2em 0.3em;
   margin-bottom: 0px;
 }
 
@@ -866,7 +938,7 @@
 .validateButton {
   margin: 1em 1em 0px 0px;
   border: 1px solid %(buttonBorderColor)s;
-  border-color: %(buttonBorderColor)s %(actionBoxTitleBgColor)s %(actionBoxTitleBgColor)s %(buttonBorderColor)s;
+  border-color: %(buttonBorderColor)s %(incontextBoxTitleBgColor)s %(incontextBoxTitleBgColor)s %(buttonBorderColor)s;
   background: %(buttonBgColor)s url("button.png") bottom left repeat-x;
 }
 
@@ -906,6 +978,11 @@
 /* overwite other css here      */
 /********************************/
 
+.ui-menu li.ui-menu-item {
+  /* remove background image (orange bullet) for autocomplete suggestions */
+  background-image: none;
+}
+
 /* ui.tabs.css */
 ul.ui-tabs-nav,
 div.ui-tabs-panel {
--- a/web/data/cubicweb.edition.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.edition.js	Wed Oct 13 08:37:21 2010 +0200
@@ -591,176 +591,8 @@
         log('got exception', ex);
         return false;
     }
-    function _callback(result, req) {
+    d.addCallback(function(result, req) {
         handleFormValidationResponse(formid, onsuccess, onfailure, result);
-    }
-    d.addCallback(_callback);
+    });
     return false;
 }
-
-
-
-// ======================= DEPRECATED FUNCTIONS ========================= //
-// (mostly reledit related)
-/**
- * .. function:: inlineValidateRelationFormOptions(rtype, eid, divid, options)
- *
- * called by reledit forms to submit changes
- * * `rtype`, the attribute being edited
- *
- * * `eid`, the eid of the entity being edited
- *
- * * `options`, a dictionnary of options used by the form validation handler such
- *    as ``role``, ``onsuccess``, ``onfailure``, ``reload``, ``vid``, ``lzone``
- *    and ``default_value``:
- *
- *     * `onsucess`, javascript function to execute on success, default is noop
- *
- *     * `onfailure`, javascript function to execute on failure, default is noop
- *
- *     * `default_value`, value if the field is empty
- *
- *     * `lzone`, html fragment (string) for a clic-zone triggering actual edition
- */
-
-
-showInlineEditionForm = cw.utils.deprecatedFunction(
-    '[3.9] this is now unused by reledit (see cw.reledit.js)',
-    function showInlineEditionForm(eid, rtype, divid) {
-        jQuery('#' + divid).hide();
-        jQuery('#' + divid + '-value').hide();
-        jQuery('#' + divid + '-form').show();
-    }
-);
-
-hideInlineEdit = cw.utils.deprecatedFunction(
-    '[3.9] this is now unused by reledit (see cw.reledit.js)',
-    function hideInlineEdit(eid, rtype, divid) {
-        jQuery('#appMsg').hide();
-        jQuery('div.errorMessage').remove();
-        jQuery('#' + divid).show();
-        jQuery('#' + divid + '-value').show();
-        jQuery('#' + divid + '-form').hide();
-    }
-);
-
-
-inlineValidateRelationFormOptions = cw.utils.deprecatedFunction(
-    '[3.9] this is now unused by reledit (see cw.reledit.js)',
-    function inlineValidateRelationFormOptions(rtype, eid, divid, options) {
-        try {
-            var form = cw.getNode(divid + '-form');
-            var relname = rtype + ':' + eid;
-            var newtarget = jQuery('[name=' + relname + ']').val();
-            var zipped = cw.utils.formContents(form);
-            var args = ajaxFuncArgs('validate_form', null, 'apply', zipped[0], zipped[1]);
-            var d = loadRemote(JSON_BASE_URL, args, 'POST');
-        } catch(ex) {
-            return false;
-        }
-        d.addCallback(function(result, req) {
-            execFormValidationResponse(rtype, eid, divid, options, result);
-        });
-        return false;
-    });
-
-execFormValidationResponse = cw.utils.deprecatedFunction(
-    '[3.9] this is now unused by reledit (see cw.reledit.js)',
-    function execFormValidationResponse(rtype, eid, divid, options, result) {
-        options = $.extend({onsuccess: noop,
-                            onfailure: noop
-                           }, options);
-        if (handleFormValidationResponse(divid + '-form', options.onsucess , options.onfailure, result)) {
-            if (options.reload) {
-                document.location.reload();
-            } else {
-                var args = {
-                    fname: 'reledit_form',
-                    rtype: rtype,
-                    role: options.role,
-                    eid: eid,
-                    divid: divid,
-                    reload: options.reload,
-                    vid: options.vid,
-                    default_value: options.default_value,
-                    landing_zone: options.lzone
-                };
-                jQuery('#' + divid + '-reledit').parent().loadxhtml(JSON_BASE_URL, args, 'post');
-            }
-        }
-});
-
-
-/**
- * .. function:: loadInlineEditionFormOptions(eid, rtype, divid, options)
- *
- * inline edition
- */
-loadInlineEditionFormOptions = cw.utils.deprecatedFunction(
-  '[3.9] this is now unused by reledit (see cw.reledit.js) ',
-  function loadInlineEditionFormOptions(eid, rtype, divid, options) {
-    var args = {
-        fname: 'reledit_form',
-        rtype: rtype,
-        role: options.role,
-        eid: eid,
-        divid: divid,
-        reload: options.reload,
-        vid: options.vid,
-        default_value: options.default_value,
-        landing_zone: options.lzone,
-        callback: function() {
-            showInlineEditionForm(eid, rtype, divid);
-        }
-    };
-    jQuery('#' + divid + '-reledit').parent().loadxhtml(JSON_BASE_URL, args, 'post');
-});
-
-
-inlineValidateRelationForm = cw.utils.deprecatedFunction(
-    '[3.9] inlineValidateRelationForm() function is deprecated, use inlineValidateRelationFormOptions instead',
-    function(rtype, role, eid, divid, reload, vid, default_value, lzone, onsucess, onfailure) {
-        try {
-            var form = cw.getNode(divid + '-form');
-            var relname = rtype + ':' + eid;
-            var newtarget = jQuery('[name=' + relname + ']').val();
-            var zipped = cw.utils.formContents(form);
-            var d = asyncRemoteExec('validate_form', 'apply', zipped[0], zipped[1]);
-        } catch(ex) {
-            return false;
-        }
-        d.addCallback(function(result, req) {
-        var options = {role : role,
-                       reload: reload,
-                       vid: vid,
-                       default_value: default_value,
-                       lzone: lzone,
-                       onsucess: onsucess || $.noop,
-                       onfailure: onfailure || $.noop
-                      };
-            execFormValidationResponse(rtype, eid, divid, options);
-        });
-        return false;
-    }
-);
-
-loadInlineEditionForm = cw.utils.deprecatedFunction(
-    '[3.9] loadInlineEditionForm() function is deprecated, use loadInlineEditionFormOptions instead',
-    function(eid, rtype, role, divid, reload, vid, default_value, lzone) {
-        var args = {
-            fname: 'reledit_form',
-            rtype: rtype,
-            role: role,
-            eid: eid,
-            divid: divid,
-            reload: reload,
-            vid: vid,
-            default_value: default_value,
-            landing_zone: lzone,
-            callback: function() {
-                showInlineEditionForm(eid, rtype, divid);
-            }
-        };
-        jQuery('#' + divid + '-reledit').parent().loadxhtml(JSON_BASE_URL, args, 'post');
-    }
-);
--- a/web/data/cubicweb.form.css	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.form.css	Wed Oct 13 08:37:21 2010 +0200
@@ -229,6 +229,6 @@
   margin: 1em 1em 0px 0px;
   border-width: 1px;
   border-style: solid;
-  border-color: %(buttonBorderColor)s %(actionBoxTitleBgColor)s %(actionBoxTitleBgColor)s %(buttonBorderColor)s;
+  border-color: %(buttonBorderColor)s %(incontextBoxBodyBgColor)s %(incontextBoxBodyBgColor)s %(buttonBorderColor)s;
   background: %(buttonBgColor)s %(buttonBgImg)s;
 }
--- a/web/data/cubicweb.htmlhelpers.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.htmlhelpers.js	Wed Oct 13 08:37:21 2010 +0200
@@ -1,3 +1,14 @@
+/* in CW 3.10, we should move these functions in this namespace */
+cw.htmlhelpers = new Namespace('cw.htmlhelpers');
+
+jQuery.extend(cw.htmlhelpers, {
+    popupLoginBox: function(loginboxid, focusid) {
+        $('#'+loginboxid).toggleClass('hidden');
+        jQuery('#' + focusid +':visible').focus();
+    }
+});
+
+
 /**
  * .. function:: baseuri()
  *
@@ -97,10 +108,11 @@
  * toggles visibility of login popup div
  */
 // XXX used exactly ONCE in basecomponents
-function popupLoginBox() {
-    $('#popupLoginBox').toggleClass('hidden');
-    jQuery('#__login:visible').focus();
-}
+popupLoginBox = cw.utils.deprecatedFunction(
+    function() {
+        $('#popupLoginBox').toggleClass('hidden');
+        jQuery('#__login:visible').focus();
+});
 
 /**
  * .. function getElementsMatching(tagName, properties, \/* optional \*\/ parent)
--- a/web/data/cubicweb.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.js	Wed Oct 13 08:37:21 2010 +0200
@@ -6,6 +6,15 @@
 cw = new Namespace('cw');
 
 jQuery.extend(cw, {
+    cubes: new Namespace('cubes'),
+    /* provide a removeEventListener / detachEvent definition to
+     * to bypass a jQuery 1.4.2 bug when unbind() is called on a
+     * plain JS object and not a DOM node.
+     * see http://dev.jquery.com/ticket/6184 for more details
+     */
+    removeEventListener: function() {},
+    detachEvent: function() {},
+
     log: function () {
         var args = [];
         for (var i = 0; i < arguments.length; i++) {
@@ -299,6 +308,17 @@
     },
 
     /**
+     * .. function:: difference(lst1, lst2)
+     *
+     * returns a list containing all elements in `lst1` that are not
+     * in `lst2`.
+     */
+    difference: function(lst1, lst2) {
+        return jQuery.grep(lst1, function(elt, i) {
+            return jQuery.inArray(elt, lst2) == -1;
+        });
+    },
+    /**
      * .. function:: domid(string)
      *
      * return a valid DOM id from a string (should also be usable in jQuery
@@ -415,22 +435,17 @@
 }
 
 // XXX avoid crashes / backward compat
-CubicWeb = {
+CubicWeb = cw;
+
+jQuery.extend(cw, {
     require: cw.utils.deprecatedFunction(
         '[3.9] CubicWeb.require() is not used anymore',
         function(module) {}),
     provide: cw.utils.deprecatedFunction(
         '[3.9] CubicWeb.provide() is not used anymore',
         function(module) {})
-};
+});
 
 jQuery(document).ready(function() {
-    jQuery(CubicWeb).trigger('server-response', [false, document]);
-    jQuery(cw).trigger('server-response', [false, document]);
+    $(cw).trigger('server-response', [false, document]);
 });
-
-// XXX as of 2010-04-07, no known cube uses this
-jQuery(CubicWeb).bind('ajax-loaded', function() {
-    log('[3.7] "ajax-loaded" event is deprecated, use "server-response" instead');
-    jQuery(cw).trigger('server-response', [false, document]);
-});
--- a/web/data/cubicweb.login.css	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.login.css	Wed Oct 13 08:37:21 2010 +0200
@@ -5,20 +5,20 @@
  *  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
  */
 
-div#popupLoginBox {
+div.popupLoginBox {
   position: absolute;
   z-index: 400;
   right: 0px;
   width: 26em;
   padding: 0px 1px 1px;
-  background: %(listingBorderColor)s; 
+  background: %(listingBorderColor)s;
 }
 
-div#popupLoginBox label{
+div.popupLoginBox label{
   font-weight: bold;
 }
 
-div#popupLoginBox div#loginContent {
+div.popupLoginBox div.loginContent {
   background: #e6e4ce;
   padding: 5px 3px 4px;
 }
@@ -30,7 +30,7 @@
   margin-left: -14em;
   width: 28em;
   background: #fff;
-  border: 2px solid %(actionBoxTitleBgColor)s;
+  border: 2px solid %(incontextBoxBodyBgColor)s;
   padding-bottom: 0.5em;
   text-align: center;
 }
@@ -40,7 +40,7 @@
   font-size: 140%;
 }
 
-div#loginTitle {
+div.loginTitle {
   color: #fff;
   font-weight: bold;
   font-size: 140%;
@@ -49,18 +49,19 @@
   background: %(headerBgColor)s url("banner.png") repeat-x top left;
 }
 
-div#loginBox div#loginContent form {
+div#loginBox div.loginContent form {
   padding-top: 1em;
   width: 90%;
   margin: auto;
 }
 
-#popupLoginBox table td {
+
+.popupLoginBox table td {
   padding: 0px 3px;
   white-space: nowrap;
 }
 
-#loginContent table {
+.loginContent table {
   padding: 0px 0.5em;
   margin: auto;
 }
@@ -74,17 +75,20 @@
   margin-top: 0.6em;
  }
 
-#loginContent input.data {
+.loginContent input.data {
   width: 12em;
 }
 
+/* This is seriously debatable
+   These buttons render much more clearly as standard/default buttons
+ */
 .loginButton {
   border: 1px solid #edecd2;
-  border-color: #edecd2 %(actionBoxTitleBgColor)s %(actionBoxTitleBgColor)s  #edecd2;
+  border-color: #edecd2 %(incontextBoxBodyBgColor)s %(incontextBoxBodyBgColor)s  #edecd2;
   margin: 2px 0px 0px;
   background: #f0eff0 url("gradient-grey-up.png") left top repeat-x;
 }
 
-#loginContent .formButtonBar {
+.loginContent .formButtonBar {
   float: right;
 }
--- a/web/data/cubicweb.old.css	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.old.css	Wed Oct 13 08:37:21 2010 +0200
@@ -22,7 +22,8 @@
   font-family: Verdana, sans-serif;
 }
 
-h1 {
+h1,
+.vtitle {
   font-size: 188%;
   margin: 0.2em 0px 0.3em;
   border-bottom: 1px solid #000;
@@ -228,6 +229,7 @@
 table#header {
   background: #ff7700 url("banner.png") left top repeat-x;
   text-align: left;
+  width: 100%;
 }
 
 table#header td {
@@ -235,17 +237,22 @@
 }
 
 table#header a {
-color: #000;
+  color: #000;
+}
+
+table#header td#headtext {
+  float: left;
+}
+
+table#header td#header-right {
+  padding-top: 1em;
+  float: right;
 }
 
 span#appliName {
- font-weight: bold;
- color: #000;
- white-space: nowrap;
-}
-
-table#header td#headtext {
-  width: 100%;
+  font-weight: bold;
+  color: #000;
+  white-space: nowrap;
 }
 
 /* FIXME appear with 4px width in IE6 */
@@ -254,10 +261,6 @@
 }
 
 /* Popup on login box and userActionBox */
-div.popupWrapper{
- position:relative;
- z-index:100;
-}
 
 div.popup {
   position: absolute;
@@ -314,18 +317,23 @@
 div#rqlinput {
   border: 1px solid #cfceb7;
   margin-bottom: 8px;
-  padding: 3px;
+  padding: 1px;
   background: #cfceb7;
+  width: 100%;
+}
+
+input#rql {
+  width: 99%;
 }
 
-input#rql{
-  width: 95%;
+input.rqlsubmit{
+  display: block;
+  width: 20px;
+  height: 20px;
+  background: %(buttonBgColor)s url("go.png") 50% 50% no-repeat;
+  vertical-align: bottom;
 }
-
-/* boxes */
-div.navboxes {
- margin-top: 8px;
-}
+/* old boxes, deprecated */
 
 div.boxFrame {
   width: 100%;
@@ -335,25 +343,17 @@
   padding-top: 0px;
   padding-bottom: 0.2em;
   font: bold 100% Georgia;
-  overflow: hidden;
   color: #fff;
   background: #ff9900 url("search.png") left bottom repeat-x;
 }
 
-div.searchBoxFrame div.boxTitle,
-div.greyBoxFrame div.boxTitle {
-  background: #cfceb7;
-}
-
 div.boxTitle span,
 div.sideBoxTitle span {
   padding: 0px 5px;
   white-space: nowrap;
 }
 
-div.sideBoxTitle span,
-div.searchBoxFrame div.boxTitle span,
-div.greyBoxFrame div.boxTitle span {
+div.sideBoxTitle span {
   color: #222211;
 }
 
@@ -367,85 +367,6 @@
   border-top: none;
 }
 
-ul.boxListing {
-  margin: 0px;
-  padding: 0px 3px;
-}
-
-ul.boxListing li,
-ul.boxListing ul li {
-  display: inline;
-  margin: 0px;
-  padding: 0px;
-  background-image: none;
-}
-
-ul.boxListing ul {
-  margin: 0px 0px 0px 7px;
-  padding: 1px 3px;
-}
-
-ul.boxListing a {
-  color: #000;
-  display: block;
-  padding: 1px 9px 1px 3px;
-}
-
-ul.boxListing .selected {
-  color: #FF4500;
-  font-weight: bold;
-}
-
-ul.boxListing a.boxBookmark:hover,
-ul.boxListing a:hover,
-ul.boxListing ul li a:hover {
-  text-decoration: none;
-  background: #eeedd9;
-  color: #111100;
-}
-
-ul.boxListing a.boxMenu:hover {
-                                background: #eeedd9 url(puce_down.png) no-repeat scroll 98% 6px;
-                                cursor:pointer;
-                                border-top:medium none;
-                                }
-a.boxMenu {
-  background: transparent url("puce_down.png") 98% 6px no-repeat;
-  display: block;
-  padding: 1px 9px 1px 3px;
-}
-
-
-a.popupMenu {
-  background: transparent url("puce_down_black.png") 2% 6px no-repeat;
-  padding-left: 2em;
-}
-
-ul.boxListing ul li a:hover {
-  background: #eeedd9  url("bullet_orange.png") 0% 6px no-repeat;
-}
-
-a.boxMenu:hover {
-  background: #eeedd9 url("puce_down.png") 98% 6px no-repeat;
-  cursor: pointer;
-}
-
-ul.boxListing a.boxBookmark {
-  padding-left: 3px;
-  background-image:none;
-  background:#fff;
-}
-
-ul.boxListing ul li a {
-  background: #fff url("bullet_orange.png") 0% 6px no-repeat;
-  padding: 1px 3px 0px 10px;
-}
-
-div.searchBoxFrame div.boxContent {
-  padding: 4px 4px 3px;
-  background: #f0eff0 url("gradient-grey-up.png") left top repeat-x;
-}
-
 div.shadow{
   height: 14px;
   background: url("shadow.gif") no-repeat top right;
@@ -485,16 +406,164 @@
   padding-right: 1em;
 }
 
-input.rqlsubmit{
-  background: #fffff8 url("go.png") 50% 50% no-repeat;
-  width: 20px;
-  height: 20px;
-  margin: 0px;
+/* boxes */
+
+div.navboxes {
+  padding-top: 0.5em;
+}
+
+div.boxTitle {
+  overflow: hidden;
+  font-weight: bold;
+}
+
+div.boxTitle span {
+  padding: 0px 0.5em;
+  white-space: nowrap;
+}
+
+div.boxBody {
+  padding: 3px 3px;
+  border-top: none;
+  background-color: %(leftrightBoxBodyBgColor)s;
+}
+
+div.boxBody a {
+  color: %(leftrightBoxBodyColor)s;
+}
+
+div.boxBody a:hover {
+  text-decoration: none;
+  cursor: pointer;
+  background-color: %(leftrightBoxBodyHoverBgColor)s;
+}
+
+/* boxes contextual customization */
+
+.contextFreeBox div.boxTitle {
+  background: %(contextFreeBoxTitleBg)s;
+  color: %(contextFreeBoxTitleColor)s;
+}
+
+.contextualBox div.boxTitle {
+  background: %(contextualBoxTitleBg)s;
+  color: %(contextualBoxTitleColor)s;
+}
+
+.primaryRight div.boxTitle {
+  background: %(incontextBoxTitleBg)s;
+  color: %(incontextBoxTitleColor)s;
+}
+
+.primaryRight div.boxBody {
+  padding: 0.2em 5px;
+  background: %(incontextBoxBodyBgColor)s;
+}
+
+.primaryRight div.boxBody a {
+  color: %(incontextBoxBodyColor)s;
+}
+
+.primaryRight div.boxBody a:hover {
+  background-color: %(incontextBoxBodyHoverBgColor)s;
+}
+
+.primaryRight div.boxFooter {
+  margin-bottom: 1em;
+}
+
+#navColumnLeft div.boxFooter, #navColumnRight div.boxFooter{
+  height: 14px;
+  background: url("shadow.gif") no-repeat top right;
+}
+
+/* boxes lists and menus */
+
+ul.boxListing {
+  margin: 0;
+  padding: 0;
 }
 
-input#norql{
-  width:13em;
-  margin-right: 2px;
+ul.boxListing ul {
+  padding: 1px 3px;
+}
+
+ul.boxListing a {
+  color: %(defaultColor)s;
+  display: block;
+  padding: 1px 3px;
+}
+
+ul.boxListing li {
+  margin: 0px;
+  padding: 0px;
+  background-image: none;
+}
+
+ul.boxListing ul li {
+  margin: 0px;
+  padding-left: 1em;
+}
+
+ul.boxListing ul li a {
+  padding-left: 10px;
+  background-image: url("bullet_orange.png");
+  background-repeat: no-repeat;
+  background-position: 0 6px;
+}
+
+ul.boxListing .selected {
+  color: %(aColor)s;
+  font-weight: bold;
+}
+
+ul.boxListing a.boxMenu:hover {
+  border-top: medium none;
+  background: %(leftrightBoxBodyHoverBgColor)s;
+}
+
+a.boxMenu,
+ul.boxListing a.boxMenu{
+  display: block;
+  padding: 1px 3px;
+  background: transparent %(bulletDownImg)s;
+}
+
+ul.boxListing a.boxMenu:hover {
+  border-top: medium none;
+  background: %(leftrightBoxBodyHoverBgColor)s %(bulletDownImg)s;
+}
+
+a.boxMenu:hover {
+  cursor: pointer;
+}
+
+a.popupMenu {
+  background: transparent url("puce_down_black.png") 2% 6px no-repeat;
+  padding-left: 2em;
+}
+
+
+/* custom boxes */
+
+.search_box div.boxBody {
+  padding: 4px 4px 3px;
+  background: #f0eff0 url("gradient-grey-up.png") left top repeat-x;
+}
+
+.bookmarks_box ul.boxListing div a {
+  background: #fff;
+  display: inline;
+  padding: 0;
+}
+
+.download_box div.boxTitle {
+  background : #8fbc8f !important;
+}
+
+.download_box div.boxBody {
+  background : #eefed9;
+  vertical-align: center;
 }
 
 /* user actions menu */
@@ -514,20 +583,6 @@
   padding-right: 2em;
 }
 
-/* download box XXX move to its own file? */
-div.downloadBoxTitle{
- background : #8FBC8F;
- font-weight: bold;
-}
-
-div.downloadBox{
- font-weight: bold;
-}
-
-div.downloadBox div.sideBoxBody{
- background : #EEFED9;
-}
-
 /**************/
 /* navigation */
 /**************/
@@ -770,6 +825,13 @@
   margin-bottom: 0.2em; /* because vertical-align doesn't seems to have any effect */
 }
 
+table.ajaxEditRelationTable{
+  margin-bottom: 0.5em;
+}
+table.ajaxEditRelationTable td.entity{
+  padding-left: 0.5em;
+}
+
 /***************************************/
 /* error view (views/management.py)    */
 /***************************************/
@@ -884,3 +946,12 @@
 .releditForm {
  display:none;
 }
+
+/********************************/
+/* overwite other css here      */
+/********************************/
+
+.ui-menu li.ui-menu-item {
+  /* remove background image (orange bullet) for autocomplete suggestions */
+  background-image: none;
+}
--- a/web/data/cubicweb.reledit.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.reledit.js	Wed Oct 13 08:37:21 2010 +0200
@@ -52,7 +52,7 @@
                 return;
             }
         }
-        jQuery('#'+params.divid+'-reledit').parent().loadxhtml(JSON_BASE_URL, params, 'post');
+        jQuery('#'+params.divid+'-reledit').loadxhtml(JSON_BASE_URL, params, 'post');
         jQuery(cw).trigger('reledit-reloaded', params);
     },
 
@@ -68,7 +68,7 @@
                     pageid: pageid,
                     eid: eid, divid: divid, formid: formid,
                     reload: reload, vid: vid};
-        var d = jQuery('#'+divid+'-reledit').parent().loadxhtml(JSON_BASE_URL, args, 'post');
+        var d = jQuery('#'+divid+'-reledit').loadxhtml(JSON_BASE_URL, args, 'post');
         d.addCallback(function () {cw.reledit.showInlineEditionForm(divid);});
     }
 });
--- a/web/data/cubicweb.tableview.css	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.tableview.css	Wed Oct 13 08:37:21 2010 +0200
@@ -6,7 +6,7 @@
   font-weight: bold;
   background: #ebe8d9 url("button.png") repeat-x;
   padding: 0.3em;
-  border-bottom: 1px solid %(actionBoxTitleBgColor)s;
+  border-bottom: 1px solid %(incontextBoxBodyBgColor)s;
   text-align: left;
 }
 
--- a/web/data/cubicweb.widgets.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/cubicweb.widgets.js	Wed Oct 13 08:37:21 2010 +0200
@@ -56,67 +56,247 @@
     return jQuery.get(url, data, callback, 'json');
 }
 
+
+(function ($) {
+    var defaultSettings = {
+        initialvalue: '',
+        multiple: false,
+        mustMatch: false,
+        delay: 50,
+        limit: 50
+    };
+    function split(val) { return val.split( /\s*,\s*/ ); }
+    function extractLast(term) { return split(term).pop(); }
+    function allButLast(val) {
+        var terms = split(val);
+        terms.pop();
+        return terms;
+    }
+
+    var methods = {
+        __init__: function(suggestions, options) {
+            return this.each(function() {
+                // here, `this` refers to the DOM element (e.g. input) being wrapped
+                // by cwautomplete plugin
+                var instanceData = $(this).data('cwautocomplete');
+                if (instanceData) {
+                    // already initialized
+                    return;
+                }
+                var settings = $.extend({}, defaultSettings, options);
+                instanceData =  {
+                    initialvalue: settings.initialvalue,
+                    userInput: this,
+                    hiddenInput: null
+                };
+                var hiHandlers = methods.hiddenInputHandlers;
+                $(this).data('cwautocomplete', instanceData);
+                $.ui.autocomplete.prototype._search = methods.search;
+                if (settings.multiple) {
+                    $.ui.autocomplete.filter = methods.multiple.makeFilter(this);
+                    $(this).bind({
+                        autocompleteselect: methods.multiple.select,
+                        autocompletefocus: methods.multiple.focus,
+                        keydown: methods.multiple.keydown
+                        });
+                }
+                // XXX katia we dont need it if minLength == 0, but by setting minLength = 0
+                // we probably break the backward compatibility
+                $(this).bind('blur', methods.blur);
+                if ($.isArray(suggestions)) { // precomputed list of suggestions
+                    settings.source = hiHandlers.checkSuggestionsDataFormat(instanceData, suggestions);
+                } else { // url to call each time something is typed
+                    settings.source = function(request, response) {
+                        var d = loadRemote(suggestions, {q: request.term, limit: settings.limit}, 'POST');
+                        d.addCallback(function (suggestions) {
+                            suggestions = hiHandlers.checkSuggestionsDataFormat(instanceData, suggestions);
+                            response(suggestions);
+                            if((suggestions.length) == 0){
+                                methods.resetValues(instanceData);
+                            }
+                        });
+                    };
+                }
+                $(this).autocomplete(settings);
+                if (settings.mustMatch) {
+                    $(this).keypress(methods.ensureExactMatch);
+                }
+            });
+        },
+
+        multiple: {
+            focus: function() {
+                // prevent value inserted on focus
+                return false;
+            },
+            select: function(event, ui) {
+                var terms = allButLast(this.value);
+                // add the selected item
+                terms.push(ui.item.value);
+                // add placeholder to get the comma-and-space at the end
+                terms.push("");
+                this.value = terms.join( ", " );
+                return false;
+            },
+            keydown: function(evt) {
+                if ($(this).data('autocomplete').menu.active && evt.keyCode == $.ui.keyCode.TAB) {
+                    evt.preventDefault();
+                }
+            },
+            makeFilter: function(userInput) {
+                return function(array, term) {
+                    // remove already entered terms from suggestion list
+                    array = cw.utils.difference(array, allButLast(userInput.value));
+                    var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
+                    return $.grep( array, function(value) {
+                        return matcher.test( value.label || value.value || value );
+                    });
+                };
+            }
+        },
+        blur: function(evt){
+            var instanceData = $(this).data('cwautocomplete');
+            if($(instanceData.userInput).val().strip().length==0){
+                methods.resetValues(instanceData);
+            }
+        },
+        search: function(value) {
+            this.element.addClass("ui-autocomplete-loading");
+            if (this.options.multiple) {
+                value = extractLast(value);
+            }
+            this.source({term: value}, this.response);
+        },
+        ensureExactMatch: function(evt) {
+            var instanceData = $(this).data('cwautocomplete');
+            if (evt.keyCode == $.ui.keyCode.ENTER || evt.keyCode == $.ui.keyCode.TAB) {
+                var validChoices = $.map($('ul.ui-autocomplete li'),
+                                         function(li) {return $(li).text();});
+                if ($.inArray($(instanceData.userInput).val(), validChoices) == -1) {
+                    $(instanceData.userInput).val('');
+                    $(instanceData.hiddenInput).val(instanceData.initialvalue || '');
+                }
+            }
+        },
+        resetValues: function(instanceData){
+            $(instanceData.userInput).val('');
+            $(instanceData.hiddenInput).val('');
+        },
+
+
+        hiddenInputHandlers: {
+            /**
+             * `hiddenInputHandlers` defines all methods specific to handle the
+             * hidden input created along the standard text input.
+             * An hiddenInput is necessary when displayed suggestions are
+             * different from actual values to submit.
+             * Imagine an autocompletion widget to choose among a list of CWusers.
+             * Suggestions would be the list of logins, but actual values would
+             * be the corresponding eids.
+             * To handle such cases, suggestions list should be a list of JS objects
+             * with two `label` and `value` properties.
+             **/
+            suggestionSelected: function(evt, ui) {
+                var instanceData = $(this).data('cwautocomplete');
+                instanceData.hiddenInput.value = ui.item.value;
+                instanceData.value = ui.item.label;
+                return false; // stop propagation
+            },
+
+            suggestionFocusChanged: function(evt, ui) {
+                var instanceData = $(this).data('cwautocomplete');
+                instanceData.userInput.value = ui.item.label;
+                return false; // stop propagation
+            },
+
+            needsHiddenInput: function(suggestions) {
+                return suggestions[0].label !== undefined;
+            },
+            initializeHiddenInput: function(instanceData) {
+                var userInput = instanceData.userInput;
+                var hiddenInput = INPUT({
+                    type: "hidden",
+                    name: userInput.name,
+                    // XXX katia : this must be handeled in .SuggestField widget, but
+                    // it seems not to be used anymore
+                    value: $(userInput).attr('cubicweb:initialvalue') || userInput.value
+                });
+                $(userInput).removeAttr('name').after(hiddenInput);
+                instanceData.hiddenInput = hiddenInput;
+                $(userInput).bind({
+                    autocompleteselect: methods.hiddenInputHandlers.suggestionSelected,
+                    autocompletefocus: methods.hiddenInputHandlers.suggestionFocusChanged
+                });
+            },
+
+            /*
+             * internal convenience function: old jquery plugin accepted to be fed
+             * with a list of couples (value, label). The new (jquery-ui) autocomplete
+             * plugin expects a list of objects with "value" and "label" properties.
+             *
+             * This function converts the old format to the new one.
+             */
+            checkSuggestionsDataFormat: function(instanceData, suggestions) {
+                // check for old (value, label) format
+                if ($.isArray(suggestions) && suggestions.length &&
+                    $.isArray(suggestions[0])){
+                    if (suggestions[0].length == 2) {
+                        cw.log('[3.10] autocomplete init func should return {label,value} dicts instead of lists');
+                        suggestions = $.map(suggestions, function(sugg) {
+                                            return {value: sugg[0], label: sugg[1]};
+                                            });
+                    } else {
+                        if(suggestions[0].length == 1){
+                            suggestions = $.map(suggestions, function(sugg) {
+                                return {value: sugg[0], label: sugg[0]};
+                            });
+                        }
+                    }
+                }
+                var hiHandlers = methods.hiddenInputHandlers;
+                if (suggestions.length && hiHandlers.needsHiddenInput(suggestions)
+                    && !instanceData.hiddenInput) {
+                    hiHandlers.initializeHiddenInput(instanceData);
+                    hiHandlers.fixUserInputInitialValue(instanceData, suggestions);
+                }
+                // otherwise, assume data shape is correct
+                return suggestions;
+            },
+
+            fixUserInputInitialValue: function(instanceData, suggestions) {
+                // called when the data is loaded to reset the correct displayed
+                // value in the visible input field (typically replacing an eid
+                // by a displayable value)
+                var curvalue = instanceData.userInput.value;
+                if (!curvalue) {
+                    return;
+                }
+                for (var i=0, length=suggestions.length; i < length; i++) {
+                    var sugg = suggestions[i];
+                    if (sugg.value == curvalue) {
+                        instanceData.userInput.value = sugg.label;
+                        return;
+                    }
+                }
+            }
+        }
+    };
+
+    $.fn.cwautocomplete = function(data, options) {
+        return methods.__init__.apply(this, [data, options]);
+    };
+})(jQuery);
+
+
 Widgets.SuggestField = defclass('SuggestField', null, {
     __init__: function(node, options) {
-        var multi = node.getAttribute('cubicweb:multi') || "no";
         options = options || {};
+        var multi = node.getAttribute('cubicweb:multi');
         options.multiple = (multi == "yes") ? true: false;
-        var dataurl = node.getAttribute('cubicweb:dataurl');
-        var method = postJSON;
-        if (options.method == 'get') {
-            method = function(url, data, callback) {
-                // We can't rely on jQuery.getJSON because the server
-                // might set the Content-Type's response header to 'text/plain'
-                jQuery.get(url, data, function(response) {
-                    callback(cw.evalJSON(response));
-                });
-            };
-        }
-        var self = this; // closure
-        method(dataurl, null, function(data) {
-            // in case we received a list of couple, we assume that the first
-            // element is the real value to be sent, and the second one is the
-            // value to be displayed
-            if (data.length && data[0].length == 2) {
-                options.formatItem = function(row) {
-                    return row[1];
-                };
-                self.hideRealValue(node);
-                self.setCurrentValue(node, data);
-            }
-            jQuery(node).autocomplete(data, options);
+        var d = loadRemote(node.getAttribute('cubicweb:dataurl'));
+        d.addCallback(function(data) {
+            $(node).cwautocomplete(data, options);
         });
-    },
-
-    hideRealValue: function(node) {
-        var hidden = INPUT({
-            'type': "hidden",
-            'name': node.name,
-            'value': node.value
-        });
-        node.parentNode.appendChild(hidden);
-        // remove 'name' attribute from visible input so that it is not submitted
-        // and set correct value in the corresponding hidden field
-        jQuery(node).removeAttr('name').bind('result', function(_, row, _) {
-            hidden.value = row[0];
-        });
-    },
-
-    setCurrentValue: function(node, data) {
-        // called when the data is loaded to reset the correct displayed
-        // value in the visible input field (typically replacing an eid
-        // by a displayable value)
-        var curvalue = node.value;
-        if (!node.value) {
-            return;
-        }
-        for (var i = 0, length = data.length; i < length; i++) {
-            var row = data[i];
-            if (row[0] == curvalue) {
-                node.value = row[1];
-                return;
-            }
-        }
     }
 });
 
@@ -124,84 +304,35 @@
 
     __init__: function(node) {
         Widgets.SuggestField.__init__(this, node, {
-            method: 'get'
+            method: 'get' // XXX
         });
     }
 
 });
 
 Widgets.RestrictedSuggestField = defclass('RestrictedSuggestField', [Widgets.SuggestField], {
-
     __init__: function(node) {
         Widgets.SuggestField.__init__(this, node, {
             mustMatch: true
         });
     }
+});
 
-});
 //remote version of RestrictedSuggestField
 Widgets.LazySuggestField = defclass('LazySuggestField', [Widgets.SuggestField], {
     __init__: function(node, options) {
         var self = this;
-        var multi = "no";
         options = options || {};
-        options.max = 50;
         options.delay = 50;
-        options.cacheLength = 0;
-        options.mustMatch = true;
         // multiple selection not supported yet (still need to formalize correctly
         // initial values / display values)
         var initialvalue = cw.evalJSON(node.getAttribute('cubicweb:initialvalue') || 'null');
         if (!initialvalue) {
             initialvalue = node.value;
         }
-        options = jQuery.extend({
-            dataType: 'json',
-            multiple: (multi == "yes") ? true: false,
-            parse: this.parseResult
-        },
-        options);
-        var dataurl = node.getAttribute('cubicweb:dataurl');
-        // remove 'name' from original input and add the hidden one that will
-        // store the actual value
-        var hidden = INPUT({
-            'type': "hidden",
-            'name': node.name,
-            'value': initialvalue
-        });
-        node.parentNode.appendChild(hidden);
-        jQuery(node).bind('result', {
-            hinput: hidden,
-            input: node
-        },
-        self.hideRealValue).removeAttr('name').autocomplete(dataurl, options);
-    },
-
-    hideRealValue: function(evt, data, value) {
-        if (!value) {
-            value = "";
-        }
-        evt.data.hinput.value = value;
-    },
-
-    /*
-     * @param data: a list of couple (value, label) to fill the suggestion list,
-     *              (returned by CW through AJAX)
-     */
-    parseResult: function(data) {
-        var parsed = [];
-        for (var i = 0; i < data.length; i++) {
-            var value = '' + data[i][0]; // a string is required later by jquery.autocomplete.js
-            var label = data[i][1];
-            parsed[parsed.length] = {
-                data: [label],
-                value: value,
-                result: label
-            };
-        };
-        return parsed;
+        options.initialvalue = initialvalue;
+        Widgets.SuggestField.__init__(this, node, options);
     }
-
 });
 
 /**
Binary file web/data/images/ui-icons_222222_256x240.png has changed
Binary file web/data/images/ui-icons_228ef1_256x240.png has changed
Binary file web/data/images/ui-icons_ef8c08_256x240.png has changed
Binary file web/data/images/ui-icons_ffd27a_256x240.png has changed
Binary file web/data/images/ui-icons_ffffff_256x240.png has changed
Binary file web/data/incontextBoxHeader.png has changed
--- a/web/data/jquery.autocomplete.css	Wed Oct 13 08:37:09 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-.ac_results {
-	padding: 0px;
-	border: 1px solid black;
-	background-color: white;
-	overflow: hidden;
-	z-index: 99999;
-}
-
-.ac_results ul {
-	width: 100%;
-	list-style-position: outside;
-	list-style: none;
-	padding: 0;
-	margin: 0;
-}
-
-.ac_results li {
-	margin: 0px;
-	padding: 2px 5px;
-	cursor: default;
-	display: block;
-	/* 
-	if width will be 100% horizontal scrollbar will apear 
-	when scroll mode will be used
-	*/
-	/*width: 100%;*/
-	font: menu;
-	font-size: 12px;
-	/* 
-	it is very important, if line-height not setted or setted 
-	in relative units scroll will be broken in firefox
-	*/
-	line-height: 16px;
-	overflow: hidden;
-        background-image: none;
-        padding: 0px 0px 1px 1px;
-}
-
-.ac_loading {
-	background: white url('indicator.gif') right center no-repeat;
-}
-
-.ac_odd {
-	background-color: #eee;
-}
-
-.ac_over {
-	background-color: #0A246A;
-	color: white;
-}
--- a/web/data/jquery.autocomplete.js	Wed Oct 13 08:37:09 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-/*
- * jQuery Autocomplete plugin 1.1
- *
- * Copyright (c) 2010 Jörn Zaefferer
- *
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- *
- * Revision: $Id: jquery.autocomplete.js 15 2010-08-22 10:30:27Z joern.zaefferer $
- */;(function($){$.fn.extend({autocomplete:function(urlOrData,options){var isUrl=typeof urlOrData=="string";options=$.extend({},$.Autocompleter.defaults,{url:isUrl?urlOrData:null,data:isUrl?null:urlOrData,delay:isUrl?$.Autocompleter.defaults.delay:10,max:options&&!options.scroll?10:150},options);options.highlight=options.highlight||function(value){return value;};options.formatMatch=options.formatMatch||options.formatItem;return this.each(function(){new $.Autocompleter(this,options);});},result:function(handler){return this.bind("result",handler);},search:function(handler){return this.trigger("search",[handler]);},flushCache:function(){return this.trigger("flushCache");},setOptions:function(options){return this.trigger("setOptions",[options]);},unautocomplete:function(){return this.trigger("unautocomplete");}});$.Autocompleter=function(input,options){var KEY={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var $input=$(input).attr("autocomplete","off").addClass(options.inputClass);var timeout;var previousValue="";var cache=$.Autocompleter.Cache(options);var hasFocus=0;var lastKeyPressCode;var config={mouseDownOnSelect:false};var select=$.Autocompleter.Select(options,input,selectCurrent,config);var blockSubmit;$.browser.opera&&$(input.form).bind("submit.autocomplete",function(){if(blockSubmit){blockSubmit=false;return false;}});$input.bind(($.browser.opera?"keypress":"keydown")+".autocomplete",function(event){hasFocus=1;lastKeyPressCode=event.keyCode;switch(event.keyCode){case KEY.UP:event.preventDefault();if(select.visible()){select.prev();}else{onChange(0,true);}break;case KEY.DOWN:event.preventDefault();if(select.visible()){select.next();}else{onChange(0,true);}break;case KEY.PAGEUP:event.preventDefault();if(select.visible()){select.pageUp();}else{onChange(0,true);}break;case KEY.PAGEDOWN:event.preventDefault();if(select.visible()){select.pageDown();}else{onChange(0,true);}break;case options.multiple&&$.trim(options.multipleSeparator)==","&&KEY.COMMA:case KEY.TAB:case KEY.RETURN:if(selectCurrent()){event.preventDefault();blockSubmit=true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout=setTimeout(onChange,options.delay);break;}}).focus(function(){hasFocus++;}).blur(function(){hasFocus=0;if(!config.mouseDownOnSelect){hideResults();}}).click(function(){if(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind("search",function(){var fn=(arguments.length>1)?arguments[1]:null;function findValueCallback(q,data){var result;if(data&&data.length){for(var i=0;i<data.length;i++){if(data[i].result.toLowerCase()==q.toLowerCase()){result=data[i];break;}}}if(typeof fn=="function")fn(result);else $input.trigger("result",result&&[result.data,result.value]);}$.each(trimWords($input.val()),function(i,value){request(value,findValueCallback,findValueCallback);});}).bind("flushCache",function(){cache.flush();}).bind("setOptions",function(){$.extend(options,arguments[1]);if("data"in arguments[1])cache.populate();}).bind("unautocomplete",function(){select.unbind();$input.unbind();$(input.form).unbind(".autocomplete");});function selectCurrent(){var selected=select.selected();if(!selected)return false;var v=selected.result;previousValue=v;if(options.multiple){var words=trimWords($input.val());if(words.length>1){var seperator=options.multipleSeparator.length;var cursorAt=$(input).selection().start;var wordAt,progress=0;$.each(words,function(i,word){progress+=word.length;if(cursorAt<=progress){wordAt=i;return false;}progress+=seperator;});words[wordAt]=v;v=words.join(options.multipleSeparator);}v+=options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger("result",[selected.data,selected.value]);return true;}function onChange(crap,skipPrevCheck){if(lastKeyPressCode==KEY.DEL){select.hide();return;}var currentValue=$input.val();if(!skipPrevCheck&&currentValue==previousValue)return;previousValue=currentValue;currentValue=lastWord(currentValue);if(currentValue.length>=options.minChars){$input.addClass(options.loadingClass);if(!options.matchCase)currentValue=currentValue.toLowerCase();request(currentValue,receiveData,hideResultsNow);}else{stopLoading();select.hide();}};function trimWords(value){if(!value)return[""];if(!options.multiple)return[$.trim(value)];return $.map(value.split(options.multipleSeparator),function(word){return $.trim(value).length?$.trim(word):null;});}function lastWord(value){if(!options.multiple)return value;var words=trimWords(value);if(words.length==1)return words[0];var cursorAt=$(input).selection().start;if(cursorAt==value.length){words=trimWords(value)}else{words=trimWords(value.replace(value.substring(cursorAt),""));}return words[words.length-1];}function autoFill(q,sValue){if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLowerCase())&&lastKeyPressCode!=KEY.BACKSPACE){$input.val($input.val()+sValue.substring(lastWord(previousValue).length));$(input).selection(previousValue.length,previousValue.length+sValue.length);}};function hideResults(){clearTimeout(timeout);timeout=setTimeout(hideResultsNow,200);};function hideResultsNow(){var wasVisible=select.visible();select.hide();clearTimeout(timeout);stopLoading();if(options.mustMatch){$input.search(function(result){if(!result){if(options.multiple){var words=trimWords($input.val()).slice(0,-1);$input.val(words.join(options.multipleSeparator)+(words.length?options.multipleSeparator:""));}else{$input.val("");$input.trigger("result",null);}}});}};function receiveData(q,data){if(data&&data.length&&hasFocus){stopLoading();select.display(data,q);autoFill(q,data[0].value);select.show();}else{hideResultsNow();}};function request(term,success,failure){if(!options.matchCase)term=term.toLowerCase();var data=cache.load(term);if(data&&data.length){success(term,data);}else if((typeof options.url=="string")&&(options.url.length>0)){var extraParams={timestamp:+new Date()};$.each(options.extraParams,function(key,param){extraParams[key]=typeof param=="function"?param():param;});$.ajax({mode:"abort",port:"autocomplete"+input.name,dataType:options.dataType,url:options.url,data:$.extend({q:lastWord(term),limit:options.max},extraParams),success:function(data){var parsed=options.parse&&options.parse(data)||parse(data);cache.add(term,parsed);success(term,parsed);}});}else{select.emptyList();failure(term);}};function parse(data){var parsed=[];var rows=data.split("\n");for(var i=0;i<rows.length;i++){var row=$.trim(rows[i]);if(row){row=row.split("|");parsed[parsed.length]={data:row,value:row[0],result:options.formatResult&&options.formatResult(row,row[0])||row[0]};}}return parsed;};function stopLoading(){$input.removeClass(options.loadingClass);};};$.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(row){return row[0];},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(value,term){return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>");},scroll:true,scrollHeight:180};$.Autocompleter.Cache=function(options){var data={};var length=0;function matchSubset(s,sub){if(!options.matchCase)s=s.toLowerCase();var i=s.indexOf(sub);if(options.matchContains=="word"){i=s.toLowerCase().search("\\b"+sub.toLowerCase());}if(i==-1)return false;return i==0||options.matchContains;};function add(q,value){if(length>options.cacheLength){flush();}if(!data[q]){length++;}data[q]=value;}function populate(){if(!options.data)return false;var stMatchSets={},nullData=0;if(!options.url)options.cacheLength=1;stMatchSets[""]=[];for(var i=0,ol=options.data.length;i<ol;i++){var rawValue=options.data[i];rawValue=(typeof rawValue=="string")?[rawValue]:rawValue;var value=options.formatMatch(rawValue,i+1,options.data.length);if(value===false)continue;var firstChar=value.charAt(0).toLowerCase();if(!stMatchSets[firstChar])stMatchSets[firstChar]=[];var row={value:value,data:rawValue,result:options.formatResult&&options.formatResult(rawValue)||value};stMatchSets[firstChar].push(row);if(nullData++<options.max){stMatchSets[""].push(row);}};$.each(stMatchSets,function(i,value){options.cacheLength++;add(i,value);});}setTimeout(populate,25);function flush(){data={};length=0;}return{flush:flush,add:add,populate:populate,load:function(q){if(!options.cacheLength||!length)return null;if(!options.url&&options.matchContains){var csub=[];for(var k in data){if(k.length>0){var c=data[k];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub.push(x);}});}}return csub;}else
-if(data[q]){return data[q];}else
-if(options.matchSubset){for(var i=q.length-1;i>=options.minChars;i--){var c=data[q.substr(0,i)];if(c){var csub=[];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub[csub.length]=x;}});return csub;}}}return null;}};};$.Autocompleter.Select=function(options,input,select,config){var CLASSES={ACTIVE:"ac_over"};var listItems,active=-1,data,term="",needsInit=true,element,list;function init(){if(!needsInit)return;element=$("<div/>").hide().addClass(options.resultsClass).css("position","absolute").appendTo(document.body);list=$("<ul/>").appendTo(element).mouseover(function(event){if(target(event).nodeName&&target(event).nodeName.toUpperCase()=='LI'){active=$("li",list).removeClass(CLASSES.ACTIVE).index(target(event));$(target(event)).addClass(CLASSES.ACTIVE);}}).click(function(event){$(target(event)).addClass(CLASSES.ACTIVE);select();input.focus();return false;}).mousedown(function(){config.mouseDownOnSelect=true;}).mouseup(function(){config.mouseDownOnSelect=false;});if(options.width>0)element.css("width",options.width);needsInit=false;}function target(event){var element=event.target;while(element&&element.tagName.toUpperCase()!="LI")element=element.parentNode;if(!element)return[];return element;}function moveSelect(step){listItems.slice(active,active+1).removeClass(CLASSES.ACTIVE);movePosition(step);var activeItem=listItems.slice(active,active+1).addClass(CLASSES.ACTIVE);if(options.scroll){var offset=0;listItems.slice(0,active).each(function(){offset+=this.offsetHeight;});if((offset+activeItem[0].offsetHeight-list.scrollTop())>list[0].clientHeight){list.scrollTop(offset+activeItem[0].offsetHeight-list.innerHeight());}else if(offset<list.scrollTop()){list.scrollTop(offset);}}};function movePosition(step){active+=step;if(active<0){active=listItems.size()-1;}else if(active>=listItems.size()){active=0;}}function limitNumberOfItems(available){return options.max&&options.max<available?options.max:available;}function fillList(){list.empty();var max=limitNumberOfItems(data.length);for(var i=0;i<max;i++){if(!data[i])continue;var formatted=options.formatItem(data[i].data,i+1,max,data[i].value,term);if(formatted===false)continue;var li=$("<li/>").html(options.highlight(formatted,term)).addClass(i%2==0?"ac_even":"ac_odd").appendTo(list)[0];$.data(li,"ac_data",data[i]);}listItems=list.find("li");if(options.selectFirst){listItems.slice(0,1).addClass(CLASSES.ACTIVE);active=0;}if($.fn.bgiframe)list.bgiframe();}return{display:function(d,q){init();data=d;term=q;fillList();},next:function(){moveSelect(1);},prev:function(){moveSelect(-1);},pageUp:function(){if(active!=0&&active-8<0){moveSelect(-active);}else{moveSelect(-8);}},pageDown:function(){if(active!=listItems.size()-1&&active+8>listItems.size()){moveSelect(listItems.size()-1-active);}else{moveSelect(8);}},hide:function(){element&&element.hide();listItems&&listItems.removeClass(CLASSES.ACTIVE);active=-1;},visible:function(){return element&&element.is(":visible");},current:function(){return this.visible()&&(listItems.filter("."+CLASSES.ACTIVE)[0]||options.selectFirst&&listItems[0]);},show:function(){var offset=$(input).offset();element.css({width:typeof options.width=="string"||options.width>0?options.width:$(input).width(),top:offset.top+input.offsetHeight,left:offset.left}).show();if(options.scroll){list.scrollTop(0);list.css({maxHeight:options.scrollHeight,overflow:'auto'});if($.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var listHeight=0;listItems.each(function(){listHeight+=this.offsetHeight;});var scrollbarsVisible=listHeight>options.scrollHeight;list.css('height',scrollbarsVisible?options.scrollHeight:listHeight);if(!scrollbarsVisible){listItems.width(list.width()-parseInt(listItems.css("padding-left"))-parseInt(listItems.css("padding-right")));}}}},selected:function(){var selected=listItems&&listItems.filter("."+CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);return selected&&selected.length&&$.data(selected[0],"ac_data");},emptyList:function(){list&&list.empty();},unbind:function(){element&&element.remove();}};};$.fn.selection=function(start,end){if(start!==undefined){return this.each(function(){if(this.createTextRange){var selRange=this.createTextRange();if(end===undefined||start==end){selRange.move("character",start);selRange.select();}else{selRange.collapse(true);selRange.moveStart("character",start);selRange.moveEnd("character",end);selRange.select();}}else if(this.setSelectionRange){this.setSelectionRange(start,end);}else if(this.selectionStart){this.selectionStart=start;this.selectionEnd=end;}});}var field=this[0];if(field.createTextRange){var range=document.selection.createRange(),orig=field.value,teststring="<->",textLength=range.text.length;range.text=teststring;var caretAt=field.value.indexOf(teststring);field.value=orig;this.selection(caretAt,caretAt+textLength);return{start:caretAt,end:caretAt+textLength}}else if(field.selectionStart!==undefined){return{start:field.selectionStart,end:field.selectionEnd}}};})(jQuery);
\ No newline at end of file
--- a/web/data/jquery.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/jquery.js	Wed Oct 13 08:37:21 2010 +0200
@@ -1,19 +1,6240 @@
-/*
- * jQuery JavaScript Library v1.3.2
+/*!
+ * jQuery JavaScript Library v1.4.2
  * http://jquery.com/
  *
- * Copyright (c) 2010 John Resig
- * Dual licensed under the MIT and GPL licenses.
- * http://docs.jquery.com/License
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
  *
- * Date: 2010-02-19 17:34:21 -0500 (Thu, 19 Feb 2010)
- * Revision: 6246
+ * Date: Sat Feb 13 22:33:48 2010 -0500
  */
-(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context );
+	},
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// Use the correct document accordingly with window argument (sandbox)
+	document = window.document,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// A simple way to check for HTML strings or ID strings
+	// (both of which we optimize for)
+	quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
+	// Is it a simple selector
+	isSimple = /^.[^:#\[\.,]*$/,
+
+	// Check if a string has a non-whitespace character in it
+	rnotwhite = /\S/,
+
+	// Used for trimming whitespace
+	rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+	// Keep a UserAgent string for use with jQuery.browser
+	userAgent = navigator.userAgent,
+
+	// For matching the engine and version of the browser
+	browserMatch,
+	
+	// Has the ready events already been bound?
+	readyBound = false,
+	
+	// The functions to execute on DOM ready
+	readyList = [],
+
+	// The ready event handler
+	DOMContentLoaded,
+
+	// Save a reference to some core methods
+	toString = Object.prototype.toString,
+	hasOwnProperty = Object.prototype.hasOwnProperty,
+	push = Array.prototype.push,
+	slice = Array.prototype.slice,
+	indexOf = Array.prototype.indexOf;
+
+jQuery.fn = jQuery.prototype = {
+	init: function( selector, context ) {
+		var match, elem, ret, doc;
+
+		// Handle $(""), $(null), or $(undefined)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+		
+		// The body element only exists once, optimize finding it
+		if ( selector === "body" && !context ) {
+			this.context = document;
+			this[0] = document.body;
+			this.selector = "body";
+			this.length = 1;
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			// Are we dealing with HTML string or an ID?
+			match = quickExpr.exec( selector );
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					doc = (context ? context.ownerDocument || context : document);
+
+					// If a single string is passed in and it's a single tag
+					// just do a createElement and skip the rest
+					ret = rsingleTag.exec( selector );
+
+					if ( ret ) {
+						if ( jQuery.isPlainObject( context ) ) {
+							selector = [ document.createElement( ret[1] ) ];
+							jQuery.fn.attr.call( selector, context, true );
+
+						} else {
+							selector = [ doc.createElement( ret[1] ) ];
+						}
+
+					} else {
+						ret = buildFragment( [ match[1] ], [ doc ] );
+						selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+					}
+					
+					return jQuery.merge( this, selector );
+					
+				// HANDLE: $("#id")
+				} else {
+					elem = document.getElementById( match[2] );
+
+					if ( elem ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $("TAG")
+			} else if ( !context && /^\w+$/.test( selector ) ) {
+				this.selector = selector;
+				this.context = document;
+				selector = document.getElementsByTagName( selector );
+				return jQuery.merge( this, selector );
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return (context || rootjQuery).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return jQuery( context ).find( selector );
+			}
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if (selector.selector !== undefined) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The current version of jQuery being used
+	jquery: "1.4.2",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	toArray: function() {
+		return slice.call( this, 0 );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems, name, selector ) {
+		// Build a new jQuery matched element set
+		var ret = jQuery();
+
+		if ( jQuery.isArray( elems ) ) {
+			push.apply( ret, elems );
+		
+		} else {
+			jQuery.merge( ret, elems );
+		}
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		ret.context = this.context;
+
+		if ( name === "find" ) {
+			ret.selector = this.selector + (this.selector ? " " : "") + selector;
+		} else if ( name ) {
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
+		}
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+	
+	ready: function( fn ) {
+		// Attach the listeners
+		jQuery.bindReady();
+
+		// If the DOM is already ready
+		if ( jQuery.isReady ) {
+			// Execute the function immediately
+			fn.call( document, jQuery );
+
+		// Otherwise, remember the function for later
+		} else if ( readyList ) {
+			// Add the function to the wait list
+			readyList.push( fn );
+		}
+
+		return this;
+	},
+	
+	eq: function( i ) {
+		return i === -1 ?
+			this.slice( i ) :
+			this.slice( i, +i + 1 );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ),
+			"slice", slice.call(arguments).join(",") );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+	
+	end: function() {
+		return this.prevObject || jQuery(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	// copy reference to target object
+	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging object literal values or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+					var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+						: jQuery.isArray(copy) ? [] : {};
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		window.$ = _$;
+
+		if ( deep ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+	
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+	
+	// Handle when the DOM is ready
+	ready: function() {
+		// Make sure that the DOM is not already loaded
+		if ( !jQuery.isReady ) {
+			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+			if ( !document.body ) {
+				return setTimeout( jQuery.ready, 13 );
+			}
+
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+
+			// If there are functions bound, to execute
+			if ( readyList ) {
+				// Execute all of them
+				var fn, i = 0;
+				while ( (fn = readyList[ i++ ]) ) {
+					fn.call( document, jQuery );
+				}
+
+				// Reset the list of functions
+				readyList = null;
+			}
+
+			// Trigger any bound ready events
+			if ( jQuery.fn.triggerHandler ) {
+				jQuery( document ).triggerHandler( "ready" );
+			}
+		}
+	},
+	
+	bindReady: function() {
+		if ( readyBound ) {
+			return;
+		}
+
+		readyBound = true;
+
+		// Catch cases where $(document).ready() is called after the
+		// browser event has already occurred.
+		if ( document.readyState === "complete" ) {
+			return jQuery.ready();
+		}
+
+		// Mozilla, Opera and webkit nightlies currently support this event
+		if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+			
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", jQuery.ready, false );
+
+		// If IE event model is used
+		} else if ( document.attachEvent ) {
+			// ensure firing before onload,
+			// maybe late but safe also for iframes
+			document.attachEvent("onreadystatechange", DOMContentLoaded);
+			
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", jQuery.ready );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var toplevel = false;
+
+			try {
+				toplevel = window.frameElement == null;
+			} catch(e) {}
+
+			if ( document.documentElement.doScroll && toplevel ) {
+				doScrollCheck();
+			}
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return toString.call(obj) === "[object Function]";
+	},
+
+	isArray: function( obj ) {
+		return toString.call(obj) === "[object Array]";
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+			return false;
+		}
+		
+		// Not own constructor property must be Object
+		if ( obj.constructor
+			&& !hasOwnProperty.call(obj, "constructor")
+			&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+			return false;
+		}
+		
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+	
+		var key;
+		for ( key in obj ) {}
+		
+		return key === undefined || hasOwnProperty.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		for ( var name in obj ) {
+			return false;
+		}
+		return true;
+	},
+	
+	error: function( msg ) {
+		throw msg;
+	},
+	
+	parseJSON: function( data ) {
+		if ( typeof data !== "string" || !data ) {
+			return null;
+		}
+
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
+		data = jQuery.trim( data );
+		
+		// Make sure the incoming data is actual JSON
+		// Logic borrowed from http://json.org/json2.js
+		if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+			.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+			.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+			// Try to use the native JSON parser first
+			return window.JSON && window.JSON.parse ?
+				window.JSON.parse( data ) :
+				(new Function("return " + data))();
+
+		} else {
+			jQuery.error( "Invalid JSON: " + data );
+		}
+	},
+
+	noop: function() {},
+
+	// Evalulates a script in a global context
+	globalEval: function( data ) {
+		if ( data && rnotwhite.test(data) ) {
+			// Inspired by code by Andrea Giammarchi
+			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+			var head = document.getElementsByTagName("head")[0] || document.documentElement,
+				script = document.createElement("script");
+
+			script.type = "text/javascript";
+
+			if ( jQuery.support.scriptEval ) {
+				script.appendChild( document.createTextNode( data ) );
+			} else {
+				script.text = data;
+			}
+
+			// Use insertBefore instead of appendChild to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709).
+			head.insertBefore( script, head.firstChild );
+			head.removeChild( script );
+		}
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+	},
+
+	// args is for internal usage only
+	each: function( object, callback, args ) {
+		var name, i = 0,
+			length = object.length,
+			isObj = length === undefined || jQuery.isFunction(object);
+
+		if ( args ) {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.apply( object[ name ], args ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.apply( object[ i++ ], args ) === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( var value = object[0];
+					i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+			}
+		}
+
+		return object;
+	},
+
+	trim: function( text ) {
+		return (text || "").replace( rtrim, "" );
+	},
+
+	// results is for internal usage only
+	makeArray: function( array, results ) {
+		var ret = results || [];
+
+		if ( array != null ) {
+			// The window, strings (and functions) also have 'length'
+			// The extra typeof function check is to prevent crashes
+			// in Safari 2 (See: #3039)
+			if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+				push.call( ret, array );
+			} else {
+				jQuery.merge( ret, array );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, array ) {
+		if ( array.indexOf ) {
+			return array.indexOf( elem );
+		}
+
+		for ( var i = 0, length = array.length; i < length; i++ ) {
+			if ( array[ i ] === elem ) {
+				return i;
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var i = first.length, j = 0;
+
+		if ( typeof second.length === "number" ) {
+			for ( var l = second.length; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+		
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var ret = [];
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			if ( !inv !== !callback( elems[ i ], i ) ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var ret = [], value;
+
+		// Go through the array, translating each of the items to their
+		// new value (or values).
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			value = callback( elems[ i ], i, arg );
+
+			if ( value != null ) {
+				ret[ ret.length ] = value;
+			}
+		}
+
+		return ret.concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	proxy: function( fn, proxy, thisObject ) {
+		if ( arguments.length === 2 ) {
+			if ( typeof proxy === "string" ) {
+				thisObject = fn;
+				fn = thisObject[ proxy ];
+				proxy = undefined;
+
+			} else if ( proxy && !jQuery.isFunction( proxy ) ) {
+				thisObject = proxy;
+				proxy = undefined;
+			}
+		}
+
+		if ( !proxy && fn ) {
+			proxy = function() {
+				return fn.apply( thisObject || this, arguments );
+			};
+		}
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		if ( fn ) {
+			proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+		}
+
+		// So proxy can be declared as an argument
+		return proxy;
+	},
+
+	// Use of jQuery.browser is frowned upon.
+	// More details: http://docs.jquery.com/Utilities/jQuery.browser
+	uaMatch: function( ua ) {
+		ua = ua.toLowerCase();
+
+		var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+			/(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+			/(msie) ([\w.]+)/.exec( ua ) ||
+			!/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+		  	[];
+
+		return { browser: match[1] || "", version: match[2] || "0" };
+	},
+
+	browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+	jQuery.browser[ browserMatch.browser ] = true;
+	jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+	jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+	jQuery.inArray = function( elem, array ) {
+		return indexOf.call( array, elem );
+	};
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+	DOMContentLoaded = function() {
+		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+		jQuery.ready();
+	};
+
+} else if ( document.attachEvent ) {
+	DOMContentLoaded = function() {
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( document.readyState === "complete" ) {
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
+			jQuery.ready();
+		}
+	};
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+	if ( jQuery.isReady ) {
+		return;
+	}
+
+	try {
+		// If IE is used, use the trick by Diego Perini
+		// http://javascript.nwbox.com/IEContentLoaded/
+		document.documentElement.doScroll("left");
+	} catch( error ) {
+		setTimeout( doScrollCheck, 1 );
+		return;
+	}
+
+	// and execute any waiting functions
+	jQuery.ready();
+}
+
+function evalScript( i, elem ) {
+	if ( elem.src ) {
+		jQuery.ajax({
+			url: elem.src,
+			async: false,
+			dataType: "script"
+		});
+	} else {
+		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+	}
+
+	if ( elem.parentNode ) {
+		elem.parentNode.removeChild( elem );
+	}
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+	var length = elems.length;
+	
+	// Setting many attributes
+	if ( typeof key === "object" ) {
+		for ( var k in key ) {
+			access( elems, k, key[k], exec, fn, value );
+		}
+		return elems;
+	}
+	
+	// Setting one attribute
+	if ( value !== undefined ) {
+		// Optionally, function values get executed if exec is true
+		exec = !pass && exec && jQuery.isFunction(value);
+		
+		for ( var i = 0; i < length; i++ ) {
+			fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+		}
+		
+		return elems;
+	}
+	
+	// Getting an attribute
+	return length ? fn( elems[0], key ) : undefined;
+}
+
+function now() {
+	return (new Date).getTime();
+}
+(function() {
+
+	jQuery.support = {};
+
+	var root = document.documentElement,
+		script = document.createElement("script"),
+		div = document.createElement("div"),
+		id = "script" + now();
+
+	div.style.display = "none";
+	div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+	var all = div.getElementsByTagName("*"),
+		a = div.getElementsByTagName("a")[0];
+
+	// Can't get basic test support
+	if ( !all || !all.length || !a ) {
+		return;
+	}
+
+	jQuery.support = {
+		// IE strips leading whitespace when .innerHTML is used
+		leadingWhitespace: div.firstChild.nodeType === 3,
+
+		// Make sure that tbody elements aren't automatically inserted
+		// IE will insert them into empty tables
+		tbody: !div.getElementsByTagName("tbody").length,
+
+		// Make sure that link elements get serialized correctly by innerHTML
+		// This requires a wrapper element in IE
+		htmlSerialize: !!div.getElementsByTagName("link").length,
+
+		// Get the style information from getAttribute
+		// (IE uses .cssText insted)
+		style: /red/.test( a.getAttribute("style") ),
+
+		// Make sure that URLs aren't manipulated
+		// (IE normalizes it by default)
+		hrefNormalized: a.getAttribute("href") === "/a",
+
+		// Make sure that element opacity exists
+		// (IE uses filter instead)
+		// Use a regex to work around a WebKit issue. See #5145
+		opacity: /^0.55$/.test( a.style.opacity ),
+
+		// Verify style float existence
+		// (IE uses styleFloat instead of cssFloat)
+		cssFloat: !!a.style.cssFloat,
+
+		// Make sure that if no value is specified for a checkbox
+		// that it defaults to "on".
+		// (WebKit defaults to "" instead)
+		checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+		// Make sure that a selected-by-default option has a working selected property.
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+		optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
+
+		parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
+
+		// Will be defined later
+		deleteExpando: true,
+		checkClone: false,
+		scriptEval: false,
+		noCloneEvent: true,
+		boxModel: null
+	};
+
+	script.type = "text/javascript";
+	try {
+		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+	} catch(e) {}
+
+	root.insertBefore( script, root.firstChild );
+
+	// Make sure that the execution of code works by injecting a script
+	// tag with appendChild/createTextNode
+	// (IE doesn't support this, fails, and uses .text instead)
+	if ( window[ id ] ) {
+		jQuery.support.scriptEval = true;
+		delete window[ id ];
+	}
+
+	// Test to see if it's possible to delete an expando from an element
+	// Fails in Internet Explorer
+	try {
+		delete script.test;
+	
+	} catch(e) {
+		jQuery.support.deleteExpando = false;
+	}
+
+	root.removeChild( script );
+
+	if ( div.attachEvent && div.fireEvent ) {
+		div.attachEvent("onclick", function click() {
+			// Cloning a node shouldn't copy over any
+			// bound event handlers (IE does this)
+			jQuery.support.noCloneEvent = false;
+			div.detachEvent("onclick", click);
+		});
+		div.cloneNode(true).fireEvent("onclick");
+	}
+
+	div = document.createElement("div");
+	div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+	var fragment = document.createDocumentFragment();
+	fragment.appendChild( div.firstChild );
+
+	// WebKit doesn't clone checked state correctly in fragments
+	jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+	// Figure out if the W3C box model works as expected
+	// document.body must exist before we can do this
+	jQuery(function() {
+		var div = document.createElement("div");
+		div.style.width = div.style.paddingLeft = "1px";
+
+		document.body.appendChild( div );
+		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+		document.body.removeChild( div ).style.display = 'none';
+
+		div = null;
+	});
+
+	// Technique from Juriy Zaytsev
+	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+	var eventSupported = function( eventName ) { 
+		var el = document.createElement("div"); 
+		eventName = "on" + eventName; 
+
+		var isSupported = (eventName in el); 
+		if ( !isSupported ) { 
+			el.setAttribute(eventName, "return;"); 
+			isSupported = typeof el[eventName] === "function"; 
+		} 
+		el = null; 
+
+		return isSupported; 
+	};
+	
+	jQuery.support.submitBubbles = eventSupported("submit");
+	jQuery.support.changeBubbles = eventSupported("change");
+
+	// release memory in IE
+	root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+	"for": "htmlFor",
+	"class": "className",
+	readonly: "readOnly",
+	maxlength: "maxLength",
+	cellspacing: "cellSpacing",
+	rowspan: "rowSpan",
+	colspan: "colSpan",
+	tabindex: "tabIndex",
+	usemap: "useMap",
+	frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+	cache: {},
+	
+	expando:expando,
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"embed": true,
+		"object": true,
+		"applet": true
+	},
+
+	data: function( elem, name, data ) {
+		if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+		if ( !id && typeof name === "string" && data === undefined ) {
+			return null;
+		}
+
+		// Compute a unique ID for the element
+		if ( !id ) { 
+			id = ++uuid;
+		}
+
+		// Avoid generating a new cache unless none exists and we
+		// want to manipulate it.
+		if ( typeof name === "object" ) {
+			elem[ expando ] = id;
+			thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+
+		} else if ( !cache[ id ] ) {
+			elem[ expando ] = id;
+			cache[ id ] = {};
+		}
+
+		thisCache = cache[ id ];
+
+		// Prevent overriding the named cache with undefined values
+		if ( data !== undefined ) {
+			thisCache[ name ] = data;
+		}
+
+		return typeof name === "string" ? thisCache[ name ] : thisCache;
+	},
+
+	removeData: function( elem, name ) {
+		if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+		// If we want to remove a specific section of the element's data
+		if ( name ) {
+			if ( thisCache ) {
+				// Remove the section of cache data
+				delete thisCache[ name ];
+
+				// If we've removed all the data, remove the element's cache
+				if ( jQuery.isEmptyObject(thisCache) ) {
+					jQuery.removeData( elem );
+				}
+			}
+
+		// Otherwise, we want to remove all of the element's data
+		} else {
+			if ( jQuery.support.deleteExpando ) {
+				delete elem[ jQuery.expando ];
+
+			} else if ( elem.removeAttribute ) {
+				elem.removeAttribute( jQuery.expando );
+			}
+
+			// Completely remove the data cache
+			delete cache[ id ];
+		}
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		if ( typeof key === "undefined" && this.length ) {
+			return jQuery.data( this[0] );
+
+		} else if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		var parts = key.split(".");
+		parts[1] = parts[1] ? "." + parts[1] : "";
+
+		if ( value === undefined ) {
+			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+			if ( data === undefined && this.length ) {
+				data = jQuery.data( this[0], key );
+			}
+			return data === undefined && parts[1] ?
+				this.data( parts[0] ) :
+				data;
+		} else {
+			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+				jQuery.data( this, key, value );
+			});
+		}
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		if ( !elem ) {
+			return;
+		}
+
+		type = (type || "fx") + "queue";
+		var q = jQuery.data( elem, type );
+
+		// Speed up dequeue by getting out quickly if this is just a lookup
+		if ( !data ) {
+			return q || [];
+		}
+
+		if ( !q || jQuery.isArray(data) ) {
+			q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+		} else {
+			q.push( data );
+		}
+
+		return q;
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+		}
+
+		if ( fn ) {
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift("inprogress");
+			}
+
+			fn.call(elem, function() {
+				jQuery.dequeue(elem, type);
+			});
+		}
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+		}
+
+		if ( data === undefined ) {
+			return jQuery.queue( this[0], type );
+		}
+		return this.each(function( i, elem ) {
+			var queue = jQuery.queue( this, type, data );
+
+			if ( type === "fx" && queue[0] !== "inprogress" ) {
+				jQuery.dequeue( this, type );
+			}
+		});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function() {
+			var elem = this;
+			setTimeout(function() {
+				jQuery.dequeue( elem, type );
+			}, time );
+		});
+	},
+
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	}
+});
+var rclass = /[\n\t]/g,
+	rspace = /\s+/,
+	rreturn = /\r/g,
+	rspecialurl = /href|src|style/,
+	rtype = /(button|input)/i,
+	rfocusable = /(button|input|object|select|textarea)/i,
+	rclickable = /^(a|area)$/i,
+	rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return access( this, name, value, true, jQuery.attr );
+	},
+
+	removeAttr: function( name, fn ) {
+		return this.each(function(){
+			jQuery.attr( this, name, "" );
+			if ( this.nodeType === 1 ) {
+				this.removeAttribute( name );
+			}
+		});
+	},
+
+	addClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.addClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( value && typeof value === "string" ) {
+			var classNames = (value || "").split( rspace );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 ) {
+					if ( !elem.className ) {
+						elem.className = value;
+
+					} else {
+						var className = " " + elem.className + " ", setClass = elem.className;
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+								setClass += " " + classNames[c];
+							}
+						}
+						elem.className = jQuery.trim( setClass );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.removeClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( (value && typeof value === "string") || value === undefined ) {
+			var classNames = (value || "").split(rspace);
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 && elem.className ) {
+					if ( value ) {
+						var className = (" " + elem.className + " ").replace(rclass, " ");
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							className = className.replace(" " + classNames[c] + " ", " ");
+						}
+						elem.className = jQuery.trim( className );
+
+					} else {
+						elem.className = "";
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value, isBool = typeof stateVal === "boolean";
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className, i = 0, self = jQuery(this),
+					state = stateVal,
+					classNames = value.split( rspace );
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space seperated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			} else if ( type === "undefined" || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery.data( this, "__className__", this.className );
+				}
+
+				// toggle whole className
+				this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ";
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		if ( value === undefined ) {
+			var elem = this[0];
+
+			if ( elem ) {
+				if ( jQuery.nodeName( elem, "option" ) ) {
+					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+				}
+
+				// We need to handle select boxes special
+				if ( jQuery.nodeName( elem, "select" ) ) {
+					var index = elem.selectedIndex,
+						values = [],
+						options = elem.options,
+						one = elem.type === "select-one";
+
+					// Nothing was selected
+					if ( index < 0 ) {
+						return null;
+					}
+
+					// Loop through all the selected options
+					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+						var option = options[ i ];
+
+						if ( option.selected ) {
+							// Get the specifc value for the option
+							value = jQuery(option).val();
+
+							// We don't need an array for one selects
+							if ( one ) {
+								return value;
+							}
+
+							// Multi-Selects return an array
+							values.push( value );
+						}
+					}
+
+					return values;
+				}
+
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+				if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+					return elem.getAttribute("value") === null ? "on" : elem.value;
+				}
+				
+
+				// Everything else, we just grab the value
+				return (elem.value || "").replace(rreturn, "");
+
+			}
+
+			return undefined;
+		}
+
+		var isFunction = jQuery.isFunction(value);
+
+		return this.each(function(i) {
+			var self = jQuery(this), val = value;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call(this, i, self.val());
+			}
+
+			// Typecast each time if the value is a Function and the appended
+			// value is therefore different each time.
+			if ( typeof val === "number" ) {
+				val += "";
+			}
+
+			if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+				this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+			} else if ( jQuery.nodeName( this, "select" ) ) {
+				var values = jQuery.makeArray(val);
+
+				jQuery( "option", this ).each(function() {
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+				});
+
+				if ( !values.length ) {
+					this.selectedIndex = -1;
+				}
+
+			} else {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	attrFn: {
+		val: true,
+		css: true,
+		html: true,
+		text: true,
+		data: true,
+		width: true,
+		height: true,
+		offset: true
+	},
+		
+	attr: function( elem, name, value, pass ) {
+		// don't set attributes on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return undefined;
+		}
+
+		if ( pass && name in jQuery.attrFn ) {
+			return jQuery(elem)[name](value);
+		}
+
+		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+			// Whether we are setting (or getting)
+			set = value !== undefined;
+
+		// Try to normalize/fix the name
+		name = notxml && jQuery.props[ name ] || name;
+
+		// Only do all the following if this is a node (faster for style)
+		if ( elem.nodeType === 1 ) {
+			// These attributes require special treatment
+			var special = rspecialurl.test( name );
+
+			// Safari mis-reports the default selected property of an option
+			// Accessing the parent's selectedIndex property fixes it
+			if ( name === "selected" && !jQuery.support.optSelected ) {
+				var parent = elem.parentNode;
+				if ( parent ) {
+					parent.selectedIndex;
+	
+					// Make sure that it also works with optgroups, see #5701
+					if ( parent.parentNode ) {
+						parent.parentNode.selectedIndex;
+					}
+				}
+			}
+
+			// If applicable, access the attribute via the DOM 0 way
+			if ( name in elem && notxml && !special ) {
+				if ( set ) {
+					// We can't allow the type property to be changed (since it causes problems in IE)
+					if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+						jQuery.error( "type property can't be changed" );
+					}
+
+					elem[ name ] = value;
+				}
+
+				// browsers index elements by id/name on forms, give priority to attributes.
+				if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+					return elem.getAttributeNode( name ).nodeValue;
+				}
+
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				if ( name === "tabIndex" ) {
+					var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+					return attributeNode && attributeNode.specified ?
+						attributeNode.value :
+						rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+							0 :
+							undefined;
+				}
+
+				return elem[ name ];
+			}
+
+			if ( !jQuery.support.style && notxml && name === "style" ) {
+				if ( set ) {
+					elem.style.cssText = "" + value;
+				}
+
+				return elem.style.cssText;
+			}
+
+			if ( set ) {
+				// convert the value to a string (all browsers do this but IE) see #1070
+				elem.setAttribute( name, "" + value );
+			}
+
+			var attr = !jQuery.support.hrefNormalized && notxml && special ?
+					// Some attributes require a special call on IE
+					elem.getAttribute( name, 2 ) :
+					elem.getAttribute( name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return attr === null ? undefined : attr;
+		}
+
+		// elem is actually elem.style ... set the style
+		// Using attr for specific style information is now deprecated. Use style instead.
+		return jQuery.style( elem, name, value );
+	}
+});
+var rnamespaces = /\.(.*)$/,
+	fcleanup = function( nm ) {
+		return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+			return "\\" + ch;
+		});
+	};
+
 /*
- * Sizzle CSS Selector Engine - v0.9.3
- *  Copyright 2010, The Dojo Foundation
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+	// Bind an event to an element
+	// Original by Dean Edwards
+	add: function( elem, types, handler, data ) {
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// For whatever reason, IE has trouble passing the window object
+		// around, causing it to be cloned in the process
+		if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+			elem = window;
+		}
+
+		var handleObjIn, handleObj;
+
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+		}
+
+		// Make sure that the function being executed has a unique ID
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure
+		var elemData = jQuery.data( elem );
+
+		// If no elemData is found then we must be trying to bind to one of the
+		// banned noData elements
+		if ( !elemData ) {
+			return;
+		}
+
+		var events = elemData.events = elemData.events || {},
+			eventHandle = elemData.handle, eventHandle;
+
+		if ( !eventHandle ) {
+			elemData.handle = eventHandle = function() {
+				// Handle the second event of a trigger and when
+				// an event is called after a page has unloaded
+				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+		}
+
+		// Add elem as a property of the handle function
+		// This is to prevent a memory leak with non-native events in IE.
+		eventHandle.elem = elem;
+
+		// Handle multiple events separated by a space
+		// jQuery(...).bind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		var type, i = 0, namespaces;
+
+		while ( (type = types[ i++ ]) ) {
+			handleObj = handleObjIn ?
+				jQuery.extend({}, handleObjIn) :
+				{ handler: handler, data: data };
+
+			// Namespaced event handlers
+			if ( type.indexOf(".") > -1 ) {
+				namespaces = type.split(".");
+				type = namespaces.shift();
+				handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+			} else {
+				namespaces = [];
+				handleObj.namespace = "";
+			}
+
+			handleObj.type = type;
+			handleObj.guid = handler.guid;
+
+			// Get the current list of functions bound to this event
+			var handlers = events[ type ],
+				special = jQuery.event.special[ type ] || {};
+
+			// Init the event handler queue
+			if ( !handlers ) {
+				handlers = events[ type ] = [];
+
+				// Check for a special event handler
+				// Only use addEventListener/attachEvent if the special
+				// events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+			
+			if ( special.add ) { 
+				special.add.call( elem, handleObj ); 
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add the function to the element's handler list
+			handlers.push( handleObj );
+
+			// Keep track of which events have been used, for global triggering
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	global: {},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, pos ) {
+		// don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+			elemData = jQuery.data( elem ),
+			events = elemData && elemData.events;
+
+		if ( !elemData || !events ) {
+			return;
+		}
+
+		// types is actually an event object here
+		if ( types && types.type ) {
+			handler = types.handler;
+			types = types.type;
+		}
+
+		// Unbind all events for the element
+		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+			types = types || "";
+
+			for ( type in events ) {
+				jQuery.event.remove( elem, type + types );
+			}
+
+			return;
+		}
+
+		// Handle multiple events separated by a space
+		// jQuery(...).unbind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		while ( (type = types[ i++ ]) ) {
+			origType = type;
+			handleObj = null;
+			all = type.indexOf(".") < 0;
+			namespaces = [];
+
+			if ( !all ) {
+				// Namespaced event handlers
+				namespaces = type.split(".");
+				type = namespaces.shift();
+
+				namespace = new RegExp("(^|\\.)" + 
+					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
+			}
+
+			eventType = events[ type ];
+
+			if ( !eventType ) {
+				continue;
+			}
+
+			if ( !handler ) {
+				for ( var j = 0; j < eventType.length; j++ ) {
+					handleObj = eventType[ j ];
+
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						jQuery.event.remove( elem, origType, handleObj.handler, j );
+						eventType.splice( j--, 1 );
+					}
+				}
+
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+
+			for ( var j = pos || 0; j < eventType.length; j++ ) {
+				handleObj = eventType[ j ];
+
+				if ( handler.guid === handleObj.guid ) {
+					// remove the given handler for the given type
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						if ( pos == null ) {
+							eventType.splice( j--, 1 );
+						}
+
+						if ( special.remove ) {
+							special.remove.call( elem, handleObj );
+						}
+					}
+
+					if ( pos != null ) {
+						break;
+					}
+				}
+			}
+
+			// remove generic event handler if no more handlers exist
+			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+					removeEvent( elem, type, elemData.handle );
+				}
+
+				ret = null;
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			var handle = elemData.handle;
+			if ( handle ) {
+				handle.elem = null;
+			}
+
+			delete elemData.events;
+			delete elemData.handle;
+
+			if ( jQuery.isEmptyObject( elemData ) ) {
+				jQuery.removeData( elem );
+			}
+		}
+	},
+
+	// bubbling is internal
+	trigger: function( event, data, elem /*, bubbling */ ) {
+		// Event object or event type
+		var type = event.type || event,
+			bubbling = arguments[3];
+
+		if ( !bubbling ) {
+			event = typeof event === "object" ?
+				// jQuery.Event object
+				event[expando] ? event :
+				// Object literal
+				jQuery.extend( jQuery.Event(type), event ) :
+				// Just the event type (string)
+				jQuery.Event(type);
+
+			if ( type.indexOf("!") >= 0 ) {
+				event.type = type = type.slice(0, -1);
+				event.exclusive = true;
+			}
+
+			// Handle a global trigger
+			if ( !elem ) {
+				// Don't bubble custom events when global (to avoid too much overhead)
+				event.stopPropagation();
+
+				// Only trigger if we've ever bound an event for it
+				if ( jQuery.event.global[ type ] ) {
+					jQuery.each( jQuery.cache, function() {
+						if ( this.events && this.events[type] ) {
+							jQuery.event.trigger( event, data, this.handle.elem );
+						}
+					});
+				}
+			}
+
+			// Handle triggering a single element
+
+			// don't do events on text and comment nodes
+			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+				return undefined;
+			}
+
+			// Clean up in case it is reused
+			event.result = undefined;
+			event.target = elem;
+
+			// Clone the incoming data, if any
+			data = jQuery.makeArray( data );
+			data.unshift( event );
+		}
+
+		event.currentTarget = elem;
+
+		// Trigger the event, it is assumed that "handle" is a function
+		var handle = jQuery.data( elem, "handle" );
+		if ( handle ) {
+			handle.apply( elem, data );
+		}
+
+		var parent = elem.parentNode || elem.ownerDocument;
+
+		// Trigger an inline bound script
+		try {
+			if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+				if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+					event.result = false;
+				}
+			}
+
+		// prevent IE from throwing an error for some elements with some event types, see #3533
+		} catch (e) {}
+
+		if ( !event.isPropagationStopped() && parent ) {
+			jQuery.event.trigger( event, data, parent, true );
+
+		} else if ( !event.isDefaultPrevented() ) {
+			var target = event.target, old,
+				isClick = jQuery.nodeName(target, "a") && type === "click",
+				special = jQuery.event.special[ type ] || {};
+
+			if ( (!special._default || special._default.call( elem, event ) === false) && 
+				!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+
+				try {
+					if ( target[ type ] ) {
+						// Make sure that we don't accidentally re-trigger the onFOO events
+						old = target[ "on" + type ];
+
+						if ( old ) {
+							target[ "on" + type ] = null;
+						}
+
+						jQuery.event.triggered = true;
+						target[ type ]();
+					}
+
+				// prevent IE from throwing an error for some elements with some event types, see #3533
+				} catch (e) {}
+
+				if ( old ) {
+					target[ "on" + type ] = old;
+				}
+
+				jQuery.event.triggered = false;
+			}
+		}
+	},
+
+	handle: function( event ) {
+		var all, handlers, namespaces, namespace, events;
+
+		event = arguments[0] = jQuery.event.fix( event || window.event );
+		event.currentTarget = this;
+
+		// Namespaced event handlers
+		all = event.type.indexOf(".") < 0 && !event.exclusive;
+
+		if ( !all ) {
+			namespaces = event.type.split(".");
+			event.type = namespaces.shift();
+			namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+		}
+
+		var events = jQuery.data(this, "events"), handlers = events[ event.type ];
+
+		if ( events && handlers ) {
+			// Clone the handlers to prevent manipulation
+			handlers = handlers.slice(0);
+
+			for ( var j = 0, l = handlers.length; j < l; j++ ) {
+				var handleObj = handlers[ j ];
+
+				// Filter the functions by class
+				if ( all || namespace.test( handleObj.namespace ) ) {
+					// Pass in a reference to the handler function itself
+					// So that we can later remove it
+					event.handler = handleObj.handler;
+					event.data = handleObj.data;
+					event.handleObj = handleObj;
+	
+					var ret = handleObj.handler.apply( this, arguments );
+
+					if ( ret !== undefined ) {
+						event.result = ret;
+						if ( ret === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+
+					if ( event.isImmediatePropagationStopped() ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+	fix: function( event ) {
+		if ( event[ expando ] ) {
+			return event;
+		}
+
+		// store a copy of the original event object
+		// and "clone" to set read-only properties
+		var originalEvent = event;
+		event = jQuery.Event( originalEvent );
+
+		for ( var i = this.props.length, prop; i; ) {
+			prop = this.props[ --i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Fix target property, if necessary
+		if ( !event.target ) {
+			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+		}
+
+		// check if target is a textnode (safari)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Add relatedTarget, if necessary
+		if ( !event.relatedTarget && event.fromElement ) {
+			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+		}
+
+		// Calculate pageX/Y if missing and clientX/Y available
+		if ( event.pageX == null && event.clientX != null ) {
+			var doc = document.documentElement, body = document.body;
+			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
+		}
+
+		// Add which for key events
+		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
+			event.which = event.charCode || event.keyCode;
+		}
+
+		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+		if ( !event.metaKey && event.ctrlKey ) {
+			event.metaKey = event.ctrlKey;
+		}
+
+		// Add which for click: 1 === left; 2 === middle; 3 === right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && event.button !== undefined ) {
+			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+		}
+
+		return event;
+	},
+
+	// Deprecated, use jQuery.guid instead
+	guid: 1E8,
+
+	// Deprecated, use jQuery.proxy instead
+	proxy: jQuery.proxy,
+
+	special: {
+		ready: {
+			// Make sure the ready event is setup
+			setup: jQuery.bindReady,
+			teardown: jQuery.noop
+		},
+
+		live: {
+			add: function( handleObj ) {
+				jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) ); 
+			},
+
+			remove: function( handleObj ) {
+				var remove = true,
+					type = handleObj.origType.replace(rnamespaces, "");
+				
+				jQuery.each( jQuery.data(this, "events").live || [], function() {
+					if ( type === this.origType.replace(rnamespaces, "") ) {
+						remove = false;
+						return false;
+					}
+				});
+
+				if ( remove ) {
+					jQuery.event.remove( this, handleObj.origType, liveHandler );
+				}
+			}
+
+		},
+
+		beforeunload: {
+			setup: function( data, namespaces, eventHandle ) {
+				// We only want to do this special case on windows
+				if ( this.setInterval ) {
+					this.onbeforeunload = eventHandle;
+				}
+
+				return false;
+			},
+			teardown: function( namespaces, eventHandle ) {
+				if ( this.onbeforeunload === eventHandle ) {
+					this.onbeforeunload = null;
+				}
+			}
+		}
+	}
+};
+
+var removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+	    elem.removeEventListener( type, handle, false );
+	} :
+	function( elem, type, handle ) {
+		elem.detachEvent( "on" + type, handle );
+	};
+
+jQuery.Event = function( src ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !this.preventDefault ) {
+		return new jQuery.Event( src );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// timeStamp is buggy for some events on Firefox(#3843)
+	// So we won't rely on the native value
+	this.timeStamp = now();
+
+	// Mark it as fixed
+	this[ expando ] = true;
+};
+
+function returnFalse() {
+	return false;
+}
+function returnTrue() {
+	return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	preventDefault: function() {
+		this.isDefaultPrevented = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		
+		// if preventDefault exists run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+		}
+		// otherwise set the returnValue property of the original event to false (IE)
+		e.returnValue = false;
+	},
+	stopPropagation: function() {
+		this.isPropagationStopped = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		// if stopPropagation exists run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+		// otherwise set the cancelBubble property of the original event to true (IE)
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	},
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+	// Check if mouse(over|out) are still within the same parent element
+	var parent = event.relatedTarget;
+
+	// Firefox sometimes assigns relatedTarget a XUL element
+	// which we cannot access the parentNode property of
+	try {
+		// Traverse up the tree
+		while ( parent && parent !== this ) {
+			parent = parent.parentNode;
+		}
+
+		if ( parent !== this ) {
+			// set the correct event type
+			event.type = event.data;
+
+			// handle event if we actually just moused on to a non sub-element
+			jQuery.event.handle.apply( this, arguments );
+		}
+
+	// assuming we've left the element since we most likely mousedover a xul element
+	} catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+	event.type = event.data;
+	jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		setup: function( data ) {
+			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+		},
+		teardown: function( data ) {
+			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+		}
+	};
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function( data, namespaces ) {
+			if ( this.nodeName.toLowerCase() !== "form" ) {
+				jQuery.event.add(this, "click.specialSubmit", function( e ) {
+					var elem = e.target, type = elem.type;
+
+					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+						return trigger( "submit", this, arguments );
+					}
+				});
+	 
+				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+					var elem = e.target, type = elem.type;
+
+					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+						return trigger( "submit", this, arguments );
+					}
+				});
+
+			} else {
+				return false;
+			}
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialSubmit" );
+		}
+	};
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+	var formElems = /textarea|input|select/i,
+
+	changeFilters,
+
+	getVal = function( elem ) {
+		var type = elem.type, val = elem.value;
+
+		if ( type === "radio" || type === "checkbox" ) {
+			val = elem.checked;
+
+		} else if ( type === "select-multiple" ) {
+			val = elem.selectedIndex > -1 ?
+				jQuery.map( elem.options, function( elem ) {
+					return elem.selected;
+				}).join("-") :
+				"";
+
+		} else if ( elem.nodeName.toLowerCase() === "select" ) {
+			val = elem.selectedIndex;
+		}
+
+		return val;
+	},
+
+	testChange = function testChange( e ) {
+		var elem = e.target, data, val;
+
+		if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
+			return;
+		}
+
+		data = jQuery.data( elem, "_change_data" );
+		val = getVal(elem);
+
+		// the current data will be also retrieved by beforeactivate
+		if ( e.type !== "focusout" || elem.type !== "radio" ) {
+			jQuery.data( elem, "_change_data", val );
+		}
+		
+		if ( data === undefined || val === data ) {
+			return;
+		}
+
+		if ( data != null || val ) {
+			e.type = "change";
+			return jQuery.event.trigger( e, arguments[1], elem );
+		}
+	};
+
+	jQuery.event.special.change = {
+		filters: {
+			focusout: testChange, 
+
+			click: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Change has to be called before submit
+			// Keydown will be called before keypress, which is used in submit-event delegation
+			keydown: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+					type === "select-multiple" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Beforeactivate happens also before the previous element is blurred
+			// with this event you can't trigger a change event, but you can store
+			// information/focus[in] is not needed anymore
+			beforeactivate: function( e ) {
+				var elem = e.target;
+				jQuery.data( elem, "_change_data", getVal(elem) );
+			}
+		},
+
+		setup: function( data, namespaces ) {
+			if ( this.type === "file" ) {
+				return false;
+			}
+
+			for ( var type in changeFilters ) {
+				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+			}
+
+			return formElems.test( this.nodeName );
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialChange" );
+
+			return formElems.test( this.nodeName );
+		}
+	};
+
+	changeFilters = jQuery.event.special.change.filters;
+}
+
+function trigger( type, elem, args ) {
+	args[0].type = type;
+	return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				this.addEventListener( orig, handler, true );
+			}, 
+			teardown: function() { 
+				this.removeEventListener( orig, handler, true );
+			}
+		};
+
+		function handler( e ) { 
+			e = jQuery.event.fix( e );
+			e.type = fix;
+			return jQuery.event.handle.call( this, e );
+		}
+	});
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+	jQuery.fn[ name ] = function( type, data, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" ) {
+			for ( var key in type ) {
+				this[ name ](key, data, type[key], fn);
+			}
+			return this;
+		}
+		
+		if ( jQuery.isFunction( data ) ) {
+			fn = data;
+			data = undefined;
+		}
+
+		var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+			jQuery( this ).unbind( event, handler );
+			return fn.apply( this, arguments );
+		}) : fn;
+
+		if ( type === "unload" && name !== "one" ) {
+			this.one( type, data, fn );
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.add( this[i], type, handler, data );
+			}
+		}
+
+		return this;
+	};
+});
+
+jQuery.fn.extend({
+	unbind: function( type, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" && !type.preventDefault ) {
+			for ( var key in type ) {
+				this.unbind(key, type[key]);
+			}
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.remove( this[i], type, fn );
+			}
+		}
+
+		return this;
+	},
+	
+	delegate: function( selector, types, data, fn ) {
+		return this.live( types, data, fn, selector );
+	},
+	
+	undelegate: function( selector, types, fn ) {
+		if ( arguments.length === 0 ) {
+				return this.unbind( "live" );
+		
+		} else {
+			return this.die( types, null, fn, selector );
+		}
+	},
+	
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+
+	triggerHandler: function( type, data ) {
+		if ( this[0] ) {
+			var event = jQuery.Event( type );
+			event.preventDefault();
+			event.stopPropagation();
+			jQuery.event.trigger( event, data, this[0] );
+			return event.result;
+		}
+	},
+
+	toggle: function( fn ) {
+		// Save reference to arguments for access in closure
+		var args = arguments, i = 1;
+
+		// link all the functions, so any of them can unbind this click handler
+		while ( i < args.length ) {
+			jQuery.proxy( fn, args[ i++ ] );
+		}
+
+		return this.click( jQuery.proxy( fn, function( event ) {
+			// Figure out which function to execute
+			var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+			jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+			// Make sure that clicks stop
+			event.preventDefault();
+
+			// and execute the function
+			return args[ lastToggle ].apply( this, arguments ) || false;
+		}));
+	},
+
+	hover: function( fnOver, fnOut ) {
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+	}
+});
+
+var liveMap = {
+	focus: "focusin",
+	blur: "focusout",
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+		var type, i = 0, match, namespaces, preType,
+			selector = origSelector || this.selector,
+			context = origSelector ? this : jQuery( this.context );
+
+		if ( jQuery.isFunction( data ) ) {
+			fn = data;
+			data = undefined;
+		}
+
+		types = (types || "").split(" ");
+
+		while ( (type = types[ i++ ]) != null ) {
+			match = rnamespaces.exec( type );
+			namespaces = "";
+
+			if ( match )  {
+				namespaces = match[0];
+				type = type.replace( rnamespaces, "" );
+			}
+
+			if ( type === "hover" ) {
+				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+				continue;
+			}
+
+			preType = type;
+
+			if ( type === "focus" || type === "blur" ) {
+				types.push( liveMap[ type ] + namespaces );
+				type = type + namespaces;
+
+			} else {
+				type = (liveMap[ type ] || type) + namespaces;
+			}
+
+			if ( name === "live" ) {
+				// bind live handler
+				context.each(function(){
+					jQuery.event.add( this, liveConvert( type, selector ),
+						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+				});
+
+			} else {
+				// unbind live handler
+				context.unbind( liveConvert( type, selector ), fn );
+			}
+		}
+		
+		return this;
+	}
+});
+
+function liveHandler( event ) {
+	var stop, elems = [], selectors = [], args = arguments,
+		related, match, handleObj, elem, j, i, l, data,
+		events = jQuery.data( this, "events" );
+
+	// Make sure we avoid non-left-click bubbling in Firefox (#3861)
+	if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+		return;
+	}
+
+	event.liveFired = this;
+
+	var live = events.live.slice(0);
+
+	for ( j = 0; j < live.length; j++ ) {
+		handleObj = live[j];
+
+		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+			selectors.push( handleObj.selector );
+
+		} else {
+			live.splice( j--, 1 );
+		}
+	}
+
+	match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+	for ( i = 0, l = match.length; i < l; i++ ) {
+		for ( j = 0; j < live.length; j++ ) {
+			handleObj = live[j];
+
+			if ( match[i].selector === handleObj.selector ) {
+				elem = match[i].elem;
+				related = null;
+
+				// Those two events require additional checking
+				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+				}
+
+				if ( !related || related !== elem ) {
+					elems.push({ elem: elem, handleObj: handleObj });
+				}
+			}
+		}
+	}
+
+	for ( i = 0, l = elems.length; i < l; i++ ) {
+		match = elems[i];
+		event.currentTarget = match.elem;
+		event.data = match.handleObj.data;
+		event.handleObj = match.handleObj;
+
+		if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
+			stop = false;
+			break;
+		}
+	}
+
+	return stop;
+}
+
+function liveConvert( type, selector ) {
+	return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( fn ) {
+		return fn ? this.bind( name, fn ) : this.trigger( name );
+	};
+
+	if ( jQuery.attrFn ) {
+		jQuery.attrFn[ name ] = true;
+	}
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+	window.attachEvent("onunload", function() {
+		for ( var id in jQuery.cache ) {
+			if ( jQuery.cache[ id ].handle ) {
+				// Try/Catch is to handle iframes being unloaded, see #4280
+				try {
+					jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+				} catch(e) {}
+			}
+		}
+	});
+}
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ *  Copyright 2009, The Dojo Foundation
  *  Released under the MIT, BSD, and GPL Licenses.
  *  More information: http://sizzlejs.com/
  */
-(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+	done = 0,
+	toString = Object.prototype.toString,
+	hasDuplicate = false,
+	baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+//   Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+	baseHasDuplicate = false;
+	return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+	results = results || [];
+	var origContext = context = context || document;
+
+	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+		return [];
+	}
+	
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
+		soFar = selector;
+	
+	// Reset the position of the chunker regexp (start from head)
+	while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+		soFar = m[3];
+		
+		parts.push( m[1] );
+		
+		if ( m[2] ) {
+			extra = m[3];
+			break;
+		}
+	}
+
+	if ( parts.length > 1 && origPOS.exec( selector ) ) {
+		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+			set = posProcess( parts[0] + parts[1], context );
+		} else {
+			set = Expr.relative[ parts[0] ] ?
+				[ context ] :
+				Sizzle( parts.shift(), context );
+
+			while ( parts.length ) {
+				selector = parts.shift();
+
+				if ( Expr.relative[ selector ] ) {
+					selector += parts.shift();
+				}
+				
+				set = posProcess( selector, set );
+			}
+		}
+	} else {
+		// Take a shortcut and set the context if the root selector is an ID
+		// (but not if it'll be faster if the inner selector is an ID)
+		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+			var ret = Sizzle.find( parts.shift(), context, contextXML );
+			context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+		}
+
+		if ( context ) {
+			var ret = seed ?
+				{ expr: parts.pop(), set: makeArray(seed) } :
+				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+			set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+			if ( parts.length > 0 ) {
+				checkSet = makeArray(set);
+			} else {
+				prune = false;
+			}
+
+			while ( parts.length ) {
+				var cur = parts.pop(), pop = cur;
+
+				if ( !Expr.relative[ cur ] ) {
+					cur = "";
+				} else {
+					pop = parts.pop();
+				}
+
+				if ( pop == null ) {
+					pop = context;
+				}
+
+				Expr.relative[ cur ]( checkSet, pop, contextXML );
+			}
+		} else {
+			checkSet = parts = [];
+		}
+	}
+
+	if ( !checkSet ) {
+		checkSet = set;
+	}
+
+	if ( !checkSet ) {
+		Sizzle.error( cur || selector );
+	}
+
+	if ( toString.call(checkSet) === "[object Array]" ) {
+		if ( !prune ) {
+			results.push.apply( results, checkSet );
+		} else if ( context && context.nodeType === 1 ) {
+			for ( var i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+					results.push( set[i] );
+				}
+			}
+		} else {
+			for ( var i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+					results.push( set[i] );
+				}
+			}
+		}
+	} else {
+		makeArray( checkSet, results );
+	}
+
+	if ( extra ) {
+		Sizzle( extra, origContext, results, seed );
+		Sizzle.uniqueSort( results );
+	}
+
+	return results;
+};
+
+Sizzle.uniqueSort = function(results){
+	if ( sortOrder ) {
+		hasDuplicate = baseHasDuplicate;
+		results.sort(sortOrder);
+
+		if ( hasDuplicate ) {
+			for ( var i = 1; i < results.length; i++ ) {
+				if ( results[i] === results[i-1] ) {
+					results.splice(i--, 1);
+				}
+			}
+		}
+	}
+
+	return results;
+};
+
+Sizzle.matches = function(expr, set){
+	return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+	var set, match;
+
+	if ( !expr ) {
+		return [];
+	}
+
+	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+		var type = Expr.order[i], match;
+		
+		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+			var left = match[1];
+			match.splice(1,1);
+
+			if ( left.substr( left.length - 1 ) !== "\\" ) {
+				match[1] = (match[1] || "").replace(/\\/g, "");
+				set = Expr.find[ type ]( match, context, isXML );
+				if ( set != null ) {
+					expr = expr.replace( Expr.match[ type ], "" );
+					break;
+				}
+			}
+		}
+	}
+
+	if ( !set ) {
+		set = context.getElementsByTagName("*");
+	}
+
+	return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+	var old = expr, result = [], curLoop = set, match, anyFound,
+		isXMLFilter = set && set[0] && isXML(set[0]);
+
+	while ( expr && set.length ) {
+		for ( var type in Expr.filter ) {
+			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+				var filter = Expr.filter[ type ], found, item, left = match[1];
+				anyFound = false;
+
+				match.splice(1,1);
+
+				if ( left.substr( left.length - 1 ) === "\\" ) {
+					continue;
+				}
+
+				if ( curLoop === result ) {
+					result = [];
+				}
+
+				if ( Expr.preFilter[ type ] ) {
+					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+					if ( !match ) {
+						anyFound = found = true;
+					} else if ( match === true ) {
+						continue;
+					}
+				}
+
+				if ( match ) {
+					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+						if ( item ) {
+							found = filter( item, match, i, curLoop );
+							var pass = not ^ !!found;
+
+							if ( inplace && found != null ) {
+								if ( pass ) {
+									anyFound = true;
+								} else {
+									curLoop[i] = false;
+								}
+							} else if ( pass ) {
+								result.push( item );
+								anyFound = true;
+							}
+						}
+					}
+				}
+
+				if ( found !== undefined ) {
+					if ( !inplace ) {
+						curLoop = result;
+					}
+
+					expr = expr.replace( Expr.match[ type ], "" );
+
+					if ( !anyFound ) {
+						return [];
+					}
+
+					break;
+				}
+			}
+		}
+
+		// Improper expression
+		if ( expr === old ) {
+			if ( anyFound == null ) {
+				Sizzle.error( expr );
+			} else {
+				break;
+			}
+		}
+
+		old = expr;
+	}
+
+	return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+	throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+	order: [ "ID", "NAME", "TAG" ],
+	match: {
+		ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+		CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+		TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+		PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+	},
+	leftMatch: {},
+	attrMap: {
+		"class": "className",
+		"for": "htmlFor"
+	},
+	attrHandle: {
+		href: function(elem){
+			return elem.getAttribute("href");
+		}
+	},
+	relative: {
+		"+": function(checkSet, part){
+			var isPartStr = typeof part === "string",
+				isTag = isPartStr && !/\W/.test(part),
+				isPartStrNotTag = isPartStr && !isTag;
+
+			if ( isTag ) {
+				part = part.toLowerCase();
+			}
+
+			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+				if ( (elem = checkSet[i]) ) {
+					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+						elem || false :
+						elem === part;
+				}
+			}
+
+			if ( isPartStrNotTag ) {
+				Sizzle.filter( part, checkSet, true );
+			}
+		},
+		">": function(checkSet, part){
+			var isPartStr = typeof part === "string";
+
+			if ( isPartStr && !/\W/.test(part) ) {
+				part = part.toLowerCase();
+
+				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+					var elem = checkSet[i];
+					if ( elem ) {
+						var parent = elem.parentNode;
+						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+					}
+				}
+			} else {
+				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+					var elem = checkSet[i];
+					if ( elem ) {
+						checkSet[i] = isPartStr ?
+							elem.parentNode :
+							elem.parentNode === part;
+					}
+				}
+
+				if ( isPartStr ) {
+					Sizzle.filter( part, checkSet, true );
+				}
+			}
+		},
+		"": function(checkSet, part, isXML){
+			var doneName = done++, checkFn = dirCheck;
+
+			if ( typeof part === "string" && !/\W/.test(part) ) {
+				var nodeCheck = part = part.toLowerCase();
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+		},
+		"~": function(checkSet, part, isXML){
+			var doneName = done++, checkFn = dirCheck;
+
+			if ( typeof part === "string" && !/\W/.test(part) ) {
+				var nodeCheck = part = part.toLowerCase();
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+		}
+	},
+	find: {
+		ID: function(match, context, isXML){
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+				return m ? [m] : [];
+			}
+		},
+		NAME: function(match, context){
+			if ( typeof context.getElementsByName !== "undefined" ) {
+				var ret = [], results = context.getElementsByName(match[1]);
+
+				for ( var i = 0, l = results.length; i < l; i++ ) {
+					if ( results[i].getAttribute("name") === match[1] ) {
+						ret.push( results[i] );
+					}
+				}
+
+				return ret.length === 0 ? null : ret;
+			}
+		},
+		TAG: function(match, context){
+			return context.getElementsByTagName(match[1]);
+		}
+	},
+	preFilter: {
+		CLASS: function(match, curLoop, inplace, result, not, isXML){
+			match = " " + match[1].replace(/\\/g, "") + " ";
+
+			if ( isXML ) {
+				return match;
+			}
+
+			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+				if ( elem ) {
+					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+						if ( !inplace ) {
+							result.push( elem );
+						}
+					} else if ( inplace ) {
+						curLoop[i] = false;
+					}
+				}
+			}
+
+			return false;
+		},
+		ID: function(match){
+			return match[1].replace(/\\/g, "");
+		},
+		TAG: function(match, curLoop){
+			return match[1].toLowerCase();
+		},
+		CHILD: function(match){
+			if ( match[1] === "nth" ) {
+				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+				// calculate the numbers (first)n+(last) including if they are negative
+				match[2] = (test[1] + (test[2] || 1)) - 0;
+				match[3] = test[3] - 0;
+			}
+
+			// TODO: Move to normal caching system
+			match[0] = done++;
+
+			return match;
+		},
+		ATTR: function(match, curLoop, inplace, result, not, isXML){
+			var name = match[1].replace(/\\/g, "");
+			
+			if ( !isXML && Expr.attrMap[name] ) {
+				match[1] = Expr.attrMap[name];
+			}
+
+			if ( match[2] === "~=" ) {
+				match[4] = " " + match[4] + " ";
+			}
+
+			return match;
+		},
+		PSEUDO: function(match, curLoop, inplace, result, not){
+			if ( match[1] === "not" ) {
+				// If we're dealing with a complex expression, or a simple one
+				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+					match[3] = Sizzle(match[3], null, null, curLoop);
+				} else {
+					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+					if ( !inplace ) {
+						result.push.apply( result, ret );
+					}
+					return false;
+				}
+			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+				return true;
+			}
+			
+			return match;
+		},
+		POS: function(match){
+			match.unshift( true );
+			return match;
+		}
+	},
+	filters: {
+		enabled: function(elem){
+			return elem.disabled === false && elem.type !== "hidden";
+		},
+		disabled: function(elem){
+			return elem.disabled === true;
+		},
+		checked: function(elem){
+			return elem.checked === true;
+		},
+		selected: function(elem){
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			elem.parentNode.selectedIndex;
+			return elem.selected === true;
+		},
+		parent: function(elem){
+			return !!elem.firstChild;
+		},
+		empty: function(elem){
+			return !elem.firstChild;
+		},
+		has: function(elem, i, match){
+			return !!Sizzle( match[3], elem ).length;
+		},
+		header: function(elem){
+			return /h\d/i.test( elem.nodeName );
+		},
+		text: function(elem){
+			return "text" === elem.type;
+		},
+		radio: function(elem){
+			return "radio" === elem.type;
+		},
+		checkbox: function(elem){
+			return "checkbox" === elem.type;
+		},
+		file: function(elem){
+			return "file" === elem.type;
+		},
+		password: function(elem){
+			return "password" === elem.type;
+		},
+		submit: function(elem){
+			return "submit" === elem.type;
+		},
+		image: function(elem){
+			return "image" === elem.type;
+		},
+		reset: function(elem){
+			return "reset" === elem.type;
+		},
+		button: function(elem){
+			return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+		},
+		input: function(elem){
+			return /input|select|textarea|button/i.test(elem.nodeName);
+		}
+	},
+	setFilters: {
+		first: function(elem, i){
+			return i === 0;
+		},
+		last: function(elem, i, match, array){
+			return i === array.length - 1;
+		},
+		even: function(elem, i){
+			return i % 2 === 0;
+		},
+		odd: function(elem, i){
+			return i % 2 === 1;
+		},
+		lt: function(elem, i, match){
+			return i < match[3] - 0;
+		},
+		gt: function(elem, i, match){
+			return i > match[3] - 0;
+		},
+		nth: function(elem, i, match){
+			return match[3] - 0 === i;
+		},
+		eq: function(elem, i, match){
+			return match[3] - 0 === i;
+		}
+	},
+	filter: {
+		PSEUDO: function(elem, match, i, array){
+			var name = match[1], filter = Expr.filters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+			} else if ( name === "contains" ) {
+				return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+			} else if ( name === "not" ) {
+				var not = match[3];
+
+				for ( var i = 0, l = not.length; i < l; i++ ) {
+					if ( not[i] === elem ) {
+						return false;
+					}
+				}
+
+				return true;
+			} else {
+				Sizzle.error( "Syntax error, unrecognized expression: " + name );
+			}
+		},
+		CHILD: function(elem, match){
+			var type = match[1], node = elem;
+			switch (type) {
+				case 'only':
+				case 'first':
+					while ( (node = node.previousSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
+						}
+					}
+					if ( type === "first" ) { 
+						return true; 
+					}
+					node = elem;
+				case 'last':
+					while ( (node = node.nextSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
+						}
+					}
+					return true;
+				case 'nth':
+					var first = match[2], last = match[3];
+
+					if ( first === 1 && last === 0 ) {
+						return true;
+					}
+					
+					var doneName = match[0],
+						parent = elem.parentNode;
+	
+					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+						var count = 0;
+						for ( node = parent.firstChild; node; node = node.nextSibling ) {
+							if ( node.nodeType === 1 ) {
+								node.nodeIndex = ++count;
+							}
+						} 
+						parent.sizcache = doneName;
+					}
+					
+					var diff = elem.nodeIndex - last;
+					if ( first === 0 ) {
+						return diff === 0;
+					} else {
+						return ( diff % first === 0 && diff / first >= 0 );
+					}
+			}
+		},
+		ID: function(elem, match){
+			return elem.nodeType === 1 && elem.getAttribute("id") === match;
+		},
+		TAG: function(elem, match){
+			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+		},
+		CLASS: function(elem, match){
+			return (" " + (elem.className || elem.getAttribute("class")) + " ")
+				.indexOf( match ) > -1;
+		},
+		ATTR: function(elem, match){
+			var name = match[1],
+				result = Expr.attrHandle[ name ] ?
+					Expr.attrHandle[ name ]( elem ) :
+					elem[ name ] != null ?
+						elem[ name ] :
+						elem.getAttribute( name ),
+				value = result + "",
+				type = match[2],
+				check = match[4];
+
+			return result == null ?
+				type === "!=" :
+				type === "=" ?
+				value === check :
+				type === "*=" ?
+				value.indexOf(check) >= 0 :
+				type === "~=" ?
+				(" " + value + " ").indexOf(check) >= 0 :
+				!check ?
+				value && result !== false :
+				type === "!=" ?
+				value !== check :
+				type === "^=" ?
+				value.indexOf(check) === 0 :
+				type === "$=" ?
+				value.substr(value.length - check.length) === check :
+				type === "|=" ?
+				value === check || value.substr(0, check.length + 1) === check + "-" :
+				false;
+		},
+		POS: function(elem, match, i, array){
+			var name = match[2], filter = Expr.setFilters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+			}
+		}
+	}
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
+		return "\\" + (num - 0 + 1);
+	}));
+}
+
+var makeArray = function(array, results) {
+	array = Array.prototype.slice.call( array, 0 );
+
+	if ( results ) {
+		results.push.apply( results, array );
+		return results;
+	}
+	
+	return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch(e){
+	makeArray = function(array, results) {
+		var ret = results || [];
+
+		if ( toString.call(array) === "[object Array]" ) {
+			Array.prototype.push.apply( ret, array );
+		} else {
+			if ( typeof array.length === "number" ) {
+				for ( var i = 0, l = array.length; i < l; i++ ) {
+					ret.push( array[i] );
+				}
+			} else {
+				for ( var i = 0; array[i]; i++ ) {
+					ret.push( array[i] );
+				}
+			}
+		}
+
+		return ret;
+	};
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+	sortOrder = function( a, b ) {
+		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+			if ( a == b ) {
+				hasDuplicate = true;
+			}
+			return a.compareDocumentPosition ? -1 : 1;
+		}
+
+		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+		if ( ret === 0 ) {
+			hasDuplicate = true;
+		}
+		return ret;
+	};
+} else if ( "sourceIndex" in document.documentElement ) {
+	sortOrder = function( a, b ) {
+		if ( !a.sourceIndex || !b.sourceIndex ) {
+			if ( a == b ) {
+				hasDuplicate = true;
+			}
+			return a.sourceIndex ? -1 : 1;
+		}
+
+		var ret = a.sourceIndex - b.sourceIndex;
+		if ( ret === 0 ) {
+			hasDuplicate = true;
+		}
+		return ret;
+	};
+} else if ( document.createRange ) {
+	sortOrder = function( a, b ) {
+		if ( !a.ownerDocument || !b.ownerDocument ) {
+			if ( a == b ) {
+				hasDuplicate = true;
+			}
+			return a.ownerDocument ? -1 : 1;
+		}
+
+		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+		aRange.setStart(a, 0);
+		aRange.setEnd(a, 0);
+		bRange.setStart(b, 0);
+		bRange.setEnd(b, 0);
+		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+		if ( ret === 0 ) {
+			hasDuplicate = true;
+		}
+		return ret;
+	};
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+function getText( elems ) {
+	var ret = "", elem;
+
+	for ( var i = 0; elems[i]; i++ ) {
+		elem = elems[i];
+
+		// Get the text from text nodes and CDATA nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+			ret += elem.nodeValue;
+
+		// Traverse everything else, except comment nodes
+		} else if ( elem.nodeType !== 8 ) {
+			ret += getText( elem.childNodes );
+		}
+	}
+
+	return ret;
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+	// We're going to inject a fake input element with a specified name
+	var form = document.createElement("div"),
+		id = "script" + (new Date).getTime();
+	form.innerHTML = "<a name='" + id + "'/>";
+
+	// Inject it into the root element, check its status, and remove it quickly
+	var root = document.documentElement;
+	root.insertBefore( form, root.firstChild );
+
+	// The workaround has to do additional checks after a getElementById
+	// Which slows things down for other browsers (hence the branching)
+	if ( document.getElementById( id ) ) {
+		Expr.find.ID = function(match, context, isXML){
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+			}
+		};
+
+		Expr.filter.ID = function(elem, match){
+			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+			return elem.nodeType === 1 && node && node.nodeValue === match;
+		};
+	}
+
+	root.removeChild( form );
+	root = form = null; // release memory in IE
+})();
+
+(function(){
+	// Check to see if the browser returns only elements
+	// when doing getElementsByTagName("*")
+
+	// Create a fake element
+	var div = document.createElement("div");
+	div.appendChild( document.createComment("") );
+
+	// Make sure no comments are found
+	if ( div.getElementsByTagName("*").length > 0 ) {
+		Expr.find.TAG = function(match, context){
+			var results = context.getElementsByTagName(match[1]);
+
+			// Filter out possible comments
+			if ( match[1] === "*" ) {
+				var tmp = [];
+
+				for ( var i = 0; results[i]; i++ ) {
+					if ( results[i].nodeType === 1 ) {
+						tmp.push( results[i] );
+					}
+				}
+
+				results = tmp;
+			}
+
+			return results;
+		};
+	}
+
+	// Check to see if an attribute returns normalized href attributes
+	div.innerHTML = "<a href='#'></a>";
+	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+			div.firstChild.getAttribute("href") !== "#" ) {
+		Expr.attrHandle.href = function(elem){
+			return elem.getAttribute("href", 2);
+		};
+	}
+
+	div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) {
+	(function(){
+		var oldSizzle = Sizzle, div = document.createElement("div");
+		div.innerHTML = "<p class='TEST'></p>";
+
+		// Safari can't handle uppercase or unicode characters when
+		// in quirks mode.
+		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+			return;
+		}
+	
+		Sizzle = function(query, context, extra, seed){
+			context = context || document;
+
+			// Only use querySelectorAll on non-XML documents
+			// (ID selectors don't work in non-HTML documents)
+			if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+				try {
+					return makeArray( context.querySelectorAll(query), extra );
+				} catch(e){}
+			}
+		
+			return oldSizzle(query, context, extra, seed);
+		};
+
+		for ( var prop in oldSizzle ) {
+			Sizzle[ prop ] = oldSizzle[ prop ];
+		}
+
+		div = null; // release memory in IE
+	})();
+}
+
+(function(){
+	var div = document.createElement("div");
+
+	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+	// Opera can't find a second classname (in 9.6)
+	// Also, make sure that getElementsByClassName actually exists
+	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+		return;
+	}
+
+	// Safari caches class attributes, doesn't catch changes (in 3.2)
+	div.lastChild.className = "e";
+
+	if ( div.getElementsByClassName("e").length === 1 ) {
+		return;
+	}
+	
+	Expr.order.splice(1, 0, "CLASS");
+	Expr.find.CLASS = function(match, context, isXML) {
+		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+			return context.getElementsByClassName(match[1]);
+		}
+	};
+
+	div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+		if ( elem ) {
+			elem = elem[dir];
+			var match = false;
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 && !isXML ){
+					elem.sizcache = doneName;
+					elem.sizset = i;
+				}
+
+				if ( elem.nodeName.toLowerCase() === cur ) {
+					match = elem;
+					break;
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+		if ( elem ) {
+			elem = elem[dir];
+			var match = false;
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 ) {
+					if ( !isXML ) {
+						elem.sizcache = doneName;
+						elem.sizset = i;
+					}
+					if ( typeof cur !== "string" ) {
+						if ( elem === cur ) {
+							match = true;
+							break;
+						}
+
+					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+						match = elem;
+						break;
+					}
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+	return !!(a.compareDocumentPosition(b) & 16);
+} : function(a, b){
+	return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833) 
+	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function(selector, context){
+	var tmpSet = [], later = "", match,
+		root = context.nodeType ? [context] : context;
+
+	// Position selectors must be done after the filter
+	// And so must :not(positional) so we move all PSEUDOs to the end
+	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+		later += match[0];
+		selector = selector.replace( Expr.match.PSEUDO, "" );
+	}
+
+	selector = Expr.relative[selector] ? selector + "*" : selector;
+
+	for ( var i = 0, l = root.length; i < l; i++ ) {
+		Sizzle( selector, root[i], tmpSet );
+	}
+
+	return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = getText;
+jQuery.isXMLDoc = isXML;
+jQuery.contains = contains;
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+var runtil = /Until$/,
+	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+	// Note: This RegExp should be improved, or likely pulled from Sizzle
+	rmultiselector = /,/,
+	slice = Array.prototype.slice;
+
+// Implement the identical functionality for filter and not
+var winnow = function( elements, qualifier, keep ) {
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			return !!qualifier.call( elem, i, elem ) === keep;
+		});
+
+	} else if ( qualifier.nodeType ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			return (elem === qualifier) === keep;
+		});
+
+	} else if ( typeof qualifier === "string" ) {
+		var filtered = jQuery.grep(elements, function( elem ) {
+			return elem.nodeType === 1;
+		});
+
+		if ( isSimple.test( qualifier ) ) {
+			return jQuery.filter(qualifier, filtered, !keep);
+		} else {
+			qualifier = jQuery.filter( qualifier, filtered );
+		}
+	}
+
+	return jQuery.grep(elements, function( elem, i ) {
+		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+	});
+};
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var ret = this.pushStack( "", "find", selector ), length = 0;
+
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			length = ret.length;
+			jQuery.find( selector, this[i], ret );
+
+			if ( i > 0 ) {
+				// Make sure that the results are unique
+				for ( var n = length; n < ret.length; n++ ) {
+					for ( var r = 0; r < length; r++ ) {
+						if ( ret[r] === ret[n] ) {
+							ret.splice(n--, 1);
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		return ret;
+	},
+
+	has: function( target ) {
+		var targets = jQuery( target );
+		return this.filter(function() {
+			for ( var i = 0, l = targets.length; i < l; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector, false), "not", selector);
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector, true), "filter", selector );
+	},
+	
+	is: function( selector ) {
+		return !!selector && jQuery.filter( selector, this ).length > 0;
+	},
+
+	closest: function( selectors, context ) {
+		if ( jQuery.isArray( selectors ) ) {
+			var ret = [], cur = this[0], match, matches = {}, selector;
+
+			if ( cur && selectors.length ) {
+				for ( var i = 0, l = selectors.length; i < l; i++ ) {
+					selector = selectors[i];
+
+					if ( !matches[selector] ) {
+						matches[selector] = jQuery.expr.match.POS.test( selector ) ? 
+							jQuery( selector, context || this.context ) :
+							selector;
+					}
+				}
+
+				while ( cur && cur.ownerDocument && cur !== context ) {
+					for ( selector in matches ) {
+						match = matches[selector];
+
+						if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+							ret.push({ selector: selector, elem: cur });
+							delete matches[selector];
+						}
+					}
+					cur = cur.parentNode;
+				}
+			}
+
+			return ret;
+		}
+
+		var pos = jQuery.expr.match.POS.test( selectors ) ? 
+			jQuery( selectors, context || this.context ) : null;
+
+		return this.map(function( i, cur ) {
+			while ( cur && cur.ownerDocument && cur !== context ) {
+				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
+					return cur;
+				}
+				cur = cur.parentNode;
+			}
+			return null;
+		});
+	},
+	
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+		if ( !elem || typeof elem === "string" ) {
+			return jQuery.inArray( this[0],
+				// If it receives a string, the selector is used
+				// If it receives nothing, the siblings are used
+				elem ? jQuery( elem ) : this.parent().children() );
+		}
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		var set = typeof selector === "string" ?
+				jQuery( selector, context || this.context ) :
+				jQuery.makeArray( selector ),
+			all = jQuery.merge( this.get(), set );
+
+		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+			all :
+			jQuery.unique( all ) );
+	},
+
+	andSelf: function() {
+		return this.add( this.prevObject );
+	}
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+	return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return jQuery.nth( elem, 2, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return jQuery.nth( elem, 2, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( elem.parentNode.firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.makeArray( elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+		
+		if ( !runtil.test( name ) ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+			ret = ret.reverse();
+		}
+
+		return this.pushStack( ret, name, slice.call(arguments).join(",") );
+	};
+});
+
+jQuery.extend({
+	filter: function( expr, elems, not ) {
+		if ( not ) {
+			expr = ":not(" + expr + ")";
+		}
+
+		return jQuery.find.matches(expr, elems);
+	},
+	
+	dir: function( elem, dir, until ) {
+		var matched = [], cur = elem[dir];
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	nth: function( cur, result, dir, elem ) {
+		result = result || 1;
+		var num = 0;
+
+		for ( ; cur; cur = cur[dir] ) {
+			if ( cur.nodeType === 1 && ++num === result ) {
+				break;
+			}
+		}
+
+		return cur;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
+	rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnocache = /<script|<object|<embed|<option|<style/i,
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
+	fcloseTag = function( all, front, tag ) {
+		return rselfClosing.test( tag ) ?
+			all :
+			front + "></" + tag + ">";
+	},
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		area: [ 1, "<map>", "</map>" ],
+		_default: [ 0, "", "" ]
+	};
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+	wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+	text: function( text ) {
+		if ( jQuery.isFunction(text) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.text( text.call(this, i, self.text()) );
+			});
+		}
+
+		if ( typeof text !== "object" && text !== undefined ) {
+			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+		}
+
+		return jQuery.text( this );
+	},
+
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append(this);
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ), contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		return this.each(function() {
+			jQuery( this ).wrapAll( html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.insertBefore( elem, this.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this );
+			});
+		} else if ( arguments.length ) {
+			var set = jQuery(arguments[0]);
+			set.push.apply( set, this.toArray() );
+			return this.pushStack( set, "before", arguments );
+		}
+	},
+
+	after: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			});
+		} else if ( arguments.length ) {
+			var set = this.pushStack( this, "after", arguments );
+			set.push.apply( set, jQuery(arguments[0]).toArray() );
+			return set;
+		}
+	},
+	
+	// keepData is for internal use only--do not document
+	remove: function( selector, keepData ) {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+				if ( !keepData && elem.nodeType === 1 ) {
+					jQuery.cleanData( elem.getElementsByTagName("*") );
+					jQuery.cleanData( [ elem ] );
+				}
+
+				if ( elem.parentNode ) {
+					 elem.parentNode.removeChild( elem );
+				}
+			}
+		}
+		
+		return this;
+	},
+
+	empty: function() {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( elem.getElementsByTagName("*") );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+		}
+		
+		return this;
+	},
+
+	clone: function( events ) {
+		// Do the clone
+		var ret = this.map(function() {
+			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+				// IE copies events bound via attachEvent when
+				// using cloneNode. Calling detachEvent on the
+				// clone will also remove the events from the orignal
+				// In order to get around this, we use innerHTML.
+				// Unfortunately, this means some modifications to
+				// attributes in IE that are actually only stored
+				// as properties will not be copied (such as the
+				// the name attribute on an input).
+				var html = this.outerHTML, ownerDocument = this.ownerDocument;
+				if ( !html ) {
+					var div = ownerDocument.createElement("div");
+					div.appendChild( this.cloneNode(true) );
+					html = div.innerHTML;
+				}
+
+				return jQuery.clean([html.replace(rinlinejQuery, "")
+					// Handle the case in IE 8 where action=/test/> self-closes a tag
+					.replace(/=([^="'>\s]+\/)>/g, '="$1">')
+					.replace(rleadingWhitespace, "")], ownerDocument)[0];
+			} else {
+				return this.cloneNode(true);
+			}
+		});
+
+		// Copy the events from the original to the clone
+		if ( events === true ) {
+			cloneCopyEvent( this, ret );
+			cloneCopyEvent( this.find("*"), ret.find("*") );
+		}
+
+		// Return the cloned set
+		return ret;
+	},
+
+	html: function( value ) {
+		if ( value === undefined ) {
+			return this[0] && this[0].nodeType === 1 ?
+				this[0].innerHTML.replace(rinlinejQuery, "") :
+				null;
+
+		// See if we can take a shortcut and just use innerHTML
+		} else if ( typeof value === "string" && !rnocache.test( value ) &&
+			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+			value = value.replace(rxhtmlTag, fcloseTag);
+
+			try {
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					// Remove element nodes and prevent memory leaks
+					if ( this[i].nodeType === 1 ) {
+						jQuery.cleanData( this[i].getElementsByTagName("*") );
+						this[i].innerHTML = value;
+					}
+				}
+
+			// If using innerHTML throws an exception, use the fallback method
+			} catch(e) {
+				this.empty().append( value );
+			}
+
+		} else if ( jQuery.isFunction( value ) ) {
+			this.each(function(i){
+				var self = jQuery(this), old = self.html();
+				self.empty().append(function(){
+					return value.call( this, i, old );
+				});
+			});
+
+		} else {
+			this.empty().append( value );
+		}
+
+		return this;
+	},
+
+	replaceWith: function( value ) {
+		if ( this[0] && this[0].parentNode ) {
+			// Make sure that the elements are removed from the DOM before they are inserted
+			// this can help fix replacing a parent with child elements
+			if ( jQuery.isFunction( value ) ) {
+				return this.each(function(i) {
+					var self = jQuery(this), old = self.html();
+					self.replaceWith( value.call( this, i, old ) );
+				});
+			}
+
+			if ( typeof value !== "string" ) {
+				value = jQuery(value).detach();
+			}
+
+			return this.each(function() {
+				var next = this.nextSibling, parent = this.parentNode;
+
+				jQuery(this).remove();
+
+				if ( next ) {
+					jQuery(next).before( value );
+				} else {
+					jQuery(parent).append( value );
+				}
+			});
+		} else {
+			return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+		}
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, table, callback ) {
+		var results, first, value = args[0], scripts = [], fragment, parent;
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+			return this.each(function() {
+				jQuery(this).domManip( args, table, callback, true );
+			});
+		}
+
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				args[0] = value.call(this, i, table ? self.html() : undefined);
+				self.domManip( args, table, callback );
+			});
+		}
+
+		if ( this[0] ) {
+			parent = value && value.parentNode;
+
+			// If we're in a fragment, just use that instead of building a new one
+			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+				results = { fragment: parent };
+
+			} else {
+				results = buildFragment( args, this, scripts );
+			}
+			
+			fragment = results.fragment;
+			
+			if ( fragment.childNodes.length === 1 ) {
+				first = fragment = fragment.firstChild;
+			} else {
+				first = fragment.firstChild;
+			}
+
+			if ( first ) {
+				table = table && jQuery.nodeName( first, "tr" );
+
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					callback.call(
+						table ?
+							root(this[i], first) :
+							this[i],
+						i > 0 || results.cacheable || this.length > 1  ?
+							fragment.cloneNode(true) :
+							fragment
+					);
+				}
+			}
+
+			if ( scripts.length ) {
+				jQuery.each( scripts, evalScript );
+			}
+		}
+
+		return this;
+
+		function root( elem, cur ) {
+			return jQuery.nodeName(elem, "table") ?
+				(elem.getElementsByTagName("tbody")[0] ||
+				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+				elem;
+		}
+	}
+});
+
+function cloneCopyEvent(orig, ret) {
+	var i = 0;
+
+	ret.each(function() {
+		if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+			return;
+		}
+
+		var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+
+		if ( events ) {
+			delete curData.handle;
+			curData.events = {};
+
+			for ( var type in events ) {
+				for ( var handler in events[ type ] ) {
+					jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+				}
+			}
+		}
+	});
+}
+
+function buildFragment( args, nodes, scripts ) {
+	var fragment, cacheable, cacheresults,
+		doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+	// Only cache "small" (1/2 KB) strings that are associated with the main document
+	// Cloning options loses the selected state, so don't cache them
+	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+		!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+		cacheable = true;
+		cacheresults = jQuery.fragments[ args[0] ];
+		if ( cacheresults ) {
+			if ( cacheresults !== 1 ) {
+				fragment = cacheresults;
+			}
+		}
+	}
+
+	if ( !fragment ) {
+		fragment = doc.createDocumentFragment();
+		jQuery.clean( args, doc, fragment, scripts );
+	}
+
+	if ( cacheable ) {
+		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+	}
+
+	return { fragment: fragment, cacheable: cacheable };
+}
+
+jQuery.fragments = {};
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var ret = [], insert = jQuery( selector ),
+			parent = this.length === 1 && this[0].parentNode;
+		
+		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+			insert[ original ]( this[0] );
+			return this;
+			
+		} else {
+			for ( var i = 0, l = insert.length; i < l; i++ ) {
+				var elems = (i > 0 ? this.clone(true) : this).get();
+				jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+				ret = ret.concat( elems );
+			}
+		
+			return this.pushStack( ret, name, insert.selector );
+		}
+	};
+});
+
+jQuery.extend({
+	clean: function( elems, context, fragment, scripts ) {
+		context = context || document;
+
+		// !context.createElement fails in IE with an error but returns typeof 'object'
+		if ( typeof context.createElement === "undefined" ) {
+			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+		}
+
+		var ret = [];
+
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			if ( typeof elem === "number" ) {
+				elem += "";
+			}
+
+			if ( !elem ) {
+				continue;
+			}
+
+			// Convert html string into DOM nodes
+			if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+				elem = context.createTextNode( elem );
+
+			} else if ( typeof elem === "string" ) {
+				// Fix "XHTML"-style tags in all browsers
+				elem = elem.replace(rxhtmlTag, fcloseTag);
+
+				// Trim whitespace, otherwise indexOf won't work as expected
+				var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+					wrap = wrapMap[ tag ] || wrapMap._default,
+					depth = wrap[0],
+					div = context.createElement("div");
+
+				// Go to html and back, then peel off extra wrappers
+				div.innerHTML = wrap[1] + elem + wrap[2];
+
+				// Move to the right depth
+				while ( depth-- ) {
+					div = div.lastChild;
+				}
+
+				// Remove IE's autoinserted <tbody> from table fragments
+				if ( !jQuery.support.tbody ) {
+
+					// String was a <table>, *may* have spurious <tbody>
+					var hasBody = rtbody.test(elem),
+						tbody = tag === "table" && !hasBody ?
+							div.firstChild && div.firstChild.childNodes :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !hasBody ?
+								div.childNodes :
+								[];
+
+					for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+							tbody[ j ].parentNode.removeChild( tbody[ j ] );
+						}
+					}
+
+				}
+
+				// IE completely kills leading whitespace when innerHTML is used
+				if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+					div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+				}
+
+				elem = div.childNodes;
+			}
+
+			if ( elem.nodeType ) {
+				ret.push( elem );
+			} else {
+				ret = jQuery.merge( ret, elem );
+			}
+		}
+
+		if ( fragment ) {
+			for ( var i = 0; ret[i]; i++ ) {
+				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+				
+				} else {
+					if ( ret[i].nodeType === 1 ) {
+						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+					}
+					fragment.appendChild( ret[i] );
+				}
+			}
+		}
+
+		return ret;
+	},
+	
+	cleanData: function( elems ) {
+		var data, id, cache = jQuery.cache,
+			special = jQuery.event.special,
+			deleteExpando = jQuery.support.deleteExpando;
+		
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			id = elem[ jQuery.expando ];
+			
+			if ( id ) {
+				data = cache[ id ];
+				
+				if ( data.events ) {
+					for ( var type in data.events ) {
+						if ( special[ type ] ) {
+							jQuery.event.remove( elem, type );
+
+						} else {
+							removeEvent( elem, type, data.handle );
+						}
+					}
+				}
+				
+				if ( deleteExpando ) {
+					delete elem[ jQuery.expando ];
+
+				} else if ( elem.removeAttribute ) {
+					elem.removeAttribute( jQuery.expando );
+				}
+				
+				delete cache[ id ];
+			}
+		}
+	}
+});
+// exclude the following css properties to add px
+var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+	ralpha = /alpha\([^)]*\)/,
+	ropacity = /opacity=([^)]*)/,
+	rfloat = /float/i,
+	rdashAlpha = /-([a-z])/ig,
+	rupper = /([A-Z])/g,
+	rnumpx = /^-?\d+(?:px)?$/i,
+	rnum = /^-?\d/,
+
+	cssShow = { position: "absolute", visibility: "hidden", display:"block" },
+	cssWidth = [ "Left", "Right" ],
+	cssHeight = [ "Top", "Bottom" ],
+
+	// cache check for defaultView.getComputedStyle
+	getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+	// normalize float css property
+	styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
+	fcamelCase = function( all, letter ) {
+		return letter.toUpperCase();
+	};
+
+jQuery.fn.css = function( name, value ) {
+	return access( this, name, value, true, function( elem, name, value ) {
+		if ( value === undefined ) {
+			return jQuery.curCSS( elem, name );
+		}
+		
+		if ( typeof value === "number" && !rexclude.test(name) ) {
+			value += "px";
+		}
+
+		jQuery.style( elem, name, value );
+	});
+};
+
+jQuery.extend({
+	style: function( elem, name, value ) {
+		// don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return undefined;
+		}
+
+		// ignore negative width and height values #1599
+		if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
+			value = undefined;
+		}
+
+		var style = elem.style || elem, set = value !== undefined;
+
+		// IE uses filters for opacity
+		if ( !jQuery.support.opacity && name === "opacity" ) {
+			if ( set ) {
+				// IE has trouble with opacity if it does not have layout
+				// Force it by setting the zoom level
+				style.zoom = 1;
+
+				// Set the alpha filter to set the opacity
+				var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
+				var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
+				style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
+			}
+
+			return style.filter && style.filter.indexOf("opacity=") >= 0 ?
+				(parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
+				"";
+		}
+
+		// Make sure we're using the right name for getting the float value
+		if ( rfloat.test( name ) ) {
+			name = styleFloat;
+		}
+
+		name = name.replace(rdashAlpha, fcamelCase);
+
+		if ( set ) {
+			style[ name ] = value;
+		}
+
+		return style[ name ];
+	},
+
+	css: function( elem, name, force, extra ) {
+		if ( name === "width" || name === "height" ) {
+			var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
+
+			function getWH() {
+				val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+				if ( extra === "border" ) {
+					return;
+				}
+
+				jQuery.each( which, function() {
+					if ( !extra ) {
+						val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+					}
+
+					if ( extra === "margin" ) {
+						val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+					} else {
+						val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+					}
+				});
+			}
+
+			if ( elem.offsetWidth !== 0 ) {
+				getWH();
+			} else {
+				jQuery.swap( elem, props, getWH );
+			}
+
+			return Math.max(0, Math.round(val));
+		}
+
+		return jQuery.curCSS( elem, name, force );
+	},
+
+	curCSS: function( elem, name, force ) {
+		var ret, style = elem.style, filter;
+
+		// IE uses filters for opacity
+		if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
+			ret = ropacity.test(elem.currentStyle.filter || "") ?
+				(parseFloat(RegExp.$1) / 100) + "" :
+				"";
+
+			return ret === "" ?
+				"1" :
+				ret;
+		}
+
+		// Make sure we're using the right name for getting the float value
+		if ( rfloat.test( name ) ) {
+			name = styleFloat;
+		}
+
+		if ( !force && style && style[ name ] ) {
+			ret = style[ name ];
+
+		} else if ( getComputedStyle ) {
+
+			// Only "float" is needed here
+			if ( rfloat.test( name ) ) {
+				name = "float";
+			}
+
+			name = name.replace( rupper, "-$1" ).toLowerCase();
+
+			var defaultView = elem.ownerDocument.defaultView;
+
+			if ( !defaultView ) {
+				return null;
+			}
+
+			var computedStyle = defaultView.getComputedStyle( elem, null );
+
+			if ( computedStyle ) {
+				ret = computedStyle.getPropertyValue( name );
+			}
+
+			// We should always get a number back from opacity
+			if ( name === "opacity" && ret === "" ) {
+				ret = "1";
+			}
+
+		} else if ( elem.currentStyle ) {
+			var camelCase = name.replace(rdashAlpha, fcamelCase);
+
+			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+			// From the awesome hack by Dean Edwards
+			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+			// If we're not dealing with a regular pixel number
+			// but a number that has a weird ending, we need to convert it to pixels
+			if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+				// Remember the original values
+				var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+				// Put in the new values to get a computed value out
+				elem.runtimeStyle.left = elem.currentStyle.left;
+				style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
+				ret = style.pixelLeft + "px";
+
+				// Revert the changed values
+				style.left = left;
+				elem.runtimeStyle.left = rsLeft;
+			}
+		}
+
+		return ret;
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback ) {
+		var old = {};
+
+		// Remember the old values, and insert the new ones
+		for ( var name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		callback.call( elem );
+
+		// Revert the old values
+		for ( var name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+	}
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		var width = elem.offsetWidth, height = elem.offsetHeight,
+			skip = elem.nodeName.toLowerCase() === "tr";
+
+		return width === 0 && height === 0 && !skip ?
+			true :
+			width > 0 && height > 0 && !skip ?
+				false :
+				jQuery.curCSS(elem, "display") === "none";
+	};
+
+	jQuery.expr.filters.visible = function( elem ) {
+		return !jQuery.expr.filters.hidden( elem );
+	};
+}
+var jsc = now(),
+	rscript = /<script(.|\s)*?\/script>/gi,
+	rselectTextarea = /select|textarea/i,
+	rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
+	jsre = /=\?(&|$)/,
+	rquery = /\?/,
+	rts = /(\?|&)_=.*?(&|$)/,
+	rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+	r20 = /%20/g,
+
+	// Keep a copy of the old load method
+	_load = jQuery.fn.load;
+
+jQuery.fn.extend({
+	load: function( url, params, callback ) {
+		if ( typeof url !== "string" ) {
+			return _load.call( this, url );
+
+		// Don't do a request if no elements are being requested
+		} else if ( !this.length ) {
+			return this;
+		}
+
+		var off = url.indexOf(" ");
+		if ( off >= 0 ) {
+			var selector = url.slice(off, url.length);
+			url = url.slice(0, off);
+		}
+
+		// Default to a GET request
+		var type = "GET";
+
+		// If the second parameter was provided
+		if ( params ) {
+			// If it's a function
+			if ( jQuery.isFunction( params ) ) {
+				// We assume that it's the callback
+				callback = params;
+				params = null;
+
+			// Otherwise, build a param string
+			} else if ( typeof params === "object" ) {
+				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+				type = "POST";
+			}
+		}
+
+		var self = this;
+
+		// Request the remote document
+		jQuery.ajax({
+			url: url,
+			type: type,
+			dataType: "html",
+			data: params,
+			complete: function( res, status ) {
+				// If successful, inject the HTML into all the matched elements
+				if ( status === "success" || status === "notmodified" ) {
+					// See if a selector was specified
+					self.html( selector ?
+						// Create a dummy div to hold the results
+						jQuery("<div />")
+							// inject the contents of the document in, removing the scripts
+							// to avoid any 'Permission Denied' errors in IE
+							.append(res.responseText.replace(rscript, ""))
+
+							// Locate the specified elements
+							.find(selector) :
+
+						// If not, just inject the full result
+						res.responseText );
+				}
+
+				if ( callback ) {
+					self.each( callback, [res.responseText, status, res] );
+				}
+			}
+		});
+
+		return this;
+	},
+
+	serialize: function() {
+		return jQuery.param(this.serializeArray());
+	},
+	serializeArray: function() {
+		return this.map(function() {
+			return this.elements ? jQuery.makeArray(this.elements) : this;
+		})
+		.filter(function() {
+			return this.name && !this.disabled &&
+				(this.checked || rselectTextarea.test(this.nodeName) ||
+					rinput.test(this.type));
+		})
+		.map(function( i, elem ) {
+			var val = jQuery(this).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray(val) ?
+					jQuery.map( val, function( val, i ) {
+						return { name: elem.name, value: val };
+					}) :
+					{ name: elem.name, value: val };
+		}).get();
+	}
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+	jQuery.fn[o] = function( f ) {
+		return this.bind(o, f);
+	};
+});
+
+jQuery.extend({
+
+	get: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = null;
+		}
+
+		return jQuery.ajax({
+			type: "GET",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get(url, null, callback, "script");
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get(url, data, callback, "json");
+	},
+
+	post: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = {};
+		}
+
+		return jQuery.ajax({
+			type: "POST",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	ajaxSetup: function( settings ) {
+		jQuery.extend( jQuery.ajaxSettings, settings );
+	},
+
+	ajaxSettings: {
+		url: location.href,
+		global: true,
+		type: "GET",
+		contentType: "application/x-www-form-urlencoded",
+		processData: true,
+		async: true,
+		/*
+		timeout: 0,
+		data: null,
+		username: null,
+		password: null,
+		traditional: false,
+		*/
+		// Create the request object; Microsoft failed to properly
+		// implement the XMLHttpRequest in IE7 (can't request local files),
+		// so we use the ActiveXObject when it is available
+		// This function can be overriden by calling jQuery.ajaxSetup
+		xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
+			function() {
+				return new window.XMLHttpRequest();
+			} :
+			function() {
+				try {
+					return new window.ActiveXObject("Microsoft.XMLHTTP");
+				} catch(e) {}
+			},
+		accepts: {
+			xml: "application/xml, text/xml",
+			html: "text/html",
+			script: "text/javascript, application/javascript",
+			json: "application/json, text/javascript",
+			text: "text/plain",
+			_default: "*/*"
+		}
+	},
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {},
+
+	ajax: function( origSettings ) {
+		var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
+		
+		var jsonp, status, data,
+			callbackContext = origSettings && origSettings.context || s,
+			type = s.type.toUpperCase();
+
+		// convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Handle JSONP Parameter Callbacks
+		if ( s.dataType === "jsonp" ) {
+			if ( type === "GET" ) {
+				if ( !jsre.test( s.url ) ) {
+					s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+				}
+			} else if ( !s.data || !jsre.test(s.data) ) {
+				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+			}
+			s.dataType = "json";
+		}
+
+		// Build temporary JSONP function
+		if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+			jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+			// Replace the =? sequence both in the query string and the data
+			if ( s.data ) {
+				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+			}
+
+			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+			// We need to make sure
+			// that a JSONP style response is executed properly
+			s.dataType = "script";
+
+			// Handle JSONP-style loading
+			window[ jsonp ] = window[ jsonp ] || function( tmp ) {
+				data = tmp;
+				success();
+				complete();
+				// Garbage collect
+				window[ jsonp ] = undefined;
+
+				try {
+					delete window[ jsonp ];
+				} catch(e) {}
+
+				if ( head ) {
+					head.removeChild( script );
+				}
+			};
+		}
+
+		if ( s.dataType === "script" && s.cache === null ) {
+			s.cache = false;
+		}
+
+		if ( s.cache === false && type === "GET" ) {
+			var ts = now();
+
+			// try replacing _= if it is there
+			var ret = s.url.replace(rts, "$1_=" + ts + "$2");
+
+			// if nothing was replaced, add timestamp to the end
+			s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+		}
+
+		// If data is available, append data to url for get requests
+		if ( s.data && type === "GET" ) {
+			s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+		}
+
+		// Watch for a new set of requests
+		if ( s.global && ! jQuery.active++ ) {
+			jQuery.event.trigger( "ajaxStart" );
+		}
+
+		// Matches an absolute URL, and saves the domain
+		var parts = rurl.exec( s.url ),
+			remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+
+		// If we're requesting a remote document
+		// and trying to load JSON or Script with a GET
+		if ( s.dataType === "script" && type === "GET" && remote ) {
+			var head = document.getElementsByTagName("head")[0] || document.documentElement;
+			var script = document.createElement("script");
+			script.src = s.url;
+			if ( s.scriptCharset ) {
+				script.charset = s.scriptCharset;
+			}
+
+			// Handle Script loading
+			if ( !jsonp ) {
+				var done = false;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function() {
+					if ( !done && (!this.readyState ||
+							this.readyState === "loaded" || this.readyState === "complete") ) {
+						done = true;
+						success();
+						complete();
+
+						// Handle memory leak in IE
+						script.onload = script.onreadystatechange = null;
+						if ( head && script.parentNode ) {
+							head.removeChild( script );
+						}
+					}
+				};
+			}
+
+			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709 and #4378).
+			head.insertBefore( script, head.firstChild );
+
+			// We handle everything using the script element injection
+			return undefined;
+		}
+
+		var requestDone = false;
+
+		// Create the request object
+		var xhr = s.xhr();
+
+		if ( !xhr ) {
+			return;
+		}
+
+		// Open the socket
+		// Passing null username, generates a login popup on Opera (#2865)
+		if ( s.username ) {
+			xhr.open(type, s.url, s.async, s.username, s.password);
+		} else {
+			xhr.open(type, s.url, s.async);
+		}
+
+		// Need an extra try/catch for cross domain requests in Firefox 3
+		try {
+			// Set the correct header, if data is being sent
+			if ( s.data || origSettings && origSettings.contentType ) {
+				xhr.setRequestHeader("Content-Type", s.contentType);
+			}
+
+			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+			if ( s.ifModified ) {
+				if ( jQuery.lastModified[s.url] ) {
+					xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+				}
+
+				if ( jQuery.etag[s.url] ) {
+					xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+				}
+			}
+
+			// Set header so the called script knows that it's an XMLHttpRequest
+			// Only send the header if it's not a remote XHR
+			if ( !remote ) {
+				xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+			}
+
+			// Set the Accepts header for the server, depending on the dataType
+			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+				s.accepts[ s.dataType ] + ", */*" :
+				s.accepts._default );
+		} catch(e) {}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
+			// Handle the global AJAX counter
+			if ( s.global && ! --jQuery.active ) {
+				jQuery.event.trigger( "ajaxStop" );
+			}
+
+			// close opended socket
+			xhr.abort();
+			return false;
+		}
+
+		if ( s.global ) {
+			trigger("ajaxSend", [xhr, s]);
+		}
+
+		// Wait for a response to come back
+		var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+			// The request was aborted
+			if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+				// Opera doesn't call onreadystatechange before this point
+				// so we simulate the call
+				if ( !requestDone ) {
+					complete();
+				}
+
+				requestDone = true;
+				if ( xhr ) {
+					xhr.onreadystatechange = jQuery.noop;
+				}
+
+			// The transfer is complete and the data is available, or the request timed out
+			} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+				requestDone = true;
+				xhr.onreadystatechange = jQuery.noop;
+
+				status = isTimeout === "timeout" ?
+					"timeout" :
+					!jQuery.httpSuccess( xhr ) ?
+						"error" :
+						s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+							"notmodified" :
+							"success";
+
+				var errMsg;
+
+				if ( status === "success" ) {
+					// Watch for, and catch, XML document parse errors
+					try {
+						// process the data (runs the xml through httpData regardless of callback)
+						data = jQuery.httpData( xhr, s.dataType, s );
+					} catch(err) {
+						status = "parsererror";
+						errMsg = err;
+					}
+				}
+
+				// Make sure that the request was successful or notmodified
+				if ( status === "success" || status === "notmodified" ) {
+					// JSONP handles its own success callback
+					if ( !jsonp ) {
+						success();
+					}
+				} else {
+					jQuery.handleError(s, xhr, status, errMsg);
+				}
+
+				// Fire the complete handlers
+				complete();
+
+				if ( isTimeout === "timeout" ) {
+					xhr.abort();
+				}
+
+				// Stop memory leaks
+				if ( s.async ) {
+					xhr = null;
+				}
+			}
+		};
+
+		// Override the abort handler, if we can (IE doesn't allow it, but that's OK)
+		// Opera doesn't fire onreadystatechange at all on abort
+		try {
+			var oldAbort = xhr.abort;
+			xhr.abort = function() {
+				if ( xhr ) {
+					oldAbort.call( xhr );
+				}
+
+				onreadystatechange( "abort" );
+			};
+		} catch(e) { }
+
+		// Timeout checker
+		if ( s.async && s.timeout > 0 ) {
+			setTimeout(function() {
+				// Check to see if the request is still happening
+				if ( xhr && !requestDone ) {
+					onreadystatechange( "timeout" );
+				}
+			}, s.timeout);
+		}
+
+		// Send the data
+		try {
+			xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
+		} catch(e) {
+			jQuery.handleError(s, xhr, null, e);
+			// Fire the complete handlers
+			complete();
+		}
+
+		// firefox 1.5 doesn't fire statechange for sync requests
+		if ( !s.async ) {
+			onreadystatechange();
+		}
+
+		function success() {
+			// If a local callback was specified, fire it and pass it the data
+			if ( s.success ) {
+				s.success.call( callbackContext, data, status, xhr );
+			}
+
+			// Fire the global callback
+			if ( s.global ) {
+				trigger( "ajaxSuccess", [xhr, s] );
+			}
+		}
+
+		function complete() {
+			// Process result
+			if ( s.complete ) {
+				s.complete.call( callbackContext, xhr, status);
+			}
+
+			// The request was completed
+			if ( s.global ) {
+				trigger( "ajaxComplete", [xhr, s] );
+			}
+
+			// Handle the global AJAX counter
+			if ( s.global && ! --jQuery.active ) {
+				jQuery.event.trigger( "ajaxStop" );
+			}
+		}
+		
+		function trigger(type, args) {
+			(s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
+		}
+
+		// return XMLHttpRequest to allow aborting the request etc.
+		return xhr;
+	},
+
+	handleError: function( s, xhr, status, e ) {
+		// If a local callback was specified, fire it
+		if ( s.error ) {
+			s.error.call( s.context || s, xhr, status, e );
+		}
+
+		// Fire the global callback
+		if ( s.global ) {
+			(s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
+		}
+	},
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Determines if an XMLHttpRequest was successful or not
+	httpSuccess: function( xhr ) {
+		try {
+			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+			return !xhr.status && location.protocol === "file:" ||
+				// Opera returns 0 when status is 304
+				( xhr.status >= 200 && xhr.status < 300 ) ||
+				xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
+		} catch(e) {}
+
+		return false;
+	},
+
+	// Determines if an XMLHttpRequest returns NotModified
+	httpNotModified: function( xhr, url ) {
+		var lastModified = xhr.getResponseHeader("Last-Modified"),
+			etag = xhr.getResponseHeader("Etag");
+
+		if ( lastModified ) {
+			jQuery.lastModified[url] = lastModified;
+		}
+
+		if ( etag ) {
+			jQuery.etag[url] = etag;
+		}
+
+		// Opera returns 0 when status is 304
+		return xhr.status === 304 || xhr.status === 0;
+	},
+
+	httpData: function( xhr, type, s ) {
+		var ct = xhr.getResponseHeader("content-type") || "",
+			xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+			data = xml ? xhr.responseXML : xhr.responseText;
+
+		if ( xml && data.documentElement.nodeName === "parsererror" ) {
+			jQuery.error( "parsererror" );
+		}
+
+		// Allow a pre-filtering function to sanitize the response
+		// s is checked to keep backwards compatibility
+		if ( s && s.dataFilter ) {
+			data = s.dataFilter( data, type );
+		}
+
+		// The filter can actually parse the response
+		if ( typeof data === "string" ) {
+			// Get the JavaScript object, if JSON is used.
+			if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+				data = jQuery.parseJSON( data );
+
+			// If the type is "script", eval it in global context
+			} else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+				jQuery.globalEval( data );
+			}
+		}
+
+		return data;
+	},
+
+	// Serialize an array of form elements or a set of
+	// key/values into a query string
+	param: function( a, traditional ) {
+		var s = [];
+		
+		// Set traditional to true for jQuery <= 1.3.2 behavior.
+		if ( traditional === undefined ) {
+			traditional = jQuery.ajaxSettings.traditional;
+		}
+		
+		// If an array was passed in, assume that it is an array of form elements.
+		if ( jQuery.isArray(a) || a.jquery ) {
+			// Serialize the form elements
+			jQuery.each( a, function() {
+				add( this.name, this.value );
+			});
+			
+		} else {
+			// If traditional, encode the "old" way (the way 1.3.2 or older
+			// did it), otherwise encode params recursively.
+			for ( var prefix in a ) {
+				buildParams( prefix, a[prefix] );
+			}
+		}
+
+		// Return the resulting serialization
+		return s.join("&").replace(r20, "+");
+
+		function buildParams( prefix, obj ) {
+			if ( jQuery.isArray(obj) ) {
+				// Serialize array item.
+				jQuery.each( obj, function( i, v ) {
+					if ( traditional || /\[\]$/.test( prefix ) ) {
+						// Treat each array item as a scalar.
+						add( prefix, v );
+					} else {
+						// If array item is non-scalar (array or object), encode its
+						// numeric index to resolve deserialization ambiguity issues.
+						// Note that rack (as of 1.0.0) can't currently deserialize
+						// nested arrays properly, and attempting to do so may cause
+						// a server error. Possible fixes are to modify rack's
+						// deserialization algorithm or to provide an option or flag
+						// to force array serialization to be shallow.
+						buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
+					}
+				});
+					
+			} else if ( !traditional && obj != null && typeof obj === "object" ) {
+				// Serialize object item.
+				jQuery.each( obj, function( k, v ) {
+					buildParams( prefix + "[" + k + "]", v );
+				});
+					
+			} else {
+				// Serialize scalar item.
+				add( prefix, obj );
+			}
+		}
+
+		function add( key, value ) {
+			// If value is a function, invoke it and return its value
+			value = jQuery.isFunction(value) ? value() : value;
+			s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+		}
+	}
+});
+var elemdisplay = {},
+	rfxtypes = /toggle|show|hide/,
+	rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
+	timerId,
+	fxAttrs = [
+		// height animations
+		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+		// width animations
+		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+		// opacity animations
+		[ "opacity" ]
+	];
+
+jQuery.fn.extend({
+	show: function( speed, callback ) {
+		if ( speed || speed === 0) {
+			return this.animate( genFx("show", 3), speed, callback);
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var old = jQuery.data(this[i], "olddisplay");
+
+				this[i].style.display = old || "";
+
+				if ( jQuery.css(this[i], "display") === "none" ) {
+					var nodeName = this[i].nodeName, display;
+
+					if ( elemdisplay[ nodeName ] ) {
+						display = elemdisplay[ nodeName ];
+
+					} else {
+						var elem = jQuery("<" + nodeName + " />").appendTo("body");
+
+						display = elem.css("display");
+
+						if ( display === "none" ) {
+							display = "block";
+						}
+
+						elem.remove();
+
+						elemdisplay[ nodeName ] = display;
+					}
+
+					jQuery.data(this[i], "olddisplay", display);
+				}
+			}
+
+			// Set the display of the elements in a second loop
+			// to avoid the constant reflow
+			for ( var j = 0, k = this.length; j < k; j++ ) {
+				this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
+			}
+
+			return this;
+		}
+	},
+
+	hide: function( speed, callback ) {
+		if ( speed || speed === 0 ) {
+			return this.animate( genFx("hide", 3), speed, callback);
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var old = jQuery.data(this[i], "olddisplay");
+				if ( !old && old !== "none" ) {
+					jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+				}
+			}
+
+			// Set the display of the elements in a second loop
+			// to avoid the constant reflow
+			for ( var j = 0, k = this.length; j < k; j++ ) {
+				this[j].style.display = "none";
+			}
+
+			return this;
+		}
+	},
+
+	// Save the old toggle function
+	_toggle: jQuery.fn.toggle,
+
+	toggle: function( fn, fn2 ) {
+		var bool = typeof fn === "boolean";
+
+		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+			this._toggle.apply( this, arguments );
+
+		} else if ( fn == null || bool ) {
+			this.each(function() {
+				var state = bool ? fn : jQuery(this).is(":hidden");
+				jQuery(this)[ state ? "show" : "hide" ]();
+			});
+
+		} else {
+			this.animate(genFx("toggle", 3), fn, fn2);
+		}
+
+		return this;
+	},
+
+	fadeTo: function( speed, to, callback ) {
+		return this.filter(":hidden").css("opacity", 0).show().end()
+					.animate({opacity: to}, speed, callback);
+	},
+
+	animate: function( prop, speed, easing, callback ) {
+		var optall = jQuery.speed(speed, easing, callback);
+
+		if ( jQuery.isEmptyObject( prop ) ) {
+			return this.each( optall.complete );
+		}
+
+		return this[ optall.queue === false ? "each" : "queue" ](function() {
+			var opt = jQuery.extend({}, optall), p,
+				hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
+				self = this;
+
+			for ( p in prop ) {
+				var name = p.replace(rdashAlpha, fcamelCase);
+
+				if ( p !== name ) {
+					prop[ name ] = prop[ p ];
+					delete prop[ p ];
+					p = name;
+				}
+
+				if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+					return opt.complete.call(this);
+				}
+
+				if ( ( p === "height" || p === "width" ) && this.style ) {
+					// Store display property
+					opt.display = jQuery.css(this, "display");
+
+					// Make sure that nothing sneaks out
+					opt.overflow = this.style.overflow;
+				}
+
+				if ( jQuery.isArray( prop[p] ) ) {
+					// Create (if needed) and add to specialEasing
+					(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+					prop[p] = prop[p][0];
+				}
+			}
+
+			if ( opt.overflow != null ) {
+				this.style.overflow = "hidden";
+			}
+
+			opt.curAnim = jQuery.extend({}, prop);
+
+			jQuery.each( prop, function( name, val ) {
+				var e = new jQuery.fx( self, opt, name );
+
+				if ( rfxtypes.test(val) ) {
+					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+				} else {
+					var parts = rfxnum.exec(val),
+						start = e.cur(true) || 0;
+
+					if ( parts ) {
+						var end = parseFloat( parts[2] ),
+							unit = parts[3] || "px";
+
+						// We need to compute starting value
+						if ( unit !== "px" ) {
+							self.style[ name ] = (end || 1) + unit;
+							start = ((end || 1) / e.cur(true)) * start;
+							self.style[ name ] = start + unit;
+						}
+
+						// If a +=/-= token was provided, we're doing a relative animation
+						if ( parts[1] ) {
+							end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+						}
+
+						e.custom( start, end, unit );
+
+					} else {
+						e.custom( start, val, "" );
+					}
+				}
+			});
+
+			// For JS strict compliance
+			return true;
+		});
+	},
+
+	stop: function( clearQueue, gotoEnd ) {
+		var timers = jQuery.timers;
+
+		if ( clearQueue ) {
+			this.queue([]);
+		}
+
+		this.each(function() {
+			// go in reverse order so anything added to the queue during the loop is ignored
+			for ( var i = timers.length - 1; i >= 0; i-- ) {
+				if ( timers[i].elem === this ) {
+					if (gotoEnd) {
+						// force the next step to be the last
+						timers[i](true);
+					}
+
+					timers.splice(i, 1);
+				}
+			}
+		});
+
+		// start the next in the queue if the last step wasn't forced
+		if ( !gotoEnd ) {
+			this.dequeue();
+		}
+
+		return this;
+	}
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+	slideDown: genFx("show", 1),
+	slideUp: genFx("hide", 1),
+	slideToggle: genFx("toggle", 1),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, callback ) {
+		return this.animate( props, speed, callback );
+	};
+});
+
+jQuery.extend({
+	speed: function( speed, easing, fn ) {
+		var opt = speed && typeof speed === "object" ? speed : {
+			complete: fn || !fn && easing ||
+				jQuery.isFunction( speed ) && speed,
+			duration: speed,
+			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+		};
+
+		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+			jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+		// Queueing
+		opt.old = opt.complete;
+		opt.complete = function() {
+			if ( opt.queue !== false ) {
+				jQuery(this).dequeue();
+			}
+			if ( jQuery.isFunction( opt.old ) ) {
+				opt.old.call( this );
+			}
+		};
+
+		return opt;
+	},
+
+	easing: {
+		linear: function( p, n, firstNum, diff ) {
+			return firstNum + diff * p;
+		},
+		swing: function( p, n, firstNum, diff ) {
+			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+		}
+	},
+
+	timers: [],
+
+	fx: function( elem, options, prop ) {
+		this.options = options;
+		this.elem = elem;
+		this.prop = prop;
+
+		if ( !options.orig ) {
+			options.orig = {};
+		}
+	}
+
+});
+
+jQuery.fx.prototype = {
+	// Simple function for setting a style value
+	update: function() {
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+		// Set display property to block for height/width animations
+		if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
+			this.elem.style.display = "block";
+		}
+	},
+
+	// Get the current size
+	cur: function( force ) {
+		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+			return this.elem[ this.prop ];
+		}
+
+		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+	},
+
+	// Start an animation from one number to another
+	custom: function( from, to, unit ) {
+		this.startTime = now();
+		this.start = from;
+		this.end = to;
+		this.unit = unit || this.unit || "px";
+		this.now = this.start;
+		this.pos = this.state = 0;
+
+		var self = this;
+		function t( gotoEnd ) {
+			return self.step(gotoEnd);
+		}
+
+		t.elem = this.elem;
+
+		if ( t() && jQuery.timers.push(t) && !timerId ) {
+			timerId = setInterval(jQuery.fx.tick, 13);
+		}
+	},
+
+	// Simple 'show' function
+	show: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.show = true;
+
+		// Begin the animation
+		// Make sure that we start at a small width/height to avoid any
+		// flash of content
+		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+		// Start by showing the element
+		jQuery( this.elem ).show();
+	},
+
+	// Simple 'hide' function
+	hide: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.hide = true;
+
+		// Begin the animation
+		this.custom(this.cur(), 0);
+	},
+
+	// Each step of an animation
+	step: function( gotoEnd ) {
+		var t = now(), done = true;
+
+		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+			this.now = this.end;
+			this.pos = this.state = 1;
+			this.update();
+
+			this.options.curAnim[ this.prop ] = true;
+
+			for ( var i in this.options.curAnim ) {
+				if ( this.options.curAnim[i] !== true ) {
+					done = false;
+				}
+			}
+
+			if ( done ) {
+				if ( this.options.display != null ) {
+					// Reset the overflow
+					this.elem.style.overflow = this.options.overflow;
+
+					// Reset the display
+					var old = jQuery.data(this.elem, "olddisplay");
+					this.elem.style.display = old ? old : this.options.display;
+
+					if ( jQuery.css(this.elem, "display") === "none" ) {
+						this.elem.style.display = "block";
+					}
+				}
+
+				// Hide the element if the "hide" operation was done
+				if ( this.options.hide ) {
+					jQuery(this.elem).hide();
+				}
+
+				// Reset the properties, if the item has been hidden or shown
+				if ( this.options.hide || this.options.show ) {
+					for ( var p in this.options.curAnim ) {
+						jQuery.style(this.elem, p, this.options.orig[p]);
+					}
+				}
+
+				// Execute the complete function
+				this.options.complete.call( this.elem );
+			}
+
+			return false;
+
+		} else {
+			var n = t - this.startTime;
+			this.state = n / this.options.duration;
+
+			// Perform the easing function, defaults to swing
+			var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+			var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+			this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+			this.now = this.start + ((this.end - this.start) * this.pos);
+
+			// Perform the next step of the animation
+			this.update();
+		}
+
+		return true;
+	}
+};
+
+jQuery.extend( jQuery.fx, {
+	tick: function() {
+		var timers = jQuery.timers;
+
+		for ( var i = 0; i < timers.length; i++ ) {
+			if ( !timers[i]() ) {
+				timers.splice(i--, 1);
+			}
+		}
+
+		if ( !timers.length ) {
+			jQuery.fx.stop();
+		}
+	},
+		
+	stop: function() {
+		clearInterval( timerId );
+		timerId = null;
+	},
+	
+	speeds: {
+		slow: 600,
+ 		fast: 200,
+ 		// Default speed
+ 		_default: 400
+	},
+
+	step: {
+		opacity: function( fx ) {
+			jQuery.style(fx.elem, "opacity", fx.now);
+		},
+
+		_default: function( fx ) {
+			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+			} else {
+				fx.elem[ fx.prop ] = fx.now;
+			}
+		}
+	}
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.animated = function( elem ) {
+		return jQuery.grep(jQuery.timers, function( fn ) {
+			return elem === fn.elem;
+		}).length;
+	};
+}
+
+function genFx( type, num ) {
+	var obj = {};
+
+	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+		obj[ this ] = type;
+	});
+
+	return obj;
+}
+if ( "getBoundingClientRect" in document.documentElement ) {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0];
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
+			clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+			top  = box.top  + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
+			left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+
+		return { top: top, left: left };
+	};
+
+} else {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0];
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		jQuery.offset.initialize();
+
+		var offsetParent = elem.offsetParent, prevOffsetParent = elem,
+			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+			body = doc.body, defaultView = doc.defaultView,
+			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+			top = elem.offsetTop, left = elem.offsetLeft;
+
+		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+				break;
+			}
+
+			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+			top  -= elem.scrollTop;
+			left -= elem.scrollLeft;
+
+			if ( elem === offsetParent ) {
+				top  += elem.offsetTop;
+				left += elem.offsetLeft;
+
+				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
+					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+				}
+
+				prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+			}
+
+			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+			}
+
+			prevComputedStyle = computedStyle;
+		}
+
+		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+			top  += body.offsetTop;
+			left += body.offsetLeft;
+		}
+
+		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+			top  += Math.max( docElem.scrollTop, body.scrollTop );
+			left += Math.max( docElem.scrollLeft, body.scrollLeft );
+		}
+
+		return { top: top, left: left };
+	};
+}
+
+jQuery.offset = {
+	initialize: function() {
+		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
+			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+		container.innerHTML = html;
+		body.insertBefore( container, body.firstChild );
+		innerDiv = container.firstChild;
+		checkDiv = innerDiv.firstChild;
+		td = innerDiv.nextSibling.firstChild.firstChild;
+
+		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+		checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
+		// safari subtracts parent border width here which is 5px
+		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+		checkDiv.style.position = checkDiv.style.top = "";
+
+		innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
+		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+		body.removeChild( container );
+		body = container = innerDiv = checkDiv = table = td = null;
+		jQuery.offset.initialize = jQuery.noop;
+	},
+
+	bodyOffset: function( body ) {
+		var top = body.offsetTop, left = body.offsetLeft;
+
+		jQuery.offset.initialize();
+
+		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+			top  += parseFloat( jQuery.curCSS(body, "marginTop",  true) ) || 0;
+			left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
+		}
+
+		return { top: top, left: left };
+	},
+	
+	setOffset: function( elem, options, i ) {
+		// set position first, in-case top/left are set even on static elem
+		if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
+			elem.style.position = "relative";
+		}
+		var curElem   = jQuery( elem ),
+			curOffset = curElem.offset(),
+			curTop    = parseInt( jQuery.curCSS( elem, "top",  true ), 10 ) || 0,
+			curLeft   = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
+
+		if ( jQuery.isFunction( options ) ) {
+			options = options.call( elem, i, curOffset );
+		}
+
+		var props = {
+			top:  (options.top  - curOffset.top)  + curTop,
+			left: (options.left - curOffset.left) + curLeft
+		};
+		
+		if ( "using" in options ) {
+			options.using.call( elem, props );
+		} else {
+			curElem.css( props );
+		}
+	}
+};
+
+
+jQuery.fn.extend({
+	position: function() {
+		if ( !this[0] ) {
+			return null;
+		}
+
+		var elem = this[0],
+
+		// Get *real* offsetParent
+		offsetParent = this.offsetParent(),
+
+		// Get correct offsets
+		offset       = this.offset(),
+		parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+		// Subtract element margins
+		// note: when an element has margin: auto the offsetLeft and marginLeft
+		// are the same in Safari causing offset.left to incorrectly be 0
+		offset.top  -= parseFloat( jQuery.curCSS(elem, "marginTop",  true) ) || 0;
+		offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
+
+		// Add offsetParent borders
+		parentOffset.top  += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth",  true) ) || 0;
+		parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
+
+		// Subtract the two offsets
+		return {
+			top:  offset.top  - parentOffset.top,
+			left: offset.left - parentOffset.left
+		};
+	},
+
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || document.body;
+			while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent;
+		});
+	}
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+	var method = "scroll" + name;
+
+	jQuery.fn[ method ] = function(val) {
+		var elem = this[0], win;
+		
+		if ( !elem ) {
+			return null;
+		}
+
+		if ( val !== undefined ) {
+			// Set the scroll offset
+			return this.each(function() {
+				win = getWindow( this );
+
+				if ( win ) {
+					win.scrollTo(
+						!i ? val : jQuery(win).scrollLeft(),
+						 i ? val : jQuery(win).scrollTop()
+					);
+
+				} else {
+					this[ method ] = val;
+				}
+			});
+		} else {
+			win = getWindow( elem );
+
+			// Return the scroll offset
+			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+				jQuery.support.boxModel && win.document.documentElement[ method ] ||
+					win.document.body[ method ] :
+				elem[ method ];
+		}
+	};
+});
+
+function getWindow( elem ) {
+	return ("scrollTo" in elem && elem.document) ?
+		elem :
+		elem.nodeType === 9 ?
+			elem.defaultView || elem.parentWindow :
+			false;
+}
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+	var type = name.toLowerCase();
+
+	// innerHeight and innerWidth
+	jQuery.fn["inner" + name] = function() {
+		return this[0] ?
+			jQuery.css( this[0], type, false, "padding" ) :
+			null;
+	};
+
+	// outerHeight and outerWidth
+	jQuery.fn["outer" + name] = function( margin ) {
+		return this[0] ?
+			jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
+			null;
+	};
+
+	jQuery.fn[ type ] = function( size ) {
+		// Get window width or height
+		var elem = this[0];
+		if ( !elem ) {
+			return size == null ? null : this;
+		}
+		
+		if ( jQuery.isFunction( size ) ) {
+			return this.each(function( i ) {
+				var self = jQuery( this );
+				self[ type ]( size.call( this, i, self[ type ]() ) );
+			});
+		}
+
+		return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
+			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+			elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+			elem.document.body[ "client" + name ] :
+
+			// Get document width or height
+			(elem.nodeType === 9) ? // is it a document
+				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+				Math.max(
+					elem.documentElement["client" + name],
+					elem.body["scroll" + name], elem.documentElement["scroll" + name],
+					elem.body["offset" + name], elem.documentElement["offset" + name]
+				) :
+
+				// Get or set width or height on the element
+				size === undefined ?
+					// Get width or height on the element
+					jQuery.css( elem, type ) :
+
+					// Set the width or height on the element (default to pixels if value is unitless)
+					this.css( type, typeof size === "string" ? size : size + "px" );
+	};
+
+});
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+})(window);
--- a/web/data/jquery.ui.css	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/jquery.ui.css	Wed Oct 13 08:37:21 2010 +0200
@@ -1,8 +1,12 @@
 /*
-* jQuery UI CSS Framework
-* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
-* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
-*/
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
 
 /* Layout helpers
 ----------------------------------*/
@@ -37,18 +41,23 @@
 .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
 
 
-
 /*
-* jQuery UI CSS Framework
-* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
-* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
-* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
-*/
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+ */
 
 
 /* Component containers
 ----------------------------------*/
 .ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
 .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
 .ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
 .ui-widget-content a { color: #333333; }
@@ -57,23 +66,24 @@
 
 /* Interaction states
 ----------------------------------*/
-.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; outline: none; }
-.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; outline: none; }
-.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; outline: none; }
-.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; outline: none; }
-.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; outline: none; }
-.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; outline: none; text-decoration: none; }
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
+.ui-widget :active { outline: none; }
 
 /* Interaction Cues
 ----------------------------------*/
-.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
-.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
-.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
-.ui-state-error a, .ui-widget-content .ui-state-error a { color: #ffffff; }
-.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #ffffff; }
-.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
-.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
-.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
 
 /* Icons
 ----------------------------------*/
@@ -224,6 +234,8 @@
 .ui-icon-seek-next { background-position: -32px -160px; }
 .ui-icon-seek-prev { background-position: -48px -160px; }
 .ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
 .ui-icon-seek-first { background-position: -80px -160px; }
 .ui-icon-stop { background-position: -96px -160px; }
 .ui-icon-eject { background-position: -112px -160px; }
@@ -268,28 +280,227 @@
 ----------------------------------*/
 
 /* Corner radius */
-.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
-.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
-.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
-.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
-.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
-.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
-.ui-corner-right {  -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
-.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
-.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-right {  -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
 
 /* Overlays */
 .ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
-.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; }/* Accordion
-----------------------------------*/
+.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
+ * jQuery UI Resizable @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
+ * jQuery UI Selectable @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*
+ * jQuery UI Accordion @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
 .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
 .ui-accordion .ui-accordion-li-fix { display: inline; }
 .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
-.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
 .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
-.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
-.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
-----------------------------------*/
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }/*
+ * jQuery UI Autocomplete @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }	
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+	list-style:none;
+	padding: 2px;
+	margin: 0;
+	display:block;
+	float: left;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+	margin:0;
+	padding: 0;
+	zoom: 1;
+	float: left;
+	clear: left;
+	width: 100%;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration:none;
+	display:block;
+	padding:.2em .4em;
+	line-height:1.5;
+	zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+/*
+ * jQuery UI Button @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; } 
+button.ui-button-icons-only { width: 3.7em; } 
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4;  }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*
+ * jQuery UI Dialog @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } 
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*
+ * jQuery UI Slider @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
+ * jQuery UI Tabs @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*
+ * jQuery UI Datepicker @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
 .ui-datepicker { width: 17em; padding: .2em .2em 0; }
 .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
 .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
@@ -300,11 +511,10 @@
 .ui-datepicker .ui-datepicker-next-hover { right:1px; }
 .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
 .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
-.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
 .ui-datepicker select.ui-datepicker-month-year {width: 100%;}
 .ui-datepicker select.ui-datepicker-month, 
 .ui-datepicker select.ui-datepicker-year { width: 49%;}
-.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
 .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
 .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
 .ui-datepicker td { border: 0; padding: 1px; }
@@ -349,58 +559,14 @@
     left: -4px; /*must have*/
     width: 200px; /*must have*/
     height: 200px; /*must have*/
-}/* Dialog
-----------------------------------*/
-.ui-dialog { position: relative; padding: .2em; width: 300px; }
-.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative;  }
-.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; } 
-.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
-.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
-.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
-.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
-.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
-.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
-.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
-.ui-draggable .ui-dialog-titlebar { cursor: move; }
-/* Progressbar
-----------------------------------*/
+}/*
+ * jQuery UI Progressbar @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
 .ui-progressbar { height:2em; text-align: left; }
-.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
-----------------------------------*/
-.ui-resizable { position: relative;}
-.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
-.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
-.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
-.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
-.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
-.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
-.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
-.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
-.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
-.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
-----------------------------------*/
-.ui-slider { position: relative; text-align: left; }
-.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
-.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
-
-.ui-slider-horizontal { height: .8em; }
-.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
-.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
-.ui-slider-horizontal .ui-slider-range-min { left: 0; }
-.ui-slider-horizontal .ui-slider-range-max { right: 0; }
-
-.ui-slider-vertical { width: .8em; height: 100px; }
-.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
-.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
-.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
-.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
-----------------------------------*/
-.ui-tabs { padding: .2em; zoom: 1; }
-.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
-.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
-.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
-.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
-.ui-tabs .ui-tabs-hide { display: none !important; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file
--- a/web/data/jquery.ui.js	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/jquery.ui.js	Wed Oct 13 08:37:21 2010 +0200
@@ -1,298 +1,778 @@
-/*
- * jQuery UI 1.7.2
+/*!
+ * jQuery UI 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI
  */
-jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/*
- * jQuery UI Draggable 1.7.2
+(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.5",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,
+NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,
+"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");
+if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind("mousedown.ui-disableSelection selectstart.ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,
+"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c.style(this,h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c.style(this,
+h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
+c(function(){var a=document.createElement("div"),b=document.body;c.extend(a.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.appendChild(a).offsetHeight===100;b.removeChild(a).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,
+d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
+;/*!
+ * jQuery UI Widget 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
+a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)===
+"_")return h;e?this.each(function(){var g=b.data(this,a);if(!g)throw"cannot call methods on "+a+" prior to initialization; attempted to call method '"+d+"'";if(!b.isFunction(g[d]))throw"no such method '"+d+"' for "+a+" widget instance";var i=g[d].apply(g,f);if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",
+widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+
+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}b.each(d,function(f,h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",
+false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
+;/*!
+ * jQuery UI Mouse 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ *	jquery.ui.widget.js
+ */
+(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&
+this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();
+return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&
+this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-
+a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
+;/*
+ * jQuery UI Position 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Position
+ */
+(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.scrollTo&&d.document){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j=
+{top:b.of.pageY,left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/
+2;if(b.at[1]==="bottom")j.top+=k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+parseInt(c.curCSS(this,"marginRight",true))||0,w=m+q+parseInt(c.curCSS(this,"marginBottom",true))||0,i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]===
+"center")i.top-=m/2;i.left=parseInt(i.left);i.top=parseInt(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();
+b.left=d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];
+b.left+=a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=
+c(b),g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
+;/*
+ * jQuery UI Draggable 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Draggables
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
  */
-(function(a){a.widget("ui.draggable",a.extend({},a.ui.mouse,{_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.addClasses&&this.element.addClass("ui-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},destroy:function(){if(!this.element.data("draggable")){return}this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")){return false}this.handle=this._getHandle(b);if(!this.handle){return false}return true},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b);this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;if(c.cursorAt){this._adjustOffsetFromHelper(c.cursorAt)}if(c.containment){this._setContainment()}this._trigger("start",b);this._cacheHelperProportions();if(a.ui.ddmanager&&!c.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,b)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(b,true);return true},_mouseDrag:function(b,d){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();this._trigger("drag",b,c);this.position=c.position}if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,b)}return false},_mouseStop:function(c){var d=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){d=a.ui.ddmanager.drop(this,c)}if(this.dropped){d=this.dropped;this.dropped=false}if((this.options.revert=="invalid"&&!d)||(this.options.revert=="valid"&&d)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d))){var b=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){b._trigger("stop",c);b._clear()})}else{this._trigger("stop",c);this._clear()}return false},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==b.target){c=true}});return c},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c])):(d.helper=="clone"?this.element.clone():this.element);if(!b.parents("body").length){b.appendTo((d.appendTo=="parent"?this.element[0].parentNode:d.appendTo))}if(b[0]!=this.element[0]&&!(/(fixed|absolute)/).test(b.css("position"))){b.css("position","absolute")}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.element.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)&&e.containment.constructor!=Array){var c=a(e.containment)[0];if(!c){return}var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}else{if(e.containment.constructor==Array){this.containment=e.containment}}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(i?0:b.scrollTop())))),left:(d-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:b.scrollLeft())))}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");if(this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false},_trigger:function(b,c,d){d=d||this._uiHash();a.ui.plugin.call(this,b,[c,d]);if(b=="drag"){this.positionAbs=this._convertPositionTo("absolute")}return a.widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(b){return{helper:this.helper,position:this.position,absolutePosition:this.positionAbs,offset:this.positionAbs}}}));a.extend(a.ui.draggable,{version:"1.7.2",eventPrefix:"drag",defaults:{addClasses:true,appendTo:"parent",axis:false,cancel:":input,option",connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false}});a.ui.plugin.add("draggable","connectToSortable",{start:function(c,e){var d=a(this).data("draggable"),f=d.options,b=a.extend({},e,{item:d.element});d.sortables=[];a(f.connectToSortable).each(function(){var g=a.data(this,"sortable");if(g&&!g.options.disabled){d.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",c,b)}})},stop:function(c,e){var d=a(this).data("draggable"),b=a.extend({},e,{item:d.element});a.each(d.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;d.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=true}this.instance._mouseStop(c);this.instance.options.helper=this.instance.options._helper;if(d.options.helper=="original"){this.instance.currentItem.css({top:"auto",left:"auto"})}}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",c,b)}})},drag:function(c,f){var e=a(this).data("draggable"),b=this;var d=function(i){var n=this.offset.click.top,m=this.offset.click.left;var g=this.positionAbs.top,k=this.positionAbs.left;var j=i.height,l=i.width;var p=i.top,h=i.left;return a.ui.isOver(g+n,k+m,p,h,j,l)};a.each(e.sortables,function(g){this.instance.positionAbs=e.positionAbs;this.instance.helperProportions=e.helperProportions;this.instance.offset.click=e.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=a(b).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return f.helper[0]};c.target=this.instance.currentItem[0];this.instance._mouseCapture(c,true);this.instance._mouseStart(c,true,true);this.instance.offset.click.top=e.offset.click.top;this.instance.offset.click.left=e.offset.click.left;this.instance.offset.parent.left-=e.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=e.offset.parent.top-this.instance.offset.parent.top;e._trigger("toSortable",c);e.dropped=this.instance.element;e.currentItem=e.element;this.instance.fromOutside=e}if(this.instance.currentItem){this.instance._mouseDrag(c)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",c,this.instance._uiHash(this.instance));this.instance._mouseStop(c,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}e._trigger("fromSortable",c);e.dropped=false}}})}});a.ui.plugin.add("draggable","cursor",{start:function(c,d){var b=a("body"),e=a(this).data("draggable").options;if(b.css("cursor")){e._cursor=b.css("cursor")}b.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._cursor){a("body").css("cursor",d._cursor)}}});a.ui.plugin.add("draggable","iframeFix",{start:function(b,c){var d=a(this).data("draggable").options;a(d.iframeFix===true?"iframe":d.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(a(this).offset()).appendTo("body")})},stop:function(b,c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});a.ui.plugin.add("draggable","opacity",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("opacity")){e._opacity=b.css("opacity")}b.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._opacity){a(c.helper).css("opacity",d._opacity)}}});a.ui.plugin.add("draggable","scroll",{start:function(c,d){var b=a(this).data("draggable");if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){b.overflowOffset=b.scrollParent.offset()}},drag:function(d,e){var c=a(this).data("draggable"),f=c.options,b=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!f.axis||f.axis!="x"){if((c.overflowOffset.top+c.scrollParent[0].offsetHeight)-d.pageY<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop+f.scrollSpeed}else{if(d.pageY-c.overflowOffset.top<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop-f.scrollSpeed}}}if(!f.axis||f.axis!="y"){if((c.overflowOffset.left+c.scrollParent[0].offsetWidth)-d.pageX<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft+f.scrollSpeed}else{if(d.pageX-c.overflowOffset.left<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft-f.scrollSpeed}}}}else{if(!f.axis||f.axis!="x"){if(d.pageY-a(document).scrollTop()<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-f.scrollSpeed)}else{if(a(window).height()-(d.pageY-a(document).scrollTop())<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+f.scrollSpeed)}}}if(!f.axis||f.axis!="y"){if(d.pageX-a(document).scrollLeft()<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-f.scrollSpeed)}else{if(a(window).width()-(d.pageX-a(document).scrollLeft())<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+f.scrollSpeed)}}}}if(b!==false&&a.ui.ddmanager&&!f.dropBehaviour){a.ui.ddmanager.prepareOffsets(c,d)}}});a.ui.plugin.add("draggable","snap",{start:function(c,d){var b=a(this).data("draggable"),e=b.options;b.snapElements=[];a(e.snap.constructor!=String?(e.snap.items||":data(draggable)"):e.snap).each(function(){var g=a(this);var f=g.offset();if(this!=b.element[0]){b.snapElements.push({item:this,width:g.outerWidth(),height:g.outerHeight(),top:f.top,left:f.left})}})},drag:function(u,p){var g=a(this).data("draggable"),q=g.options;var y=q.snapTolerance;var x=p.offset.left,w=x+g.helperProportions.width,f=p.offset.top,e=f+g.helperProportions.height;for(var v=g.snapElements.length-1;v>=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y<x&&x<n+y&&m-y<f&&f<A+y)||(s-y<x&&x<n+y&&m-y<e&&e<A+y)||(s-y<w&&w<n+y&&m-y<f&&f<A+y)||(s-y<w&&w<n+y&&m-y<e&&e<A+y))){if(g.snapElements[v].snapping){(g.options.snap.release&&g.options.snap.release.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=false;continue}if(q.snapMode!="inner"){var c=Math.abs(m-e)<=y;var z=Math.abs(A-f)<=y;var j=Math.abs(s-w)<=y;var k=Math.abs(n-x)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m-g.helperProportions.height,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s-g.helperProportions.width}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n}).left-g.margins.left}}var h=(c||z||j||k);if(q.snapMode!="outer"){var c=Math.abs(m-f)<=y;var z=Math.abs(A-e)<=y;var j=Math.abs(s-x)<=y;var k=Math.abs(n-w)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A-g.helperProportions.height,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n-g.helperProportions.width}).left-g.margins.left}}if(!g.snapElements[v].snapping&&(c||z||j||k||h)){(g.options.snap.snap&&g.options.snap.snap.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=(c||z||j||k||h)}}});a.ui.plugin.add("draggable","stack",{start:function(b,c){var e=a(this).data("draggable").options;var d=a.makeArray(a(e.stack.group)).sort(function(g,f){return(parseInt(a(g).css("zIndex"),10)||e.stack.min)-(parseInt(a(f).css("zIndex"),10)||e.stack.min)});a(d).each(function(f){this.style.zIndex=e.stack.min+f});this[0].style.zIndex=e.stack.min+d.length}});a.ui.plugin.add("draggable","zIndex",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("zIndex")){e._zIndex=b.css("zIndex")}b.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._zIndex){a(c.helper).css("zIndex",d._zIndex)}}})})(jQuery);;/*
- * jQuery UI Droppable 1.7.2
+(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
+"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
+this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-
+this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();
+d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||
+this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,
+b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==
+a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||
+0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
+this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-
+(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment==
+"parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&
+a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),
+10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
+this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():
+f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])e=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+
+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;e=this.originalPageX+
+Math.round((e-this.originalPageX)/b.grid[0])*b.grid[0];e=this.containment?!(e-this.offset.click.left<this.containment[0]||e-this.offset.click.left>this.containment[2])?e:!(e-this.offset.click.left<this.containment[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-
+this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=
+this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.5"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var g=d.data(this,"sortable");
+if(g&&!g.options.disabled){c.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;
+c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=
+1;this.instance.currentItem=d(f).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;
+this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=
+this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","iframeFix",{start:function(){var a=
+d(this).data("draggable").options;d(a.iframeFix===true?"iframe":a.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;
+if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!=
+"HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-
+b.overflowOffset.left<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-
+c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,
+width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,g=b.offset.left,n=g+c.helperProportions.width,m=b.offset.top,o=m+c.helperProportions.height,h=c.snapElements.length-1;h>=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e<g&&g<k+e&&j-e<m&&m<l+e||i-e<g&&g<k+e&&j-e<o&&o<l+e||i-e<n&&n<k+e&&j-e<m&&m<l+e||i-e<n&&n<k+e&&j-e<o&&
+o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=
+p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&
+(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),
+10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
+;/*
+ * jQuery UI Droppable 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Droppables
  *
  * Depends:
- *	ui.core.js
- *	ui.draggable.js
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.draggable.js
  */
-(function(a){a.widget("ui.droppable",{_init:function(){var c=this.options,b=c.accept;this.isover=0;this.isout=1;this.options.accept=this.options.accept&&a.isFunction(this.options.accept)?this.options.accept:function(e){return e.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};a.ui.ddmanager.droppables[this.options.scope]=a.ui.ddmanager.droppables[this.options.scope]||[];a.ui.ddmanager.droppables[this.options.scope].push(this);(this.options.addClasses&&this.element.addClass("ui-droppable"))},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++){if(b[c]==this){b.splice(c,1)}}this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable")},_setData:function(b,c){if(b=="accept"){this.options.accept=c&&a.isFunction(c)?c:function(e){return e.is(c)}}else{a.widget.prototype._setData.apply(this,arguments)}},_activate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.addClass(this.options.activeClass)}(b&&this._trigger("activate",c,this.ui(b)))},_deactivate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}(b&&this._trigger("deactivate",c,this.ui(b)))},_over:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.addClass(this.options.hoverClass)}this._trigger("over",c,this.ui(b))}},_out:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("out",c,this.ui(b))}},_drop:function(c,d){var b=d||a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return false}var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var f=a.data(this,"droppable");if(f.options.greedy&&a.ui.intersect(b,a.extend(f,{offset:f.element.offset()}),f.options.tolerance)){e=true;return false}});if(e){return false}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("drop",c,this.ui(b));return this.element}return false},ui:function(b){return{draggable:(b.currentItem||b.element),helper:b.helper,position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs}}});a.extend(a.ui.droppable,{version:"1.7.2",eventPrefix:"drop",defaults:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"}});a.ui.intersect=function(q,j,o){if(!j.offset){return false}var e=(q.positionAbs||q.position.absolute).left,d=e+q.helperProportions.width,n=(q.positionAbs||q.position.absolute).top,m=n+q.helperProportions.height;var g=j.offset.left,c=g+j.proportions.width,p=j.offset.top,k=p+j.proportions.height;switch(o){case"fit":return(g<e&&d<c&&p<n&&m<k);break;case"intersect":return(g<e+(q.helperProportions.width/2)&&d-(q.helperProportions.width/2)<c&&p<n+(q.helperProportions.height/2)&&m-(q.helperProportions.height/2)<k);break;case"pointer":var h=((q.positionAbs||q.position.absolute).left+(q.clickOffset||q.offset.click).left),i=((q.positionAbs||q.position.absolute).top+(q.clickOffset||q.offset.click).top),f=a.ui.isOver(i,h,p,g,j.proportions.height,j.proportions.width);return f;break;case"touch":return((n>=p&&n<=k)||(m>=p&&m<=k)||(n<p&&m>k))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(e<g&&d>c));break;default:return false;break}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,g){var b=a.ui.ddmanager.droppables[e.options.scope];var f=g?g.type:null;var h=(e.currentItem||e.element).find(":data(droppable)").andSelf();droppablesLoop:for(var d=0;d<b.length;d++){if(b[d].options.disabled||(e&&!b[d].options.accept.call(b[d].element[0],(e.currentItem||e.element)))){continue}for(var c=0;c<h.length;c++){if(h[c]==b[d].element[0]){b[d].proportions.height=0;continue droppablesLoop}}b[d].visible=b[d].element.css("display")!="none";if(!b[d].visible){continue}b[d].offset=b[d].element.offset();b[d].proportions={width:b[d].element[0].offsetWidth,height:b[d].element[0].offsetHeight};if(f=="mousedown"){b[d]._activate.call(b[d],g)}}},drop:function(b,c){var d=false;a.each(a.ui.ddmanager.droppables[b.options.scope],function(){if(!this.options){return}if(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)){d=this._drop.call(this,c)}if(!this.options.disabled&&this.visible&&this.options.accept.call(this.element[0],(b.currentItem||b.element))){this.isout=1;this.isover=0;this._deactivate.call(this,c)}});return d},drag:function(b,c){if(b.options.refreshPositions){a.ui.ddmanager.prepareOffsets(b,c)}a.each(a.ui.ddmanager.droppables[b.options.scope],function(){if(this.options.disabled||this.greedyChild||!this.visible){return}var e=a.ui.intersect(b,this,this.options.tolerance);var g=!e&&this.isover==1?"isout":(e&&this.isover==0?"isover":null);if(!g){return}var f;if(this.options.greedy){var d=this.element.parents(":data(droppable):eq(0)");if(d.length){f=a.data(d[0],"droppable");f.greedyChild=(g=="isover"?1:0)}}if(f&&g=="isover"){f.isover=0;f.isout=1;f._out.call(f,c)}this[g]=1;this[g=="isout"?"isover":"isout"]=0;this[g=="isover"?"_over":"_out"].call(this,c);if(f&&g=="isout"){f.isout=0;f.isover=1;f._over.call(f,c)}})}}})(jQuery);;/*
- * jQuery UI Resizable 1.7.2
+(function(d){d.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,b=a.accept;this.isover=0;this.isout=1;this.accept=d.isFunction(b)?b:function(c){return c.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};d.ui.ddmanager.droppables[a.scope]=d.ui.ddmanager.droppables[a.scope]||[];d.ui.ddmanager.droppables[a.scope].push(this);
+a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=d.ui.ddmanager.droppables[this.options.scope],b=0;b<a.length;b++)a[b]==this&&a.splice(b,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,b){if(a=="accept")this.accept=d.isFunction(b)?b:function(c){return c.is(b)};d.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&
+this.element.addClass(this.options.activeClass);b&&this._trigger("activate",a,this.ui(b))},_deactivate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);b&&this._trigger("deactivate",a,this.ui(b))},_over:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
+this._trigger("over",a,this.ui(b))}},_out:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",a,this.ui(b))}},_drop:function(a,b){var c=b||d.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return false;var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g=
+d.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==c.options.scope&&g.accept.call(g.element[0],c.currentItem||c.element)&&d.ui.intersect(c,d.extend(g,{offset:g.element.offset()}),g.options.tolerance)){e=true;return false}});if(e)return false;if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop",
+a,this.ui(c));return this.element}return false},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}});d.extend(d.ui.droppable,{version:"1.8.5"});d.ui.intersect=function(a,b,c){if(!b.offset)return false;var e=(a.positionAbs||a.position.absolute).left,g=e+a.helperProportions.width,f=(a.positionAbs||a.position.absolute).top,h=f+a.helperProportions.height,i=b.offset.left,k=i+b.proportions.width,j=b.offset.top,l=j+b.proportions.height;
+switch(c){case "fit":return i<=e&&g<=k&&j<=f&&h<=l;case "intersect":return i<e+a.helperProportions.width/2&&g-a.helperProportions.width/2<k&&j<f+a.helperProportions.height/2&&h-a.helperProportions.height/2<l;case "pointer":return d.ui.isOver((a.positionAbs||a.position.absolute).top+(a.clickOffset||a.offset.click).top,(a.positionAbs||a.position.absolute).left+(a.clickOffset||a.offset.click).left,j,i,b.proportions.height,b.proportions.width);case "touch":return(f>=j&&f<=l||h>=j&&h<=l||f<j&&h>l)&&(e>=
+i&&e<=k||g>=i&&g<=k||e<i&&g>k);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f<c.length;f++)if(!(c[f].options.disabled||a&&!c[f].accept.call(c[f].element[0],a.currentItem||a.element))){for(var h=0;h<g.length;h++)if(g[h]==c[f].element[0]){c[f].proportions.height=0;continue a}c[f].visible=c[f].element.css("display")!=
+"none";if(c[f].visible){c[f].offset=c[f].element.offset();c[f].proportions={width:c[f].element[0].offsetWidth,height:c[f].element[0].offsetHeight};e=="mousedown"&&c[f]._activate.call(c[f],b)}}},drop:function(a,b){var c=false;d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&d.ui.intersect(a,this,this.options.tolerance))c=c||this._drop.call(this,b);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem||
+a.element)){this.isout=1;this.isover=0;this._deactivate.call(this,b)}}});return c},drag:function(a,b){a.options.refreshPositions&&d.ui.ddmanager.prepareOffsets(a,b);d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var c=d.ui.intersect(a,this,this.options.tolerance);if(c=!c&&this.isover==1?"isout":c&&this.isover==0?"isover":null){var e;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){e=
+d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})}}})(jQuery);
+;/*
+ * jQuery UI Resizable 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Resizables
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
  */
-(function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f<k.length;f++){var h=c.trim(k[f]),d="ui-resizable-"+h;var g=c('<div class="ui-resizable-handle '+d+'"></div>');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidth<k.width),l=a(k.height)&&h.maxHeight&&(h.maxHeight<k.height),g=a(k.width)&&h.minWidth&&(h.minWidth>k.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e<this._proportionallyResizeElements.length;e++){var g=this._proportionallyResizeElements[e];if(!this.borderDif){var d=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],h=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=c.map(d,function(k,m){var l=parseInt(k,10)||0,n=parseInt(h[m],10)||0;return l+n})}if(c.browser.msie&&!(!(c(f).is(":hidden")||c(f).parents(":hidden").length))){continue}g.css({height:(f.height()-this.borderDif[0]-this.borderDif[2])||0,width:(f.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var e=this.element,h=this.options;this.elementOffset=e.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));c.extend(c.ui.resizable,{version:"1.7.2",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,t){var s=(q[t]||0)+(j[t]||0);if(s&&s>=0){o[t]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=s._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)){s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/s.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*s.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);;/*
- * jQuery UI Selectable 1.7.2
+(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
+_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
+top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
+this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
+nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
+String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),k=0;k=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,k);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
+this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){e(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};
+if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),
+d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=
+this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:
+this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",
+b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;
+f={width:c.size.width-(f?0:c.sizeDiff.width),height:c.size.height-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",
+b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(l(b.left))this.position.left=b.left;if(l(b.top))this.position.top=b.top;if(l(b.height))this.size.height=b.height;if(l(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=
+a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,d=l(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=l(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=l(b.width)&&a.minWidth&&a.minWidth>b.width,h=l(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,
+k=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&k)b.left=i-a.minWidth;if(d&&k)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),
+c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=
+this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+
+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,
+arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,
+{version:"1.8.5"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,
+function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var k=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:k.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=
+(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(k.css("position"))){c._revertToRelativePosition=true;k.css({position:"absolute",top:"auto",left:"auto"})}k.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=
+false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-
+a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",
+b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top",
+"Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,
+f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=
+a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+
+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&
+e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",
+height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=
+d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
+;/*
+ * jQuery UI Selectable 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Selectables
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
  */
-(function(a){a.widget("ui.selectable",a.extend({},a.ui.mouse,{_init:function(){var b=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]);c.each(function(){var d=a(this);var e=d.offset();a.data(this,"selectable-item",{element:this,$element:d,left:e.left,top:e.top,right:e.left+d.outerWidth(),bottom:e.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(d){var b=this;this.opos=[d.pageX,d.pageY];if(this.options.disabled){return}var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",d);a(c.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:d.clientX,top:d.clientY,width:0,height:0});if(c.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var e=a.data(this,"selectable-item");e.startselected=true;if(!d.metaKey){e.$element.removeClass("ui-selected");e.selected=false;e.$element.addClass("ui-unselecting");e.unselecting=true;b._trigger("unselecting",d,{unselecting:e.element})}});a(d.target).parents().andSelf().each(function(){var e=a.data(this,"selectable-item");if(e){e.$element.removeClass("ui-unselecting").addClass("ui-selecting");e.unselecting=false;e.selecting=true;e.selected=true;b._trigger("selecting",d,{selecting:e.element});return false}})},_mouseDrag:function(i){var c=this;this.dragged=true;if(this.options.disabled){return}var e=this.options;var d=this.opos[0],h=this.opos[1],b=i.pageX,g=i.pageY;if(d>b){var f=b;b=d;d=f}if(h>g){var f=g;g=h;h=f}this.helper.css({left:d,top:h,width:b-d,height:g-h});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!j||j.element==c.element[0]){return}var k=false;if(e.tolerance=="touch"){k=(!(j.left>b||j.right<d||j.top>g||j.bottom<h))}else{if(e.tolerance=="fit"){k=(j.left>d&&j.right<b&&j.top>h&&j.bottom<g)}}if(k){if(j.selected){j.$element.removeClass("ui-selected");j.selected=false}if(j.unselecting){j.$element.removeClass("ui-unselecting");j.unselecting=false}if(!j.selecting){j.$element.addClass("ui-selecting");j.selecting=true;c._trigger("selecting",i,{selecting:j.element})}}else{if(j.selecting){if(i.metaKey&&j.startselected){j.$element.removeClass("ui-selecting");j.selecting=false;j.$element.addClass("ui-selected");j.selected=true}else{j.$element.removeClass("ui-selecting");j.selecting=false;if(j.startselected){j.$element.addClass("ui-unselecting");j.unselecting=true}c._trigger("unselecting",i,{unselecting:j.element})}}if(j.selected){if(!i.metaKey&&!j.startselected){j.$element.removeClass("ui-selected");j.selected=false;j.$element.addClass("ui-unselecting");j.unselecting=true;c._trigger("unselecting",i,{unselecting:j.element})}}}});return false},_mouseStop:function(d){var b=this;this.dragged=false;var c=this.options;a(".ui-unselecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-unselecting");e.unselecting=false;e.startselected=false;b._trigger("unselected",d,{unselected:e.element})});a(".ui-selecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-selecting").addClass("ui-selected");e.selecting=false;e.selected=true;e.startselected=true;b._trigger("selected",d,{selected:e.element})});this._trigger("stop",d);this.helper.remove();return false}}));a.extend(a.ui.selectable,{version:"1.7.2",defaults:{appendTo:"body",autoRefresh:true,cancel:":input,option",delay:0,distance:0,filter:"*",tolerance:"touch"}})})(jQuery);;/*
- * jQuery UI Sortable 1.7.2
+(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),
+selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX,
+c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting",
+c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d=
+this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.right<b||a.top>i||a.bottom<g);else if(d.tolerance=="fit")k=a.left>b&&a.right<h&&a.top>g&&a.bottom<i;if(k){if(a.selected){a.$element.removeClass("ui-selected");a.selected=false}if(a.unselecting){a.$element.removeClass("ui-unselecting");
+a.unselecting=false}if(!a.selecting){a.$element.addClass("ui-selecting");a.selecting=true;f._trigger("selecting",c,{selecting:a.element})}}else{if(a.selecting)if(c.metaKey&&a.startselected){a.$element.removeClass("ui-selecting");a.selecting=false;a.$element.addClass("ui-selected");a.selected=true}else{a.$element.removeClass("ui-selecting");a.selecting=false;if(a.startselected){a.$element.addClass("ui-unselecting");a.unselecting=true}f._trigger("unselecting",c,{unselecting:a.element})}if(a.selected)if(!c.metaKey&&
+!a.startselected){a.$element.removeClass("ui-selected");a.selected=false;a.$element.addClass("ui-unselecting");a.unselecting=true;f._trigger("unselecting",c,{unselecting:a.element})}}}});return false}},_mouseStop:function(c){var f=this;this.dragged=false;e(".ui-unselecting",this.element[0]).each(function(){var d=e.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=false;d.startselected=false;f._trigger("unselected",c,{unselected:d.element})});e(".ui-selecting",this.element[0]).each(function(){var d=
+e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.8.5"})})(jQuery);
+;/*
+ * jQuery UI Sortable 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Sortables
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
  */
-(function(a){a.widget("ui.sortable",a.extend({},a.ui.mouse,{_init:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--){this.items[b].item.removeData("sortable-item")}},_mouseCapture:function(e,f){if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(e);var d=null,c=this,b=a(e.target).parents().each(function(){if(a.data(this,"sortable-item")==c){d=a(this);return false}});if(a.data(e.target,"sortable-item")==c){d=a(e.target)}if(!d){return false}if(this.options.handle&&!f){var g=false;a(this.options.handle,d).find("*").andSelf().each(function(){if(this==e.target){g=true}});if(!g){return false}}this.currentItem=d;this._removeCurrentsFromItems();return true},_mouseStart:function(e,f,b){var g=this.options,c=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(e);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(e);this.originalPageX=e.pageX;this.originalPageY=e.pageY;if(g.cursorAt){this._adjustOffsetFromHelper(g.cursorAt)}this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(g.containment){this._setContainment()}if(g.cursor){if(a("body").css("cursor")){this._storedCursor=a("body").css("cursor")}a("body").css("cursor",g.cursor)}if(g.opacity){if(this.helper.css("opacity")){this._storedOpacity=this.helper.css("opacity")}this.helper.css("opacity",g.opacity)}if(g.zIndex){if(this.helper.css("zIndex")){this._storedZIndex=this.helper.css("zIndex")}this.helper.css("zIndex",g.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){this.overflowOffset=this.scrollParent.offset()}this._trigger("start",e,this._uiHash());if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!b){for(var d=this.containers.length-1;d>=0;d--){this.containers[d]._trigger("activate",e,c._uiHash(this))}}if(a.ui.ddmanager){a.ui.ddmanager.current=this}if(a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,e)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(e);return true},_mouseDrag:function(f){this.position=this._generatePosition(f);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}if(this.options.scroll){var g=this.options,b=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-f.pageY<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop+g.scrollSpeed}else{if(f.pageY-this.overflowOffset.top<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop-g.scrollSpeed}}if((this.overflowOffset.left+this.scrollParent[0].offsetWidth)-f.pageX<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft+g.scrollSpeed}else{if(f.pageX-this.overflowOffset.left<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft-g.scrollSpeed}}}else{if(f.pageY-a(document).scrollTop()<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-g.scrollSpeed)}else{if(a(window).height()-(f.pageY-a(document).scrollTop())<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+g.scrollSpeed)}}if(f.pageX-a(document).scrollLeft()<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-g.scrollSpeed)}else{if(a(window).width()-(f.pageX-a(document).scrollLeft())<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+g.scrollSpeed)}}}if(b!==false&&a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,f)}}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}for(var d=this.items.length-1;d>=0;d--){var e=this.items[d],c=e.item[0],h=this._intersectsWithPointer(e);if(!h){continue}if(c!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=c&&!a.ui.contains(this.placeholder[0],c)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],c):true)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e)){this._rearrange(f,e)}else{break}this._trigger("change",f,this._uiHash());break}}this._contactContainers(f);if(a.ui.ddmanager){a.ui.ddmanager.drag(this,f)}this._trigger("sort",f,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(c,d){if(!c){return}if(a.ui.ddmanager&&!this.options.dropBehaviour){a.ui.ddmanager.drop(this,c)}if(this.options.revert){var b=this;var e=b.placeholder.offset();b.reverting=true;a(this.helper).animate({left:e.left-this.offset.parent.left-b.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-b.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){b._clear(c)})}else{this._clear(c,d)}return false},cancel:function(){var b=this;if(this.dragging){this._mouseUp();if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,b._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,b._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){a(this.domPosition.prev).after(this.currentItem)}else{a(this.domPosition.parent).prepend(this.currentItem)}return true},serialize:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};a(b).each(function(){var e=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||(/(.+)[-=_](.+)/));if(e){c.push((d.key||e[1]+"[]")+"="+(d.key&&d.expression?e[1]:e[2]))}});return c.join("&")},toArray:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};b.each(function(){c.push(a(d.item||this).attr(d.attribute||"id")||"")});return c},_intersectsWith:function(m){var e=this.positionAbs.left,d=e+this.helperProportions.width,k=this.positionAbs.top,j=k+this.helperProportions.height;var f=m.left,c=f+m.width,n=m.top,i=n+m.height;var o=this.offset.click.top,h=this.offset.click.left;var g=(k+o)>n&&(k+o)<i&&(e+h)>f&&(e+h)<c;if(this.options.tolerance=="pointer"||this.options.forcePointerForContainers||(this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>m[this.floating?"width":"height"])){return g}else{return(f<e+(this.helperProportions.width/2)&&d-(this.helperProportions.width/2)<c&&n<k+(this.helperProportions.height/2)&&j-(this.helperProportions.height/2)<i)}},_intersectsWithPointer:function(d){var e=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top,d.height),c=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left,d.width),g=e&&c,b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(!g){return false}return this.floating?(((f&&f=="right")||b=="down")?2:1):(b&&(b=="down"?2:1))},_intersectsWithSides:function(e){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+(e.height/2),e.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+(e.width/2),e.width),b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(this.floating&&f){return((f=="right"&&d)||(f=="left"&&!d))}else{return b&&((b=="down"&&c)||(b=="up"&&!c))}},_getDragVerticalDirection:function(){var b=this.positionAbs.top-this.lastPositionAbs.top;return b!=0&&(b>0?"down":"up")},_getDragHorizontalDirection:function(){var b=this.positionAbs.left-this.lastPositionAbs.left;return b!=0&&(b>0?"right":"left")},refresh:function(b){this._refreshItems(b);this.refreshPositions()},_connectWith:function(){var b=this.options;return b.connectWith.constructor==String?[b.connectWith]:b.connectWith},_getItemsAsjQuery:function(b){var l=this;var g=[];var e=[];var h=this._connectWith();if(h&&b){for(var d=h.length-1;d>=0;d--){var k=a(h[d]);for(var c=k.length-1;c>=0;c--){var f=a.data(k[c],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element):a(f.options.items,f.element).not(".ui-sortable-helper"),f])}}}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var d=e.length-1;d>=0;d--){e[d][0].each(function(){g.push(this)})}return a(g)},_removeCurrentsFromItems:function(){var d=this.currentItem.find(":data(sortable-item)");for(var c=0;c<this.items.length;c++){for(var b=0;b<d.length;b++){if(d[b]==this.items[c].item[0]){this.items.splice(c,1)}}}},_refreshItems:function(b){this.items=[];this.containers=[this];var h=this.items;var p=this;var f=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]];var l=this._connectWith();if(l){for(var e=l.length-1;e>=0;e--){var m=a(l[e]);for(var d=m.length-1;d>=0;d--){var g=a.data(m[d],"sortable");if(g&&g!=this&&!g.options.disabled){f.push([a.isFunction(g.options.items)?g.options.items.call(g.element[0],b,{item:this.currentItem}):a(g.options.items,g.element),g]);this.containers.push(g)}}}}for(var e=f.length-1;e>=0;e--){var k=f[e][1];var c=f[e][0];for(var d=0,n=c.length;d<n;d++){var o=a(c[d]);o.data("sortable-item",k);h.push({item:o,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){if(this.offsetParent&&this.helper){this.offset.parent=this._getParentOffset()}for(var d=this.items.length-1;d>=0;d--){var e=this.items[d];if(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0]){continue}var c=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!b){e.width=c.outerWidth();e.height=c.outerHeight()}var f=c.offset();e.left=f.left;e.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var d=this.containers.length-1;d>=0;d--){var f=this.containers[d].element.offset();this.containers[d].containerCache.left=f.left;this.containers[d].containerCache.top=f.top;this.containers[d].containerCache.width=this.containers[d].element.outerWidth();this.containers[d].containerCache.height=this.containers[d].element.outerHeight()}}},_createPlaceholder:function(d){var b=d||this,e=b.options;if(!e.placeholder||e.placeholder.constructor==String){var c=e.placeholder;e.placeholder={element:function(){var f=a(document.createElement(b.currentItem[0].nodeName)).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!c){f.style.visibility="hidden"}return f},update:function(f,g){if(c&&!e.forcePlaceholderSize){return}if(!g.height()){g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10))}if(!g.width()){g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=a(e.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);e.placeholder.update(b,b.placeholder)},_contactContainers:function(d){for(var c=this.containers.length-1;c>=0;c--){if(this._intersectsWith(this.containers[c].containerCache)){if(!this.containers[c].containerCache.over){if(this.currentContainer!=this.containers[c]){var h=10000;var g=null;var e=this.positionAbs[this.containers[c].floating?"left":"top"];for(var b=this.items.length-1;b>=0;b--){if(!a.ui.contains(this.containers[c].element[0],this.items[b].item[0])){continue}var f=this.items[b][this.containers[c].floating?"left":"top"];if(Math.abs(f-e)<h){h=Math.abs(f-e);g=this.items[b]}}if(!g&&!this.options.dropOnEmpty){continue}this.currentContainer=this.containers[c];g?this._rearrange(d,g,null,true):this._rearrange(d,null,this.containers[c].element,true);this._trigger("change",d,this._uiHash());this.containers[c]._trigger("change",d,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder)}this.containers[c]._trigger("over",d,this._uiHash(this));this.containers[c].containerCache.over=1}}else{if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",d,this._uiHash(this));this.containers[c].containerCache.over=0}}}},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c,this.currentItem])):(d.helper=="clone"?this.currentItem.clone():this.currentItem);if(!b.parents("body").length){a(d.appendTo!="parent"?d.appendTo:this.currentItem[0].parentNode)[0].appendChild(b[0])}if(b[0]==this.currentItem[0]){this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}}if(b[0].style.width==""||d.forceHelperSize){b.width(this.currentItem.width())}if(b[0].style.height==""||d.forceHelperSize){b.height(this.currentItem.height())}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.currentItem.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.currentItem.css("marginLeft"),10)||0),top:(parseInt(this.currentItem.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)){var c=a(e.containment)[0];var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(i?0:b.scrollTop())))),left:(d-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:b.scrollLeft())))}},_rearrange:function(g,f,c,e){c?c[0].appendChild(this.placeholder[0]):f.item[0].parentNode.insertBefore(this.placeholder[0],(this.direction=="down"?f.item[0]:f.item[0].nextSibling));this.counter=this.counter?++this.counter:1;var d=this,b=this.counter;window.setTimeout(function(){if(b==d.counter){d.refreshPositions(!e)}},0)},_clear:function(d,e){this.reverting=false;var f=[],b=this;if(!this._noFinalSort&&this.currentItem[0].parentNode){this.placeholder.before(this.currentItem)}this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var c in this._storedCSS){if(this._storedCSS[c]=="auto"||this._storedCSS[c]=="static"){this._storedCSS[c]=""}}this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}if(this.fromOutside&&!e){f.push(function(g){this._trigger("receive",g,this._uiHash(this.fromOutside))})}if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!e){f.push(function(g){this._trigger("update",g,this._uiHash())})}if(!a.ui.contains(this.element[0],this.currentItem[0])){if(!e){f.push(function(g){this._trigger("remove",g,this._uiHash())})}for(var c=this.containers.length-1;c>=0;c--){if(a.ui.contains(this.containers[c].element[0],this.currentItem[0])&&!e){f.push((function(g){return function(h){g._trigger("receive",h,this._uiHash(this))}}).call(this,this.containers[c]));f.push((function(g){return function(h){g._trigger("update",h,this._uiHash(this))}}).call(this,this.containers[c]))}}}for(var c=this.containers.length-1;c>=0;c--){if(!e){f.push((function(g){return function(h){g._trigger("deactivate",h,this._uiHash(this))}}).call(this,this.containers[c]))}if(this.containers[c].containerCache.over){f.push((function(g){return function(h){g._trigger("out",h,this._uiHash(this))}}).call(this,this.containers[c]));this.containers[c].containerCache.over=0}}if(this._storedCursor){a("body").css("cursor",this._storedCursor)}if(this._storedOpacity){this.helper.css("opacity",this._storedOpacity)}if(this._storedZIndex){this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex)}this.dragging=false;if(this.cancelHelperRemoval){if(!e){this._trigger("beforeStop",d,this._uiHash());for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}return false}if(!e){this._trigger("beforeStop",d,this._uiHash())}this.placeholder[0].parentNode.removeChild(this.placeholder[0]);if(this.helper[0]!=this.currentItem[0]){this.helper.remove()}this.helper=null;if(!e){for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){if(a.widget.prototype._trigger.apply(this,arguments)===false){this.cancel()}},_uiHash:function(c){var b=c||this;return{helper:b.helper,placeholder:b.placeholder||a([]),position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs,item:b.currentItem,sender:c?c.element:null}}}));a.extend(a.ui.sortable,{getter:"serialize toArray",version:"1.7.2",eventPrefix:"sort",defaults:{appendTo:"parent",axis:false,cancel:":input,option",connectWith:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000}})})(jQuery);;/*
- * jQuery UI Accordion 1.7.2
+(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable");
+this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,
+arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=
+c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,
+{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();
+if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",
+a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");
+if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+
+this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()-b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+
+b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+
+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,
+c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==
+document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp();this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",
+null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):
+d(this.domPosition.parent).prepend(this.currentItem);return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")},toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||
+"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+
+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection();var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?
+2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},
+_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=
+this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=
+this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element),this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");
+if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&&this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=
+0;b--){var c=this.items[b],e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=
+this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},
+update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=
+null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));
+this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,
+null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||
+d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width==""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a==
+"string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition==
+"absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition==
+"relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},
+_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-
+this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),
+10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?
+this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=
+this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+
+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?
+g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():
+e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==
+f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem[0].parentNode&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",
+f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",
+g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=
+0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});
+d.extend(d.ui.sortable,{version:"1.8.5"})})(jQuery);
+;/*
+ * jQuery UI Accordion 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Accordion
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ */
+(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");
+a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
+if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var f=d.closest(".ui-accordion-header");a.active=f.length?f:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",function(g){return a._keydown(g)}).next().attr("role",
+"tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(g){a._clickHandler.call(a,g,this);g.preventDefault()})},_createIcons:function(){var a=this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+a.icons.header).prependTo(this.headers);
+this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabIndex");
+this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();
+b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,f=this.headers.index(a.target),g=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:g=this.headers[(f+1)%d];break;case b.LEFT:case b.UP:g=this.headers[(f-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);
+a.preventDefault()}if(g){c(a.target).attr("tabIndex",-1);c(g).attr("tabIndex",0);g.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+
+c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;
+if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);
+a.next().addClass("ui-accordion-content-active")}h=a.next();f=this.active.next();g={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):h,oldContent:f};d=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(h,f,g,b,d)}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
+this.active.next().addClass("ui-accordion-content-active");var f=this.active.next(),g={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:f},h=this.active=c([]);this._toggle(h,f,g)}},_toggle:function(a,b,d,f,g){var h=this,e=h.options;h.toShow=a;h.toHide=b;h.data=d;var j=function(){if(h)return h._completed.apply(h,arguments)};h._trigger("changestart",null,h.data);h.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&f?{toShow:c([]),toHide:b,complete:j,
+down:g,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:g,autoHeight:e.autoHeight||e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;f=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!f[k]&&!c.easing[k])k="slide";f[k]||(f[k]=function(l){this.slide(l,{easing:k,duration:i||700})});
+f[k](d)}else{if(e.collapsible&&f)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.5",animations:{slide:function(a,
+b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),f=0,g={},h={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){h[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);g[i]={value:j[1],
+unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(h,{step:function(j,i){if(i.prop=="height")f=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=f*g[i.prop].value+g[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",paddingTop:"hide",
+paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
+;/*
+ * jQuery UI Autocomplete 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ *	jquery.ui.position.js
  */
-(function(a){a.widget("ui.accordion",{_init:function(){var d=this.options,b=this;this.running=0;if(d.collapsible==a.ui.accordion.defaults.collapsible&&d.alwaysOpen!=a.ui.accordion.defaults.alwaysOpen){d.collapsible=!d.alwaysOpen}if(d.navigation){var c=this.element.find("a").filter(d.navigationFilter);if(c.length){if(c.filter(d.header).length){this.active=c}else{this.active=c.parent().parent().prev();c.addClass("ui-accordion-content-active")}}}this.element.addClass("ui-accordion ui-widget ui-helper-reset");if(this.element[0].nodeName=="UL"){this.element.children("li").addClass("ui-accordion-li-fix")}this.headers=this.element.find(d.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){a(this).removeClass("ui-state-focus")});this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");this.active=this._findActive(this.active||d.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");this.active.next().addClass("ui-accordion-content-active");a("<span/>").addClass("ui-icon "+d.icons.header).prependTo(this.headers);this.active.find(".ui-icon").toggleClass(d.icons.header).toggleClass(d.icons.headerSelected);if(a.browser.msie){this.element.find("a").css("zoom","1")}this.resize();this.element.attr("role","tablist");this.headers.attr("role","tab").bind("keydown",function(e){return b._keydown(e)}).next().attr("role","tabpanel");this.headers.not(this.active||"").attr("aria-expanded","false").attr("tabIndex","-1").next().hide();if(!this.active.length){this.headers.eq(0).attr("tabIndex","0")}else{this.active.attr("aria-expanded","true").attr("tabIndex","0")}if(!a.browser.safari){this.headers.find("a").attr("tabIndex","-1")}if(d.event){this.headers.bind((d.event)+".accordion",function(e){return b._clickHandler.call(b,e,this)})}},destroy:function(){var c=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role").unbind(".accordion").removeData("accordion");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabindex");this.headers.find("a").removeAttr("tabindex");this.headers.children(".ui-icon").remove();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active");if(c.autoHeight||c.fillHeight){b.css("height","")}},_setData:function(b,c){if(b=="alwaysOpen"){b="collapsible";c=!c}a.widget.prototype._setData.apply(this,arguments)},_keydown:function(e){var g=this.options,f=a.ui.keyCode;if(g.disabled||e.altKey||e.ctrlKey){return}var d=this.headers.length;var b=this.headers.index(e.target);var c=false;switch(e.keyCode){case f.RIGHT:case f.DOWN:c=this.headers[(b+1)%d];break;case f.LEFT:case f.UP:c=this.headers[(b-1+d)%d];break;case f.SPACE:case f.ENTER:return this._clickHandler({target:e.target},e.target)}if(c){a(e.target).attr("tabIndex","-1");a(c).attr("tabIndex","0");c.focus();return false}return true},resize:function(){var e=this.options,d;if(e.fillSpace){if(a.browser.msie){var b=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}d=this.element.parent().height();if(a.browser.msie){this.element.parent().css("overflow",b)}this.headers.each(function(){d-=a(this).outerHeight()});var c=0;this.headers.next().each(function(){c=Math.max(c,a(this).innerHeight()-a(this).height())}).height(Math.max(0,d-c)).css("overflow","auto")}else{if(e.autoHeight){d=0;this.headers.next().each(function(){d=Math.max(d,a(this).outerHeight())}).height(d)}}},activate:function(b){var c=this._findActive(b)[0];this._clickHandler({target:c},c)},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===false?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,f){var d=this.options;if(d.disabled){return false}if(!b.target&&d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var h=this.active.next(),e={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:h},c=(this.active=a([]));this._toggle(c,h,e);return false}var g=a(b.currentTarget||f);var i=g[0]==this.active[0];if(this.running||(!d.collapsible&&i)){return false}this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");if(!i){g.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").find(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);g.next().addClass("ui-accordion-content-active")}var c=g.next(),h=this.active.next(),e={options:d,newHeader:i&&d.collapsible?a([]):g,oldHeader:this.active,newContent:i&&d.collapsible?a([]):c.find("> *"),oldContent:h.find("> *")},j=this.headers.index(this.active[0])>this.headers.index(g[0]);this.active=i?a([]):g;this._toggle(c,h,e,i,j);return false},_toggle:function(b,i,g,j,k){var d=this.options,m=this;this.toShow=b;this.toHide=i;this.data=g;var c=function(){if(!m){return}return m._completed.apply(m,arguments)};this._trigger("changestart",null,this.data);this.running=i.size()===0?b.size():i.size();if(d.animated){var f={};if(d.collapsible&&j){f={toShow:a([]),toHide:i,complete:c,down:k,autoHeight:d.autoHeight||d.fillSpace}}else{f={toShow:b,toHide:i,complete:c,down:k,autoHeight:d.autoHeight||d.fillSpace}}if(!d.proxied){d.proxied=d.animated}if(!d.proxiedDuration){d.proxiedDuration=d.duration}d.animated=a.isFunction(d.proxied)?d.proxied(f):d.proxied;d.duration=a.isFunction(d.proxiedDuration)?d.proxiedDuration(f):d.proxiedDuration;var l=a.ui.accordion.animations,e=d.duration,h=d.animated;if(!l[h]){l[h]=function(n){this.slide(n,{easing:h,duration:e||700})}}l[h](f)}else{if(d.collapsible&&j){b.toggle()}else{i.hide();b.show()}c(true)}i.prev().attr("aria-expanded","false").attr("tabIndex","-1").blur();b.prev().attr("aria-expanded","true").attr("tabIndex","0").focus()},_completed:function(b){var c=this.options;this.running=b?0:--this.running;if(this.running){return}if(c.clearStyle){this.toShow.add(this.toHide).css({height:"",overflow:""})}this._trigger("change",null,this.data)}});a.extend(a.ui.accordion,{version:"1.7.2",defaults:{active:null,alwaysOpen:true,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},animations:{slide:function(j,h){j=a.extend({easing:"swing",duration:300},j,h);if(!j.toHide.size()){j.toShow.animate({height:"show"},j);return}if(!j.toShow.size()){j.toHide.animate({height:"hide"},j);return}var c=j.toShow.css("overflow"),g,d={},f={},e=["height","paddingTop","paddingBottom"],b;var i=j.toShow;b=i[0].style.width;i.width(parseInt(i.parent().width(),10)-parseInt(i.css("paddingLeft"),10)-parseInt(i.css("paddingRight"),10)-(parseInt(i.css("borderLeftWidth"),10)||0)-(parseInt(i.css("borderRightWidth"),10)||0));a.each(e,function(k,m){f[m]="hide";var l=(""+a.css(j.toShow[0],m)).match(/^([\d+-.]+)(.*)$/);d[m]={value:l[1],unit:l[2]||"px"}});j.toShow.css({height:0,overflow:"hidden"}).show();j.toHide.filter(":hidden").each(j.complete).end().filter(":visible").animate(f,{step:function(k,l){if(l.prop=="height"){g=(l.now-l.start)/(l.end-l.start)}j.toShow[0].style[l.prop]=(g*d[l.prop].value)+d[l.prop].unit},duration:j.duration,easing:j.easing,complete:function(){if(!j.autoHeight){j.toShow.css("height","")}j.toShow.css("width",b);j.toShow.css({overflow:c});j.complete()}})},bounceslide:function(b){this.slide(b,{easing:b.down?"easeOutBounce":"swing",duration:b.down?1000:200})},easeslide:function(b){this.slide(b,{easing:"easeinout",duration:700})}}})})(jQuery);;/*
- * jQuery UI Dialog 1.7.2
+(function(e){e.widget("ui.autocomplete",{options:{appendTo:"body",delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},_create:function(){var a=this,b=this.element[0].ownerDocument;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!a.options.disabled){var d=e.ui.keyCode;switch(c.keyCode){case d.PAGE_UP:a._move("previousPage",
+c);break;case d.PAGE_DOWN:a._move("nextPage",c);break;case d.UP:a._move("previous",c);c.preventDefault();break;case d.DOWN:a._move("next",c);c.preventDefault();break;case d.ENTER:case d.NUMPAD_ENTER:a.menu.element.is(":visible")&&c.preventDefault();case d.TAB:if(!a.menu.active)return;a.menu.select(c);break;case d.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);
+break}}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};this.menu=e("<ul></ul>").addClass("ui-autocomplete").appendTo(e(this.options.appendTo||"body",b)[0]).mousedown(function(c){var d=a.menu.element[0];
+c.target===d&&setTimeout(function(){e(document).one("mousedown",function(f){f.target!==a.element[0]&&f.target!==d&&!e.ui.contains(d,f.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,d){d=d.item.data("item.autocomplete");false!==a._trigger("focus",null,{item:d})&&/^key/.test(c.originalEvent.type)&&a.element.val(d.value)},selected:function(c,d){d=d.item.data("item.autocomplete");var f=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();
+a.previous=f}if(false!==a._trigger("select",c,{item:d})){a.term=d.value;a.element.val(d.value)}a.close(c);a.selectedItem=d},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");e.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");
+this.menu.element.remove();e.Widget.prototype.destroy.call(this)},_setOption:function(a,b){e.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(e(b||"body",this.element[0].ownerDocument)[0])},_initSource:function(){var a=this,b,c;if(e.isArray(this.options.source)){b=this.options.source;this.source=function(d,f){f(e.ui.autocomplete.filter(b,d.term))}}else if(typeof this.options.source==="string"){c=this.options.source;this.source=
+function(d,f){a.xhr&&a.xhr.abort();a.xhr=e.getJSON(c,d,function(g,i,h){h===a.xhr&&f(g);a.xhr=null})}}else this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search")!==false)return this._search(a)},_search:function(a){this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(a.length){a=
+this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this._trigger("close",a);this.menu.element.hide();this.menu.deactivate()}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return e.map(a,function(b){if(typeof b===
+"string")return{label:b,value:b};return e.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1),c;this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();this.menu.element.show().position(e.extend({of:this.element},this.options.position));a=b.width("").outerWidth();c=this.element.outerWidth();b.outerWidth(Math.max(a,c))},_renderMenu:function(a,b){var c=this;e.each(b,function(d,f){c._renderItem(a,f)})},
+_renderItem:function(a,b){return e("<li></li>").data("item.autocomplete",b).append(e("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});e.extend(e.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},
+filter:function(a,b){var c=new RegExp(e.ui.autocomplete.escapeRegex(b),"i");return e.grep(a,function(d){return c.test(d.label||d.value||d)})}})})(jQuery);
+(function(e){e.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(b){if(e(b.target).closest(".ui-menu-item a").length){b.preventDefault();a.select(b)}});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
+-1).mouseenter(function(b){a.activate(b,e(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.attr("scrollTop"),f=this.element.height();if(c<0)this.element.attr("scrollTop",d+c);else c>=f&&this.element.attr("scrollTop",d+c-f+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",a,{item:b})},
+deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(this.active){a=this.active[a+"All"](".ui-menu-item").eq(0);
+a.length?this.activate(c,a):this.activate(c,this.element.children(b))}else this.activate(c,this.element.children(b))},nextPage:function(a){if(this.hasScroll())if(!this.active||this.last())this.activate(a,this.element.children(":first"));else{var b=this.active.offset().top,c=this.element.height(),d=this.element.children("li").filter(function(){var f=e(this).offset().top-b-c+e(this).height();return f<10&&f>-10});d.length||(d=this.element.children(":last"));this.activate(a,d)}else this.activate(a,this.element.children(!this.active||
+this.last()?":first":":last"))},previousPage:function(a){if(this.hasScroll())if(!this.active||this.first())this.activate(a,this.element.children(":last"));else{var b=this.active.offset().top,c=this.element.height();result=this.element.children("li").filter(function(){var d=e(this).offset().top-b+c-e(this).height();return d<10&&d>-10});result.length||(result=this.element.children(":first"));this.activate(a,result)}else this.activate(a,this.element.children(!this.active||this.first()?":last":":first"))},
+hasScroll:function(){return this.element.height()<this.element.attr("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})})(jQuery);
+;/*
+ * jQuery UI Button 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * http://docs.jquery.com/UI/Button
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ */
+(function(a){var g,i=function(b){a(":ui-button",b.target.form).each(function(){var c=a(this).data("button");setTimeout(function(){c.refresh()},1)})},h=function(b){var c=b.name,d=b.form,e=a([]);if(c)e=d?a(d).find("[name='"+c+"']"):a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form});return e};a.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",
+i);if(typeof this.options.disabled!=="boolean")this.options.disabled=this.element.attr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var b=this,c=this.options,d=this.type==="checkbox"||this.type==="radio",e="ui-state-hover"+(!d?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",
+function(){if(!c.disabled){a(this).addClass("ui-state-hover");this===g&&a(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||a(this).removeClass(e)}).bind("focus.button",function(){a(this).addClass("ui-state-focus")}).bind("blur.button",function(){a(this).removeClass("ui-state-focus")});d&&this.element.bind("change.button",function(){b.refresh()});if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).toggleClass("ui-state-active");
+b.buttonElement.attr("aria-pressed",b.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");b.buttonElement.attr("aria-pressed",true);var f=b.element[0];h(f).not(f).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed",false)});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;a(this).addClass("ui-state-active");
+g=this;a(document).one("mouseup",function(){g=null})}).bind("mouseup.button",function(){if(c.disabled)return false;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(f){if(c.disabled)return false;if(f.keyCode==a.ui.keyCode.SPACE||f.keyCode==a.ui.keyCode.ENTER)a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(f){f.keyCode===a.ui.keyCode.SPACE&&a(this).click()})}this._setOption("disabled",
+c.disabled)},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type==="radio"){this.buttonElement=this.element.parents().last().find("label[for="+this.element.attr("id")+"]");this.element.addClass("ui-helper-hidden-accessible");var b=this.element.is(":checked");b&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",b)}else this.buttonElement=
+this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active  ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||
+this.buttonElement.removeAttr("title");a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled")c?this.element.attr("disabled",true):this.element.removeAttr("disabled");this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b);if(this.type==="radio")h(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
+true):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",false)});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",true):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",false)},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
+c=a("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary;if(d.primary||d.secondary){b.addClass("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary"));d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>");d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>");if(!this.options.text){b.addClass(e?"ui-button-icons-only":"ui-button-icon-only").removeClass("ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary");
+this.hasTitle||b.attr("title",c)}}else b.addClass("ui-button-text-only")}}});a.widget("ui.buttonset",{_create:function(){this.element.addClass("ui-buttonset");this._init()},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){this.buttons=this.element.find(":button, :submit, :reset, :checkbox, :radio, a, :data(button)").filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":visible").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end().end()},
+destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");a.Widget.prototype.destroy.call(this)}})})(jQuery);
+;/*
+ * jQuery UI Dialog 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Dialog
  *
  * Depends:
- *	ui.core.js
- *	ui.draggable.js
- *	ui.resizable.js
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ *  jquery.ui.button.js
+ *	jquery.ui.draggable.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.position.js
+ *	jquery.ui.resizable.js
  */
-(function(c){var b={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"},a="ui-dialog ui-widget ui-widget-content ui-corner-all ";c.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");var l=this,m=this.options,j=m.title||this.originalTitle||"&nbsp;",e=c.ui.dialog.getTitleId(this.element),k=(this.uiDialog=c("<div/>")).appendTo(document.body).hide().addClass(a+m.dialogClass).css({position:"absolute",overflow:"hidden",zIndex:m.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(n){(m.closeOnEscape&&n.keyCode&&n.keyCode==c.ui.keyCode.ESCAPE&&l.close(n))}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(n){l.moveToTop(false,n)}),g=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(k),f=(this.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(k),i=c('<a href="#"/>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){i.addClass("ui-state-hover")},function(){i.removeClass("ui-state-hover")}).focus(function(){i.addClass("ui-state-focus")}).blur(function(){i.removeClass("ui-state-focus")}).mousedown(function(n){n.stopPropagation()}).click(function(n){l.close(n);return false}).appendTo(f),h=(this.uiDialogTitlebarCloseText=c("<span/>")).addClass("ui-icon ui-icon-closethick").text(m.closeText).appendTo(i),d=c("<span/>").addClass("ui-dialog-title").attr("id",e).html(j).prependTo(f);f.find("*").add(f).disableSelection();(m.draggable&&c.fn.draggable&&this._makeDraggable());(m.resizable&&c.fn.resizable&&this._makeResizable());this._createButtons(m.buttons);this._isOpen=false;(m.bgiframe&&c.fn.bgiframe&&k.bgiframe());(m.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(f){var d=this;if(false===d._trigger("beforeclose",f)){return}(d.overlay&&d.overlay.destroy());d.uiDialog.unbind("keypress.ui-dialog");(d.options.hide?d.uiDialog.hide(d.options.hide,function(){d._trigger("close",f)}):d.uiDialog.hide()&&d._trigger("close",f));c.ui.dialog.overlay.resize();d._isOpen=false;if(d.options.modal){var e=0;c(".ui-dialog").each(function(){if(this!=d.uiDialog[0]){e=Math.max(e,c(this).css("z-index"))}});c.ui.dialog.maxZ=e}},isOpen:function(){return this._isOpen},moveToTop:function(f,e){if((this.options.modal&&!f)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",e)}if(this.options.zIndex>c.ui.dialog.maxZ){c.ui.dialog.maxZ=this.options.zIndex}(this.overlay&&this.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=++c.ui.dialog.maxZ));var d={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};this.uiDialog.css("z-index",++c.ui.dialog.maxZ);this.element.attr(d);this._trigger("focus",e)},open:function(){if(this._isOpen){return}var e=this.options,d=this.uiDialog;this.overlay=e.modal?new c.ui.dialog.overlay(this):null;(d.next().length&&d.appendTo("body"));this._size();this._position(e.position);d.show(e.show);this.moveToTop(true);(e.modal&&d.bind("keypress.ui-dialog",function(h){if(h.keyCode!=c.ui.keyCode.TAB){return}var g=c(":tabbable",this),i=g.filter(":first")[0],f=g.filter(":last")[0];if(h.target==f&&!h.shiftKey){setTimeout(function(){i.focus()},1)}else{if(h.target==i&&h.shiftKey){setTimeout(function(){f.focus()},1)}}}));c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();this._trigger("open");this._isOpen=true},_createButtons:function(g){var f=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");this.uiDialog.find(".ui-dialog-buttonpane").remove();(typeof g=="object"&&g!==null&&c.each(g,function(){return !(d=true)}));if(d){c.each(g,function(h,i){c('<button type="button"></button>').addClass("ui-state-default ui-corner-all").text(h).click(function(){i.apply(f.element[0],arguments)}).hover(function(){c(this).addClass("ui-state-hover")},function(){c(this).removeClass("ui-state-hover")}).focus(function(){c(this).addClass("ui-state-focus")}).blur(function(){c(this).removeClass("ui-state-focus")}).appendTo(e)});e.appendTo(this.uiDialog)}},_makeDraggable:function(){var d=this,f=this.options,e;this.uiDialog.draggable({cancel:".ui-dialog-content",handle:".ui-dialog-titlebar",containment:"document",start:function(){e=f.height;c(this).height(c(this).height()).addClass("ui-dialog-dragging");(f.dragStart&&f.dragStart.apply(d.element[0],arguments))},drag:function(){(f.drag&&f.drag.apply(d.element[0],arguments))},stop:function(){c(this).removeClass("ui-dialog-dragging").height(e);(f.dragStop&&f.dragStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}})},_makeResizable:function(g){g=(g===undefined?this.options.resizable:g);var d=this,f=this.options,e=typeof g=="string"?g:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",alsoResize:this.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:f.minHeight,start:function(){c(this).addClass("ui-dialog-resizing");(f.resizeStart&&f.resizeStart.apply(d.element[0],arguments))},resize:function(){(f.resize&&f.resize.apply(d.element[0],arguments))},handles:e,stop:function(){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();(f.resizeStop&&f.resizeStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}}).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_position:function(i){var e=c(window),f=c(document),g=f.scrollTop(),d=f.scrollLeft(),h=g;if(c.inArray(i,["center","top","right","bottom","left"])>=0){i=[i=="right"||i=="left"?i:"center",i=="top"||i=="bottom"?i:"middle"]}if(i.constructor!=Array){i=["center","middle"]}if(i[0].constructor==Number){d+=i[0]}else{switch(i[0]){case"left":d+=0;break;case"right":d+=e.width()-this.uiDialog.outerWidth();break;default:case"center":d+=(e.width()-this.uiDialog.outerWidth())/2}}if(i[1].constructor==Number){g+=i[1]}else{switch(i[1]){case"top":g+=0;break;case"bottom":g+=e.height()-this.uiDialog.outerHeight();break;default:case"middle":g+=(e.height()-this.uiDialog.outerHeight())/2}}g=Math.max(g,h);this.uiDialog.css({top:g,left:d})},_setData:function(e,f){(b[e]&&this.uiDialog.data(b[e],f));switch(e){case"buttons":this._createButtons(f);break;case"closeText":this.uiDialogTitlebarCloseText.text(f);break;case"dialogClass":this.uiDialog.removeClass(this.options.dialogClass).addClass(a+f);break;case"draggable":(f?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(f);break;case"position":this._position(f);break;case"resizable":var d=this.uiDialog,g=this.uiDialog.is(":data(resizable)");(g&&!f&&d.resizable("destroy"));(g&&typeof f=="string"&&d.resizable("option","handles",f));(g||this._makeResizable(f));break;case"title":c(".ui-dialog-title",this.uiDialogTitlebar).html(f||"&nbsp;");break;case"width":this.uiDialog.width(f);break}c.widget.prototype._setData.apply(this,arguments)},_size:function(){var e=this.options;this.element.css({height:0,minHeight:0,width:"auto"});var d=this.uiDialog.css({height:"auto",width:e.width}).height();this.element.css({minHeight:Math.max(e.minHeight-d,0),height:e.height=="auto"?"auto":Math.max(e.height-d,0)})}});c.extend(c.ui.dialog,{version:"1.7.2",defaults:{autoOpen:true,bgiframe:false,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1000},getter:"isOpen",uuid:0,maxZ:0,getTitleId:function(d){return"ui-dialog-title-"+(d.attr("id")||++this.uuid)},overlay:function(d){this.$el=c.ui.dialog.overlay.create(d)}});c.extend(c.ui.dialog.overlay,{instances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(d){return d+".dialog-overlay"}).join(" "),create:function(e){if(this.instances.length===0){setTimeout(function(){if(c.ui.dialog.overlay.instances.length){c(document).bind(c.ui.dialog.overlay.events,function(f){var g=c(f.target).parents(".ui-dialog").css("zIndex")||0;return(g>c.ui.dialog.overlay.maxZ)})}},1);c(document).bind("keydown.dialog-overlay",function(f){(e.options.closeOnEscape&&f.keyCode&&f.keyCode==c.ui.keyCode.ESCAPE&&e.close(f))});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var d=c("<div></div>").appendTo(document.body).addClass("ui-widget-overlay").css({width:this.width(),height:this.height()});(e.options.bgiframe&&c.fn.bgiframe&&d.bgiframe());this.instances.push(d);return d},destroy:function(d){this.instances.splice(c.inArray(this.instances,d),1);if(this.instances.length===0){c([document,window]).unbind(".dialog-overlay")}d.remove();var e=0;c.each(this.instances,function(){e=Math.max(e,this.css("z-index"))});this.maxZ=e},height:function(){if(c.browser.msie&&c.browser.version<7){var e=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var d=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(e<d){return c(window).height()+"px"}else{return e+"px"}}else{return c(document).height()+"px"}},width:function(){if(c.browser.msie&&c.browser.version<7){var d=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);var e=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);if(d<e){return c(window).width()+"px"}else{return d+"px"}}else{return c(document).width()+"px"}},resize:function(){var d=c([]);c.each(c.ui.dialog.overlay.instances,function(){d=d.add(this)});d.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);;/*
- * jQuery UI Slider 1.7.2
+(function(c,j){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",of:window,collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");
+if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||"&#160;",f=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog",
+"aria-labelledby":f}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var e=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);
+return false}).appendTo(e);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",f).html(d).prependTo(e);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;e.find("*").add(e).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&
+g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");
+b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0])d=Math.max(d,c(this).css("z-index"))});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,f=d.options;if(f.modal&&!a||!f.stack&&!f.modal)return d._trigger("focus",b);if(f.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=
+f.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;d.next().length&&d.appendTo("body");a._size();a._position(b.position);d.show(b.show);
+a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(f){if(f.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),e=g.filter(":first");g=g.filter(":last");if(f.target===g[0]&&!f.shiftKey){e.focus(1);return false}else if(f.target===e[0]&&f.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,
+f=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(f);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(e,h){h=c.isFunction(h)?{click:h,text:e}:h;e=c("<button></button>",h).unbind("click").click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.fn.button&&e.button()});f.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(e){return{position:e.position,
+offset:e.offset}}var b=this,d=b.options,f=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(e,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",e,a(h))},drag:function(e,h){b._trigger("drag",e,a(h))},stop:function(e,h){d.position=[h.position.left-f.scrollLeft(),h.position.top-f.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);
+b._trigger("dragStop",e,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}a=a===j?this.options.resizable:a;var d=this,f=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:d._minHeight(),
+handles:a,start:function(e,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",e,b(h))},resize:function(e,h){d._trigger("resize",e,b(h))},stop:function(e,h){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();d._trigger("resizeStop",e,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,
+a.height)},_position:function(a){var b=[],d=[0,0],f;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,e){if(+b[g]===b[g]){d[g]=b[g];b[g]=e}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(f=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a);
+f||this.uiDialog.hide()},_setOption:function(a,b){var d=this,f=d.uiDialog,g=f.is(":data(resizable)"),e=false;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);e=true;break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":f.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case "draggable":b?
+d._makeDraggable():f.draggable("destroy");break;case "height":e=true;break;case "maxHeight":g&&f.resizable("option","maxHeight",b);e=true;break;case "maxWidth":g&&f.resizable("option","maxWidth",b);e=true;break;case "minHeight":g&&f.resizable("option","minHeight",b);e=true;break;case "minWidth":g&&f.resizable("option","minWidth",b);e=true;break;case "position":d._position(b);break;case "resizable":g&&!b&&f.resizable("destroy");g&&typeof b==="string"&&f.resizable("option","handles",b);!g&&b!==false&&
+d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break;case "width":e=true;break}c.Widget.prototype._setOption.apply(d,arguments);e&&d._size()},_size:function(){var a=this.options,b;this.element.css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();this.element.css(a.height==="auto"?{minHeight:Math.max(a.minHeight-b,0),height:c.support.minHeight?"auto":Math.max(a.minHeight-
+b,0)}:{minHeight:0,height:Math.max(a.height-b,0)}).show();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.5",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),
+function(a){return a+".dialog-overlay"}).join(" "),create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=
+(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,
+b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<
+b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
+;/*
+ * jQuery UI Slider 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Slider
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
+ *	jquery.ui.mouse.js
+ *	jquery.ui.widget.js
  */
-(function(a){a.widget("ui.slider",a.extend({},a.ui.mouse,{_init:function(){var b=this,c=this.options;this._keySliding=false;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");this.range=a([]);if(c.range){if(c.range===true){this.range=a("<div></div>");if(!c.values){c.values=[this._valueMin(),this._valueMin()]}if(c.values.length&&c.values.length!=2){c.values=[c.values[0],c.values[0]]}}else{this.range=a("<div></div>")}this.range.appendTo(this.element).addClass("ui-slider-range");if(c.range=="min"||c.range=="max"){this.range.addClass("ui-slider-range-"+c.range)}this.range.addClass("ui-widget-header")}if(a(".ui-slider-handle",this.element).length==0){a('<a href="#"></a>').appendTo(this.element).addClass("ui-slider-handle")}if(c.values&&c.values.length){while(a(".ui-slider-handle",this.element).length<c.values.length){a('<a href="#"></a>').appendTo(this.element).addClass("ui-slider-handle")}}this.handles=a(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(d){d.preventDefault()}).hover(function(){if(!c.disabled){a(this).addClass("ui-state-hover")}},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(!c.disabled){a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}else{a(this).blur()}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(d){a(this).data("index.ui-slider-handle",d)});this.handles.keydown(function(i){var f=true;var e=a(this).data("index.ui-slider-handle");if(b.options.disabled){return}switch(i.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:f=false;if(!b._keySliding){b._keySliding=true;a(this).addClass("ui-state-active");b._start(i,e)}break}var g,d,h=b._step();if(b.options.values&&b.options.values.length){g=d=b.values(e)}else{g=d=b.value()}switch(i.keyCode){case a.ui.keyCode.HOME:d=b._valueMin();break;case a.ui.keyCode.END:d=b._valueMax();break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g==b._valueMax()){return}d=g+h;break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g==b._valueMin()){return}d=g-h;break}b._slide(i,e,d);return f}).keyup(function(e){var d=a(this).data("index.ui-slider-handle");if(b._keySliding){b._stop(e,d);b._change(e,d);b._keySliding=false;a(this).removeClass("ui-state-active")}});this._refreshValue()},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy()},_mouseCapture:function(d){var e=this.options;if(e.disabled){return false}this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();var h={x:d.pageX,y:d.pageY};var j=this._normValueFromMouse(h);var c=this._valueMax()-this._valueMin()+1,f;var k=this,i;this.handles.each(function(l){var m=Math.abs(j-k.values(l));if(c>m){c=m;f=a(this);i=l}});if(e.range==true&&this.values(1)==e.min){f=a(this.handles[++i])}this._start(d,i);k._handleIndex=i;f.addClass("ui-state-active").focus();var g=f.offset();var b=!a(d.target).parents().andSelf().is(".ui-slider-handle");this._clickOffset=b?{left:0,top:0}:{left:d.pageX-g.left-(f.width()/2),top:d.pageY-g.top-(f.height()/2)-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};j=this._normValueFromMouse(h);this._slide(d,i,j);return true},_mouseStart:function(b){return true},_mouseDrag:function(d){var b={x:d.pageX,y:d.pageY};var c=this._normValueFromMouse(b);this._slide(d,this._handleIndex,c);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._handleIndex=null;this._clickOffset=null;return false},_detectOrientation:function(){this.orientation=this.options.orientation=="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(d){var c,h;if("horizontal"==this.orientation){c=this.elementSize.width;h=d.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{c=this.elementSize.height;h=d.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}var f=(h/c);if(f>1){f=1}if(f<0){f=0}if("vertical"==this.orientation){f=1-f}var e=this._valueMax()-this._valueMin(),i=f*e,b=i%this.options.step,g=this._valueMin()+i-b;if(b>(this.options.step/2)){g+=this.options.step}return parseFloat(g.toFixed(5))},_start:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("start",d,b)},_slide:function(f,e,d){var g=this.handles[e];if(this.options.values&&this.options.values.length){var b=this.values(e?0:1);if((this.options.values.length==2&&this.options.range===true)&&((e==0&&d>b)||(e==1&&d<b))){d=b}if(d!=this.values(e)){var c=this.values();c[e]=d;var h=this._trigger("slide",f,{handle:this.handles[e],value:d,values:c});var b=this.values(e?0:1);if(h!==false){this.values(e,d,(f.type=="mousedown"&&this.options.animate),true)}}}else{if(d!=this.value()){var h=this._trigger("slide",f,{handle:this.handles[e],value:d});if(h!==false){this._setData("value",d,(f.type=="mousedown"&&this.options.animate))}}}},_stop:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("stop",d,b)},_change:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("change",d,b)},value:function(b){if(arguments.length){this._setData("value",b);this._change(null,0)}return this._value()},values:function(b,e,c,d){if(arguments.length>1){this.options.values[b]=e;this._refreshValue(c);if(!d){this._change(null,b)}}if(arguments.length){if(this.options.values&&this.options.values.length){return this._values(b)}else{return this.value()}}else{return this._values()}},_setData:function(b,d,c){a.widget.prototype._setData.apply(this,arguments);switch(b){case"disabled":if(d){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled")}else{this.handles.removeAttr("disabled")}case"orientation":this._detectOrientation();this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue(c);break;case"value":this._refreshValue(c);break}},_step:function(){var b=this.options.step;return b},_value:function(){var b=this.options.value;if(b<this._valueMin()){b=this._valueMin()}if(b>this._valueMax()){b=this._valueMax()}return b},_values:function(b){if(arguments.length){var c=this.options.values[b];if(c<this._valueMin()){c=this._valueMin()}if(c>this._valueMax()){c=this._valueMax()}return c}else{return this.options.values}},_valueMin:function(){var b=this.options.min;return b},_valueMax:function(){var b=this.options.max;return b},_refreshValue:function(c){var f=this.options.range,d=this.options,l=this;if(this.options.values&&this.options.values.length){var i,h;this.handles.each(function(p,n){var o=(l.values(p)-l._valueMin())/(l._valueMax()-l._valueMin())*100;var m={};m[l.orientation=="horizontal"?"left":"bottom"]=o+"%";a(this).stop(1,1)[c?"animate":"css"](m,d.animate);if(l.options.range===true){if(l.orientation=="horizontal"){(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({left:o+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({width:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}else{(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({bottom:(o)+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({height:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}}lastValPercent=o})}else{var j=this.value(),g=this._valueMin(),k=this._valueMax(),e=k!=g?(j-g)/(k-g)*100:0;var b={};b[l.orientation=="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[c?"animate":"css"](b,d.animate);(f=="min")&&(this.orientation=="horizontal")&&this.range.stop(1,1)[c?"animate":"css"]({width:e+"%"},d.animate);(f=="max")&&(this.orientation=="horizontal")&&this.range[c?"animate":"css"]({width:(100-e)+"%"},{queue:false,duration:d.animate});(f=="min")&&(this.orientation=="vertical")&&this.range.stop(1,1)[c?"animate":"css"]({height:e+"%"},d.animate);(f=="max")&&(this.orientation=="vertical")&&this.range[c?"animate":"css"]({height:(100-e)+"%"},{queue:false,duration:d.animate})}}}));a.extend(a.ui.slider,{getter:"value values",version:"1.7.2",eventPrefix:"slide",defaults:{animate:false,delay:0,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null}})})(jQuery);;/*
- * jQuery UI Tabs 1.7.2
+(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var a=this,b=this.options;this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");b.disabled&&this.element.addClass("ui-slider-disabled ui-disabled");
+this.range=d([]);if(b.range){if(b.range===true){this.range=d("<div></div>");if(!b.values)b.values=[this._valueMin(),this._valueMin()];if(b.values.length&&b.values.length!==2)b.values=[b.values[0],b.values[0]]}else this.range=d("<div></div>");this.range.appendTo(this.element).addClass("ui-slider-range");if(b.range==="min"||b.range==="max")this.range.addClass("ui-slider-range-"+b.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");
+if(b.values&&b.values.length)for(;d(".ui-slider-handle",this.element).length<b.values.length;)d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();
+else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(c){d(this).data("index.ui-slider-handle",c)});this.handles.keydown(function(c){var e=true,f=d(this).data("index.ui-slider-handle"),h,g,i;if(!a.options.disabled){switch(c.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:e=
+false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");h=a._start(c,f);if(h===false)return}break}i=a.options.step;h=a.options.values&&a.options.values.length?(g=a.values(f)):(g=a.value());switch(c.keyCode){case d.ui.keyCode.HOME:g=a._valueMin();break;case d.ui.keyCode.END:g=a._valueMax();break;case d.ui.keyCode.PAGE_UP:g=a._trimAlignValue(h+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:g=a._trimAlignValue(h-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(h===
+a._valueMax())return;g=a._trimAlignValue(h+i);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(h===a._valueMin())return;g=a._trimAlignValue(h-i);break}a._slide(c,f,g);return e}}).keyup(function(c){var e=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(c,e);a._change(c,e);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");
+this._mouseDestroy();return this},_mouseCapture:function(a){var b=this.options,c,e,f,h,g;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:a.pageX,y:a.pageY});e=this._valueMax()-this._valueMin()+1;h=this;this.handles.each(function(i){var j=Math.abs(c-h.values(i));if(e>j){e=j;f=d(this);g=i}});if(b.range===true&&this.values(1)===b.min){g+=1;f=d(this.handles[g])}if(this._start(a,
+g)===false)return false;this._mouseSliding=true;h._handleIndex=g;f.addClass("ui-state-active").focus();b=f.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-f.width()/2,top:a.pageY-b.top-f.height()/2-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};this._slide(a,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(a){var b=
+this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b;if(this.orientation==="horizontal"){b=
+this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);
+c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var e;if(this.options.values&&this.options.values.length){e=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>e||b===1&&c<e))c=e;if(c!==this.values(b)){e=this.values();e[b]=c;a=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e});this.values(b?0:1);a!==false&&this.values(b,c,true)}}else if(c!==this.value()){a=this._trigger("slide",a,{handle:this.handles[b],value:c});
+a!==false&&this.value(c)}},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);c.values=this.values()}this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);c.values=this.values()}this._trigger("change",a,c)}},value:function(a){if(arguments.length){this.options.value=
+this._trimAlignValue(a);this._refreshValue();this._change(null,0)}return this._value()},values:function(a,b){var c,e,f;if(arguments.length>1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;f<c.length;f+=1){c[f]=this._trimAlignValue(e[f]);this._change(null,f)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(a):this.value();
+else return this._values()},_setOption:function(a,b){var c,e=0;if(d.isArray(this.options.values))e=this.options.values.length;d.Widget.prototype._setOption.apply(this,arguments);switch(a){case "disabled":if(b){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled");this.element.addClass("ui-disabled")}else{this.handles.removeAttr("disabled");this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
+this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(c=0;c<e;c+=1)this._change(null,c);this._animateOff=false;break}},_value:function(){var a=this.options.value;return a=this._trimAlignValue(a)},_values:function(a){var b,c;if(arguments.length){b=this.options.values[a];
+return b=this._trimAlignValue(b)}else{b=this.options.values.slice();for(c=0;c<b.length;c+=1)b[c]=this._trimAlignValue(b[c]);return b}},_trimAlignValue:function(a){if(a<this._valueMin())return this._valueMin();if(a>this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=a%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a=
+this.options.range,b=this.options,c=this,e=!this._animateOff?b.animate:false,f,h={},g,i,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(k){f=(c.values(k)-c._valueMin())/(c._valueMax()-c._valueMin())*100;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](h,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(k===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},b.animate);if(k===1)c.range[e?"animate":"css"]({width:f-
+g+"%"},{queue:false,duration:b.animate})}else{if(k===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},b.animate);if(k===1)c.range[e?"animate":"css"]({height:f-g+"%"},{queue:false,duration:b.animate})}g=f});else{i=this.value();j=this._valueMin();l=this._valueMax();f=l!==j?(i-j)/(l-j)*100:0;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](h,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},
+b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.5"})})(jQuery);
+;/*
+ * jQuery UI Tabs 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Tabs
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
  */
-(function(a){a.widget("ui.tabs",{_init:function(){if(this.options.deselectable!==undefined){this.options.collapsible=this.options.deselectable}this._tabify(true)},_setData:function(b,c){if(b=="selected"){if(this.options.collapsible&&c==this.options.selected){return}this.select(c)}else{this.options[b]=c;if(b=="deselectable"){this.options.collapsible=c}this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+a.data(b)},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+a.data(this.list[0]));return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(c,b){return{tab:c,panel:b,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(n){this.list=this.element.children("ul:first");this.lis=a("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);var p=this,d=this.options;var c=/^#.+/;this.anchors.each(function(r,o){var q=a(o).attr("href");var s=q.split("#")[0],u;if(s&&(s===location.toString().split("#")[0]||(u=a("base")[0])&&s===u.href)){q=o.hash;o.href=q}if(c.test(q)){p.panels=p.panels.add(p._sanitizeSelector(q))}else{if(q!="#"){a.data(o,"href.tabs",q);a.data(o,"load.tabs",q.replace(/#.*$/,""));var w=p._tabId(o);o.href="#"+w;var v=a("#"+w);if(!v.length){v=a(d.panelTemplate).attr("id",w).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(p.panels[r-1]||p.list);v.data("destroy.tabs",true)}p.panels=p.panels.add(v)}else{d.disabled.push(r)}}});if(n){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(d.selected===undefined){if(location.hash){this.anchors.each(function(q,o){if(o.hash==location.hash){d.selected=q;return false}})}if(typeof d.selected!="number"&&d.cookie){d.selected=parseInt(p._cookie(),10)}if(typeof d.selected!="number"&&this.lis.filter(".ui-tabs-selected").length){d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}d.selected=d.selected||0}else{if(d.selected===null){d.selected=-1}}d.selected=((d.selected>=0&&this.anchors[d.selected])||d.selected<0)?d.selected:0;d.disabled=a.unique(d.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(q,o){return p.lis.index(q)}))).sort();if(a.inArray(d.selected,d.disabled)!=-1){d.disabled.splice(a.inArray(d.selected,d.disabled),1)}this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");if(d.selected>=0&&this.anchors.length){this.panels.eq(d.selected).removeClass("ui-tabs-hide");this.lis.eq(d.selected).addClass("ui-tabs-selected ui-state-active");p.element.queue("tabs",function(){p._trigger("show",null,p._ui(p.anchors[d.selected],p.panels[d.selected]))});this.load(d.selected)}a(window).bind("unload",function(){p.lis.add(p.anchors).unbind(".tabs");p.lis=p.anchors=p.panels=null})}else{d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}this.element[d.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");if(d.cookie){this._cookie(d.selected,d.cookie)}for(var g=0,m;(m=this.lis[g]);g++){a(m)[a.inArray(g,d.disabled)!=-1&&!a(m).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled")}if(d.cache===false){this.anchors.removeData("cache.tabs")}this.lis.add(this.anchors).unbind(".tabs");if(d.event!="mouseover"){var f=function(o,i){if(i.is(":not(.ui-state-disabled)")){i.addClass("ui-state-"+o)}};var j=function(o,i){i.removeClass("ui-state-"+o)};this.lis.bind("mouseover.tabs",function(){f("hover",a(this))});this.lis.bind("mouseout.tabs",function(){j("hover",a(this))});this.anchors.bind("focus.tabs",function(){f("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var b,h;if(d.fx){if(a.isArray(d.fx)){b=d.fx[0];h=d.fx[1]}else{b=h=d.fx}}function e(i,o){i.css({display:""});if(a.browser.msie&&o.opacity){i[0].style.removeAttribute("filter")}}var k=h?function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.hide().removeClass("ui-tabs-hide").animate(h,h.duration||"normal",function(){e(o,h);p._trigger("show",null,p._ui(i,o[0]))})}:function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");p._trigger("show",null,p._ui(i,o[0]))};var l=b?function(o,i){i.animate(b,b.duration||"normal",function(){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");e(i,b);p.element.dequeue("tabs")})}:function(o,i,q){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");p.element.dequeue("tabs")};this.anchors.bind(d.event+".tabs",function(){var o=this,r=a(this).closest("li"),i=p.panels.filter(":not(.ui-tabs-hide)"),q=a(p._sanitizeSelector(this.hash));if((r.hasClass("ui-tabs-selected")&&!d.collapsible)||r.hasClass("ui-state-disabled")||r.hasClass("ui-state-processing")||p._trigger("select",null,p._ui(this,q[0]))===false){this.blur();return false}d.selected=p.anchors.index(this);p.abort();if(d.collapsible){if(r.hasClass("ui-tabs-selected")){d.selected=-1;if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){l(o,i)}).dequeue("tabs");this.blur();return false}else{if(!i.length){if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this));this.blur();return false}}}if(d.cookie){p._cookie(d.selected,d.cookie)}if(q.length){if(i.length){p.element.queue("tabs",function(){l(o,i)})}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this))}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(a.browser.msie){this.blur()}});this.anchors.bind("click.tabs",function(){return false})},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var c=a.data(this,"href.tabs");if(c){this.href=c}var d=a(this).unbind(".tabs");a.each(["href","load","cache"],function(e,f){d.removeData(f+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){if(a.data(this,"destroy.tabs")){a(this).remove()}else{a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}});if(b.cookie){this._cookie(null,b.cookie)}},add:function(e,d,c){if(c===undefined){c=this.anchors.length}var b=this,g=this.options,i=a(g.tabTemplate.replace(/#\{href\}/g,e).replace(/#\{label\}/g,d)),h=!e.indexOf("#")?e.replace("#",""):this._tabId(a("a",i)[0]);i.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var f=a("#"+h);if(!f.length){f=a(g.panelTemplate).attr("id",h).data("destroy.tabs",true)}f.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(c>=this.lis.length){i.appendTo(this.list);f.appendTo(this.list[0].parentNode)}else{i.insertBefore(this.lis[c]);f.insertBefore(this.panels[c])}g.disabled=a.map(g.disabled,function(k,j){return k>=c?++k:k});this._tabify();if(this.anchors.length==1){i.addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[c],this.panels[c]))},remove:function(b){var d=this.options,e=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();if(e.hasClass("ui-tabs-selected")&&this.anchors.length>1){this.select(b+(b+1<this.anchors.length?1:-1))}d.disabled=a.map(a.grep(d.disabled,function(g,f){return g!=b}),function(g,f){return g>=b?--g:g});this._tabify();this._trigger("remove",null,this._ui(e.find("a")[0],c[0]))},enable:function(b){var c=this.options;if(a.inArray(b,c.disabled)==-1){return}this.lis.eq(b).removeClass("ui-state-disabled");c.disabled=a.grep(c.disabled,function(e,d){return e!=b});this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]))},disable:function(c){var b=this,d=this.options;if(c!=d.selected){this.lis.eq(c).addClass("ui-state-disabled");d.disabled.push(c);d.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}},select:function(b){if(typeof b=="string"){b=this.anchors.index(this.anchors.filter("[href$="+b+"]"))}else{if(b===null){b=-1}}if(b==-1&&this.options.collapsible){b=this.options.selected}this.anchors.eq(b).trigger(this.options.event+".tabs")},load:function(e){var c=this,g=this.options,b=this.anchors.eq(e)[0],d=a.data(b,"load.tabs");this.abort();if(!d||this.element.queue("tabs").length!==0&&a.data(b,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(e).addClass("ui-state-processing");if(g.spinner){var f=a("span",b);f.data("label.tabs",f.html()).html(g.spinner)}this.xhr=a.ajax(a.extend({},g.ajaxOptions,{url:d,success:function(i,h){a(c._sanitizeSelector(b.hash)).html(i);c._cleanup();if(g.cache){a.data(b,"cache.tabs",true)}c._trigger("load",null,c._ui(c.anchors[e],c.panels[e]));try{g.ajaxOptions.success(i,h)}catch(j){}c.element.dequeue("tabs")}}))},abort:function(){this.element.queue([]);this.panels.stop(false,true);if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup()},url:function(c,b){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",b)},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.7.2",getter:"length",defaults:{ajaxOptions:null,cache:false,cookie:null,collapsible:false,disabled:[],event:"click",fx:null,idPrefix:"ui-tabs-",panelTemplate:"<div></div>",spinner:"<em>Loading&#8230;</em>",tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>'}});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(d,f){var b=this,g=this.options;var c=b._rotate||(b._rotate=function(h){clearTimeout(b.rotation);b.rotation=setTimeout(function(){var i=g.selected;b.select(++i<b.anchors.length?i:0)},d);if(h){h.stopPropagation()}});var e=b._unrotate||(b._unrotate=!f?function(h){if(h.clientX){b.rotate(null)}}:function(h){t=g.selected;c()});if(d){this.element.bind("tabsshow",c);this.anchors.bind(g.event+".tabs",e);c()}else{clearTimeout(b.rotation);this.element.unbind("tabsshow",c);this.anchors.unbind(g.event+".tabs",e);delete this._rotate;delete this._unrotate}}})})(jQuery);;/*
- * jQuery UI Datepicker 1.7.2
+(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(a,e){if(a=="selected")this.options.collapsible&&
+e==this.options.selected||this.select(e);else{this.options[a]=e;this._tabify()}},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var a=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[a].concat(d.makeArray(arguments)))},_ui:function(a,e){return{tab:a,panel:e,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var a=
+d(this);a.html(a.data("label.tabs")).removeData("label.tabs")})},_tabify:function(a){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var b=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]||
+(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))b.panels=b.panels.add(b._sanitizeSelector(i));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=b._tabId(f);f.href="#"+i;f=d("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(b.panels[g-1]||b.list);f.data("destroy.tabs",true)}b.panels=b.panels.add(f)}else c.disabled.push(g)});if(a){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
+this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(b._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected=
+this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return b.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
+if(c.selected>=0&&this.anchors.length){this.panels.eq(c.selected).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");b.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[c.selected],b.panels[c.selected]))});this.load(c.selected)}d(window).bind("unload",function(){b.lis.add(b.anchors).unbind(".tabs");b.lis=b.anchors=b.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));this.element[c.collapsible?"addClass":
+"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);a=0;for(var j;j=this.lis[a];a++)d(j)[d.inArray(a,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+g)};this.lis.bind("mouseover.tabs",
+function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",function(){e(f,o);b._trigger("show",
+null,b._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");b._trigger("show",null,b._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){b.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);b.element.dequeue("tabs")})}:function(g,f){b.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");b.element.dequeue("tabs")};this.anchors.bind(c.event+".tabs",
+function(){var g=this,f=d(g).closest("li"),i=b.panels.filter(":not(.ui-tabs-hide)"),l=d(b._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||b.panels.filter(":animated").length||b._trigger("select",null,b._ui(this,l[0]))===false){this.blur();return false}c.selected=b.anchors.index(this);b.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected=-1;c.cookie&&b._cookie(c.selected,c.cookie);b.element.queue("tabs",
+function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&b._cookie(c.selected,c.cookie);b.element.queue("tabs",function(){r(g,l)});b.load(b.anchors.index(this));this.blur();return false}c.cookie&&b._cookie(c.selected,c.cookie);if(l.length){i.length&&b.element.queue("tabs",function(){s(g,i)});b.element.queue("tabs",function(){r(g,l)});b.load(b.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",
+function(){return false})},_getIndex:function(a){if(typeof a=="string")a=this.anchors.index(this.anchors.filter("[href$="+a+"]"));return a},destroy:function(){var a=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=d.data(this,"href.tabs");if(e)this.href=
+e;var b=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){b.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});a.cookie&&this._cookie(null,a.cookie);return this},add:function(a,e,b){if(b===p)b=this.anchors.length;
+var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,a).replace(/#\{label\}/g,e));a=!a.indexOf("#")?a.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=d("#"+a);j.length||(j=d(h.panelTemplate).attr("id",a).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(b>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[b]);
+j.insertBefore(this.panels[b])}h.disabled=d.map(h.disabled,function(k){return k>=b?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[b],this.panels[b]));return this},remove:function(a){a=this._getIndex(a);var e=this.options,b=this.lis.eq(a).remove(),c=this.panels.eq(a).remove();
+if(b.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(a+(a+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=a}),function(h){return h>=a?--h:h});this._tabify();this._trigger("remove",null,this._ui(b.find("a")[0],c[0]));return this},enable:function(a){a=this._getIndex(a);var e=this.options;if(d.inArray(a,e.disabled)!=-1){this.lis.eq(a).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(b){return b!=a});this._trigger("enable",null,
+this._ui(this.anchors[a],this.panels[a]));return this}},disable:function(a){a=this._getIndex(a);var e=this.options;if(a!=e.selected){this.lis.eq(a).addClass("ui-state-disabled");e.disabled.push(a);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a]))}return this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;this.anchors.eq(a).trigger(this.options.event+".tabs");return this},
+load:function(a){a=this._getIndex(a);var e=this,b=this.options,c=this.anchors.eq(a)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(a).addClass("ui-state-processing");if(b.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(b.spinner)}this.xhr=d.ajax(d.extend({},b.ajaxOptions,{url:h,success:function(k,n){d(e._sanitizeSelector(c.hash)).html(k);e._cleanup();b.cache&&d.data(c,"cache.tabs",
+true);e._trigger("load",null,e._ui(e.anchors[a],e.panels[a]));try{b.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[a],e.panels[a]));try{b.ajaxOptions.error(k,n,a,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},url:function(a,
+e){this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.5"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(a,e){var b=this,c=this.options,h=b._rotate||(b._rotate=function(j){clearTimeout(b.rotation);b.rotation=setTimeout(function(){var k=c.selected;b.select(++k<b.anchors.length?k:0)},a);j&&j.stopPropagation()});e=b._unrotate||(b._unrotate=!e?function(j){j.clientX&&b.rotate(null)}:
+function(){t=c.selected;h()});if(a){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(b.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
+;/*
+ * jQuery UI Datepicker 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Datepicker
  *
  * Depends:
- *	ui.core.js
+ *	jquery.ui.core.js
  */
-(function($){$.extend($.ui,{datepicker:{version:"1.7.2"}});var PROP_NAME="datepicker";function Datepicker(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass="ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dateFormat:"mm/dd/yy",firstDay:0,isRTL:false};this._defaults={showOn:"focus",showAnim:"show",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,showMonthAfterYear:false,yearRange:"-10:+10",showOtherMonths:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"normal",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false};$.extend(this._defaults,this.regional[""]);this.dpDiv=$('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(target,inst){var input=$(target);inst.append=$([]);inst.trigger=$([]);if(input.hasClass(this.markerClassName)){return}var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){inst.append=$('<span class="'+this._appendClass+'">'+appendText+"</span>");input[isRTL?"before":"after"](inst.append)}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");inst.trigger=$(this._get(inst,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$('<button type="button"></button>').addClass(this._triggerClass).html(buttonImage==""?buttonText:$("<img/>").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](inst.trigger);inst.trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return}divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst);this._updateAlternate(inst)},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$('<input type="text" id="'+id+'" size="1" style="position: absolute; top: -100px;"/>');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){inst.append.remove();inst.trigger.remove();$target.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;inst.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().removeClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;inst.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().addClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i<this._disabledInputs.length;i++){if(this._disabledInputs[i]==target){return true}}return false},_getInst:function(target){try{return $.data(target,PROP_NAME)}catch(err){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(target,name,value){var inst=this._getInst(target);if(arguments.length==2&&typeof name=="string"){return(name=="defaults"?$.extend({},$.datepicker._defaults):(inst?(name=="all"?$.extend({},inst.settings):this._get(inst,name)):null))}var settings=name||{};if(typeof name=="string"){settings={};settings[name]=value}if(inst){if(this._curInst==inst){this._hideDatepicker(null)}var date=this._getDateDatepicker(target);extendRemove(inst.settings,settings);this._setDateDatepicker(target,date);this._updateDatepicker(inst)}},_changeDatepicker:function(target,name,value){this._optionDatepicker(target,name,value)},_refreshDatepicker:function(target){var inst=this._getInst(target);if(inst){this._updateDatepicker(inst)}},_setDateDatepicker:function(target,date,endDate){var inst=this._getInst(target);if(inst){this._setDate(inst,date,endDate);this._updateDatepicker(inst);this._updateAlternate(inst)}},_getDateDatepicker:function(target){var inst=this._getInst(target);if(inst&&!inst.inline){this._setDateFromField(inst)}return(inst?this._getDate(inst):null)},_doKeyDown:function(event){var inst=$.datepicker._getInst(event.target);var handled=true;var isRTL=inst.dpDiv.is(".ui-datepicker-rtl");inst._keyEvent=true;if($.datepicker._datepickerShowing){switch(event.keyCode){case 9:$.datepicker._hideDatepicker(null,"");break;case 13:var sel=$("td."+$.datepicker._dayOverClass+", td."+$.datepicker._currentClass,inst.dpDiv);if(sel[0]){$.datepicker._selectDay(event.target,inst.selectedMonth,inst.selectedYear,sel[0])}else{$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"))}return false;break;case 27:$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"));break;case 33:$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M");break;case 34:$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M");break;case 35:if(event.ctrlKey||event.metaKey){$.datepicker._clearDate(event.target)}handled=event.ctrlKey||event.metaKey;break;case 36:if(event.ctrlKey||event.metaKey){$.datepicker._gotoToday(event.target)}handled=event.ctrlKey||event.metaKey;break;case 37:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?+1:-1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M")}break;case 38:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,-7,"D")}handled=event.ctrlKey||event.metaKey;break;case 39:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?-1:+1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M")}break;case 40:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,+7,"D")}handled=event.ctrlKey||event.metaKey;break;default:handled=false}}else{if(event.keyCode==36&&event.ctrlKey){$.datepicker._showDatepicker(this)}else{handled=false}}if(handled){event.preventDefault();event.stopPropagation()}},_doKeyPress:function(event){var inst=$.datepicker._getInst(event.target);if($.datepicker._get(inst,"constrainInput")){var chars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat"));var chr=String.fromCharCode(event.charCode==undefined?event.keyCode:event.charCode);return event.ctrlKey||(chr<" "||!chars||chars.indexOf(chr)>-1)}},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return}var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};var self=this;inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){$(this).removeClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).removeClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).removeClass("ui-datepicker-next-hover")}}).bind("mouseover",function(){if(!self._isDisabledDatepicker(inst.inline?inst.dpDiv.parent()[0]:inst.input[0])){$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");$(this).addClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).addClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).addClass("ui-datepicker-next-hover")}}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();var numMonths=this._getNumberOfMonths(inst);var cols=numMonths[1];var width=17;if(cols>1){inst.dpDiv.addClass("ui-datepicker-multi-"+cols).css("width",(width*cols)+"em")}else{inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("")}inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"&&inst==$.datepicker._curInst){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var dpWidth=inst.dpDiv.outerWidth();var dpHeight=inst.dpDiv.outerHeight();var inputWidth=inst.input?inst.input.outerWidth():0;var inputHeight=inst.input?inst.input.outerHeight():0;var viewWidth=(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)+$(document).scrollLeft();var viewHeight=(window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)+$(document).scrollTop();offset.left-=(this._get(inst,"isRTL")?(dpWidth-inputWidth):0);offset.left-=(isFixed&&offset.left==inst.input.offset().left)?$(document).scrollLeft():0;offset.top-=(isFixed&&offset.top==(inst.input.offset().top+inputHeight))?$(document).scrollTop():0;offset.left-=(offset.left+dpWidth>viewWidth&&viewWidth>dpWidth)?Math.abs(offset.left+dpWidth-viewWidth):0;offset.top-=(offset.top+dpHeight>viewHeight&&viewHeight>dpHeight)?Math.abs(offset.top+dpHeight+inputHeight*2-viewHeight):0;return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return}if(inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(event){if(!$.datepicker._curInst){return}var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);if(this._isDisabledDatepicker(target[0])){return}this._adjustInstDate(inst,offset+(period=="M"?this._get(inst,"showCurrentAtPos"):0),period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_selectDay:function(id,month,year,td){var target=$(id);if($(td).hasClass(this._unselectableClass)||this._isDisabledDatepicker(target[0])){return}var inst=this._getInst(target[0]);inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay));this._updateDatepicker(inst)}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof(inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat")||this._get(inst,"dateFormat");var date=this._getDate(inst);dateStr=this.formatDate(altFormat,date,this._getFormatConfig(inst));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDate<firstMon){checkDate.setDate(checkDate.getDate()-3);return $.datepicker.iso8601Week(checkDate)}else{if(checkDate>new Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)<firstDay-3){return 1}}}return Math.floor(((checkDate-firstMon)/86400000)/7)+1},parseDate:function(format,value,settings){if(format==null||value==null){throw"Invalid arguments"}value=(typeof value=="object"?value.toString():value+"");if(value==""){return null}var shortYearCutoff=(settings?settings.shortYearCutoff:null)||this._defaults.shortYearCutoff;var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var year=-1;var month=-1;var day=-1;var doy=-1;var literal=false;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var getNumber=function(match){lookAhead(match);var origSize=(match=="@"?14:(match=="y"?4:(match=="o"?3:2)));var size=origSize;var num=0;while(size>0&&iValue<value.length&&value.charAt(iValue)>="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j<names.length;j++){size=Math.max(size,names[j].length)}var name="";var iInit=iValue;while(size>0&&iValue<value.length){name+=value.charAt(iValue++);for(var i=0;i<names.length;i++){if(name==names[i]){return i+1}}size--}throw"Unknown name at position "+iInit};var checkLiteral=function(){if(value.charAt(iValue)!=format.charAt(iFormat)){throw"Unexpected literal at position "+iValue}iValue++};var iValue=0;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{checkLiteral()}}else{switch(format.charAt(iFormat)){case"d":day=getNumber("d");break;case"D":getName("D",dayNamesShort,dayNames);break;case"o":doy=getNumber("o");break;case"m":month=getNumber("m");break;case"M":month=getName("M",monthNamesShort,monthNames);break;case"y":year=getNumber("y");break;case"@":var date=new Date(getNumber("@"));year=date.getFullYear();month=date.getMonth()+1;day=date.getDate();break;case"'":if(lookAhead("'")){checkLiteral()}else{literal=true}break;default:checkLiteral()}}}if(year==-1){year=new Date().getFullYear()}else{if(year<100){year+=new Date().getFullYear()-new Date().getFullYear()%100+(year<=shortYearCutoff?0:-100)}}if(doy>-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=this._daylightSavingAdjust(new Date(year,month-1,day));if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var formatNumber=function(match,value,len){var num=""+value;if(lookAhead(match)){while(num.length<len){num="0"+num}}return num};var formatName=function(match,value,shortNames,longNames){return(lookAhead(match)?longNames[value]:shortNames[value])};var output="";var literal=false;if(date){for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{output+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":output+=formatNumber("d",date.getDate(),2);break;case"D":output+=formatName("D",date.getDay(),dayNamesShort,dayNames);break;case"o":var doy=date.getDate();for(var m=date.getMonth()-1;m>=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{chars+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":case"m":case"y":case"@":chars+="0123456789";break;case"D":case"M":return null;case"'":if(lookAhead("'")){chars+="'"}else{literal=true}break;default:chars+=format.charAt(iFormat)}}}return chars},_get:function(inst,name){return inst.settings[name]!==undefined?inst.settings[name]:this._defaults[name]},_setDateFromField:function(inst){var dateFormat=this._get(inst,"dateFormat");var dates=inst.input?inst.input.val():null;inst.endDay=inst.endMonth=inst.endYear=null;var date=defaultDate=this._getDefaultDate(inst);var settings=this._getFormatConfig(inst);try{date=this.parseDate(dateFormat,dates,settings)||defaultDate}catch(event){this.log(event);date=defaultDate}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates?date.getDate():0);inst.currentMonth=(dates?date.getMonth():0);inst.currentYear=(dates?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setDate(date.getDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));date=(date&&date.toString()=="Invalid Date"?defaultDate:date);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return this._daylightSavingAdjust(date)},_daylightSavingAdjust:function(date){if(!date){return null}date.setHours(date.getHours()>12?date.getHours()+2:0);return date},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return startDate},_generateHTML:function(inst){var today=new Date();today=this._daylightSavingAdjust(new Date(today.getFullYear(),today.getMonth(),today.getDate()));var isRTL=this._get(inst,"isRTL");var showButtonPanel=this._get(inst,"showButtonPanel");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=this._daylightSavingAdjust((!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=this._daylightSavingAdjust(new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate()));maxDraw=(minDate&&maxDraw<minDate?minDate:maxDraw);while(this._daylightSavingAdjust(new Date(drawYear,drawMonth,1))>maxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}inst.drawMonth=drawMonth;inst.drawYear=drawYear;var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,this._daylightSavingAdjust(new Date(drawYear,drawMonth-stepMonths,1)),this._getFormatConfig(inst)));var prev=(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', -"+stepMonths+", 'M');\" title=\""+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>"));var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,this._daylightSavingAdjust(new Date(drawYear,drawMonth+stepMonths,1)),this._getFormatConfig(inst)));var next=(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', +"+stepMonths+", 'M');\" title=\""+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>"));var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var controls=(!inst.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">'+this._get(inst,"closeText")+"</button>":"");var buttonPanel=(showButtonPanel)?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(isRTL?controls:"")+(this._isInRange(inst,gotoDate)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#'+inst.id+"');\">"+currentText+"</button>":"")+(isRTL?"":controls)+"</div>":"";var firstDay=parseInt(this._get(inst,"firstDay"),10);firstDay=(isNaN(firstDay)?0:firstDay);var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var monthNamesShort=this._get(inst,"monthNamesShort");var beforeShowDay=this._get(inst,"beforeShowDay");var showOtherMonths=this._get(inst,"showOtherMonths");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var endDate=inst.endDay?this._daylightSavingAdjust(new Date(inst.endYear,inst.endMonth,inst.endDay)):currentDate;var defaultDate=this._getDefaultDate(inst);var html="";for(var row=0;row<numMonths[0];row++){var group="";for(var col=0;col<numMonths[1];col++){var selectedDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,inst.selectedDay));var cornerClass=" ui-corner-all";var calender="";if(isMultiMonth){calender+='<div class="ui-datepicker-group ui-datepicker-group-';switch(col){case 0:calender+="first";cornerClass=" ui-corner-"+(isRTL?"right":"left");break;case numMonths[1]-1:calender+="last";cornerClass=" ui-corner-"+(isRTL?"left":"right");break;default:calender+="middle";cornerClass="";break}calender+='">'}calender+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+cornerClass+'">'+(/all|left/.test(cornerClass)&&row==0?(isRTL?next:prev):"")+(/all|right/.test(cornerClass)&&row==0?(isRTL?prev:next):"")+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,monthNames,monthNamesShort)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var thead="";for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;thead+="<th"+((dow+firstDay+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+dayNames[day]+'">'+dayNamesMin[day]+"</span></th>"}calender+=thead+"</tr></thead><tbody>";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));var printDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,1-leadDays));for(var dRow=0;dRow<numRows;dRow++){calender+="<tr>";var tbody="";for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDate<minDate)||(maxDate&&printDate>maxDate);tbody+='<td class="'+((dow+firstDay+6)%7>=5?" ui-datepicker-week-end":"")+(otherMonth?" ui-datepicker-other-month":"")+((printDate.getTime()==selectedDate.getTime()&&drawMonth==inst.selectedMonth&&inst._keyEvent)||(defaultDate.getTime()==printDate.getTime()&&defaultDate.getTime()==selectedDate.getTime())?" "+this._dayOverClass:"")+(unselectable?" "+this._unselectableClass+" ui-state-disabled":"")+(otherMonth&&!showOtherMonths?"":" "+daySettings[1]+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?"":" onclick=\"DP_jQuery.datepicker._selectDay('#"+inst.id+"',"+drawMonth+","+drawYear+', this);return false;"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():"&#xa0;"):(unselectable?'<span class="ui-state-default">'+printDate.getDate()+"</span>":'<a class="ui-state-default'+(printDate.getTime()==today.getTime()?" ui-state-highlight":"")+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" ui-state-active":"")+'" href="#">'+printDate.getDate()+"</a>"))+"</td>";printDate.setDate(printDate.getDate()+1);printDate=this._daylightSavingAdjust(printDate)}calender+=tbody+"</tr>"}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}calender+="</tbody></table>"+(isMultiMonth?"</div>"+((numMonths[0]>0&&col==numMonths[1]-1)?'<div class="ui-datepicker-row-break"></div>':""):"");group+=calender}html+=group}html+=buttonPanel+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,monthNames,monthNamesShort){minDate=(inst.rangeStart&&minDate&&selectedDate<minDate?selectedDate:minDate);var changeMonth=this._get(inst,"changeMonth");var changeYear=this._get(inst,"changeYear");var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='<div class="ui-datepicker-title">';var monthHtml="";if(secondary||!changeMonth){monthHtml+='<span class="ui-datepicker-month">'+monthNames[drawMonth]+"</span> "}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='<select class="ui-datepicker-month" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'M');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='<option value="'+month+'"'+(month==drawMonth?' selected="selected"':"")+">"+monthNamesShort[month]+"</option>"}}monthHtml+="</select>"}if(!showMonthAfterYear){html+=monthHtml+((secondary||changeMonth||changeYear)&&(!(changeMonth&&changeYear))?"&#xa0;":"")}if(secondary||!changeYear){html+='<span class="ui-datepicker-year">'+drawYear+"</span>"}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=drawYear+parseInt(years[0],10);endYear=drawYear+parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='<select class="ui-datepicker-year" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'Y');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(;year<=endYear;year++){html+='<option value="'+year+'"'+(year==drawYear?' selected="selected"':"")+">"+year+"</option>"}html+="</select>"}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?"&#xa0;":"")+monthHtml}html+="</div>";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart<newMinDate?inst.rangeStart:newMinDate);var minDate=newMinDate||this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date>=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.7.2";window.DP_jQuery=$})(jQuery);;/*
- * jQuery UI Progressbar 1.7.2
+(function(d,G){function L(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
+"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
+"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
+minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}function E(a,b){d.extend(a,
+b);for(var c in b)if(b[c]==null||b[c]==G)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.5"}});var y=(new Date).getTime();d.extend(L.prototype,{markerClassName:"hasDatepicker",log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){E(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=
+f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')}},
+_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&
+b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==
+""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,
+c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),
+true);this._updateDatepicker(b);this._updateAlternate(b)}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}E(a.settings,e||{});b=b&&b.constructor==
+Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);
+d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},
+_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().removeClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=
+d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().addClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;
+for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?d.extend({},e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&
+this._hideDatepicker();var h=this._getDateDatepicker(a,true);E(e.settings,f);this._attachments(d(a),e);this._autoSize(e);this._setDateDatepicker(a,h);this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,b);this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&
+!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass,b.dpDiv).add(d("td."+d.datepicker._currentClass,b.dpDiv));c[0]?d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]):d.datepicker._hideDatepicker();
+return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);c=a.ctrlKey||a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||
+a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,
+a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=d.datepicker._getInst(a.target);if(d.datepicker._get(b,"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));
+var c=String.fromCharCode(a.charCode==G?a.keyCode:a.charCode);return a.ctrlKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||
+a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);d.datepicker._curInst&&d.datepicker._curInst!=b&&d.datepicker._curInst.dpDiv.stop(true,true);var c=d.datepicker._get(b,"beforeShow");E(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);
+d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&
+d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){d.datepicker._datepickerShowing=true;var i=d.datepicker._getBorders(b.dpDiv);b.dpDiv.find("iframe.ui-datepicker-cover").css({left:-i[0],top:-i[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})};b.dpDiv.zIndex(d(a).zIndex()+1);d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,
+h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this,c=d.datepicker._getBorders(a.dpDiv);a.dpDiv.empty().append(this._generateHTML(a)).find("iframe.ui-datepicker-cover").css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){d(this).removeClass("ui-state-hover");
+this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).removeClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover",function(){if(!b._isDisabledDatepicker(a.inline?a.dpDiv.parent()[0]:a.input[0])){d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");d(this).addClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).addClass("ui-datepicker-prev-hover");
+this.className.indexOf("ui-datepicker-next")!=-1&&d(this).addClass("ui-datepicker-next-hover")}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();c=this._getNumberOfMonths(a);var e=c[1];e>1?a.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",17*e+"em"):a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");a.dpDiv[(c[0]!=1||c[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");
+a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input.focus()},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),
+k=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>k&&k>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1);)a=a[b?"previousSibling":"nextSibling"];
+a=d(a).offset();return[a.left,a.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();if(a=this._get(b,"onClose"))a.apply(b.input?b.input[0]:null,[b.input?b.input.val():
+"",b]);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&
+!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;
+b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=
+this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear=!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=
+d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,
+"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b==
+"object"?b.toString():b+"";if(b=="")return null;for(var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff,f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,k=c=-1,l=-1,u=-1,j=false,o=function(p){(p=z+1<a.length&&a.charAt(z+1)==p)&&z++;return p},m=function(p){o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"?4:p=="o"?
+3:2)+"}");p=b.substring(s).match(p);if(!p)throw"Missing number at position "+s;s+=p[0].length;return parseInt(p[0],10)},n=function(p,w,H){p=o(p)?H:w;for(w=0;w<p.length;w++)if(b.substr(s,p[w].length).toLowerCase()==p[w].toLowerCase()){s+=p[w].length;return w+1}throw"Unknown name at position "+s;},r=function(){if(b.charAt(s)!=a.charAt(z))throw"Unexpected literal at position "+s;s++},s=0,z=0;z<a.length;z++)if(j)if(a.charAt(z)=="'"&&!o("'"))j=false;else r();else switch(a.charAt(z)){case "d":l=m("d");
+break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":k=m("m");break;case "M":k=n("M",i,g);break;case "y":c=m("y");break;case "@":var v=new Date(m("@"));c=v.getFullYear();k=v.getMonth()+1;l=v.getDate();break;case "!":v=new Date((m("!")-this._ticksTo1970)/1E4);c=v.getFullYear();k=v.getMonth()+1;l=v.getDate();break;case "'":if(o("'"))r();else j=true;break;default:r()}if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>
+-1){k=1;l=u;do{e=this._getDaysInMonth(c,k-1);if(l<=e)break;k++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,k-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=k||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*
+60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=j+1<a.length&&a.charAt(j+1)==o)&&j++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<n;)m="0"+m;return m},k=function(o,m,n,r){return i(o)?r[m]:n[m]},l="",u=false;if(b)for(var j=0;j<a.length;j++)if(u)if(a.charAt(j)==
+"'"&&!i("'"))u=false;else l+=a.charAt(j);else switch(a.charAt(j)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=k("D",b.getDay(),e,f);break;case "o":l+=g("o",(b.getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5,3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=k("M",b.getMonth(),h,c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+=
+"'";else u=true;break;default:l+=a.charAt(j)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+="0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==G?a.settings[b]:this._defaults[b]},
+_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,
+this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,k=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,j=u.exec(h);j;){switch(j[2]||"d"){case "d":case "D":g+=
+parseInt(j[1],10);break;case "w":case "W":g+=parseInt(j[1],10)*7;break;case "m":case "M":l+=parseInt(j[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(k,l));break;case "y":case "Y":k+=parseInt(j[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(k,l));break}j=u.exec(h)}return new Date(k,l,g)};if(b=(b=b==null?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):b)&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},
+_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?
+"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),k=
+this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),j=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=j&&n<j?j:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,
+"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-k,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', -"+k+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+
+n+"</span></a>";var r=this._get(a,"nextText");r=!h?r:this.formatDate(r,this._daylightSavingAdjust(new Date(m,g+k,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', +"+k+", 'M');\" title=\""+r+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+r+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+r+'"><span class="ui-icon ui-icon-circle-triangle-'+
+(c?"w":"e")+'">'+r+"</span></a>";k=this._get(a,"currentText");r=this._get(a,"gotoCurrent")&&a.currentDay?u:b;k=!h?k:this.formatDate(k,r,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+y+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,r)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+
+y+".datepicker._gotoToday('#"+a.id+"');\">"+k+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;k=this._get(a,"showWeek");r=this._get(a,"dayNames");this._get(a,"dayNamesShort");var s=this._get(a,"dayNamesMin"),z=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),w=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var M=this._getDefaultDate(a),I="",C=0;C<i[0];C++){for(var N=
+"",D=0;D<i[1];D++){var J=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",x="";if(l){x+='<div class="ui-datepicker-group';if(i[1]>1)switch(D){case 0:x+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:x+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:x+=" ui-datepicker-group-middle";t="";break}x+='">'}x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?
+f:n:"")+(/all|right/.test(t)&&C==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,j,o,C>0||D>0,z,v)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var A=k?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(t=0;t<7;t++){var q=(t+h)%7;A+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+r[q]+'">'+s[q]+"</span></th>"}x+=A+"</tr></thead><tbody>";A=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,
+A);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;A=l?6:Math.ceil((t+A)/7);q=this._daylightSavingAdjust(new Date(m,g,1-t));for(var O=0;O<A;O++){x+="<tr>";var P=!k?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(q)+"</td>";for(t=0;t<7;t++){var F=p?p.apply(a.input?a.input[0]:null,[q]):[true,""],B=q.getMonth()!=g,K=B&&!H||!F[0]||j&&q<j||o&&q>o;P+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(B?" ui-datepicker-other-month":"")+(q.getTime()==J.getTime()&&g==a.selectedMonth&&
+a._keyEvent||M.getTime()==q.getTime()&&M.getTime()==J.getTime()?" "+this._dayOverClass:"")+(K?" "+this._unselectableClass+" ui-state-disabled":"")+(B&&!w?"":" "+F[1]+(q.getTime()==u.getTime()?" "+this._currentClass:"")+(q.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!B||w)&&F[2]?' title="'+F[2]+'"':"")+(K?"":' onclick="DP_jQuery_'+y+".datepicker._selectDay('#"+a.id+"',"+q.getMonth()+","+q.getFullYear()+', this);return false;"')+">"+(B&&!w?"&#xa0;":K?'<span class="ui-state-default">'+q.getDate()+
+"</span>":'<a class="ui-state-default'+(q.getTime()==b.getTime()?" ui-state-highlight":"")+(q.getTime()==J.getTime()?" ui-state-active":"")+(B?" ui-priority-secondary":"")+'" href="#">'+q.getDate()+"</a>")+"</td>";q.setDate(q.getDate()+1);q=this._daylightSavingAdjust(q)}x+=P+"</tr>"}g++;if(g>11){g=0;m++}x+="</tbody></table>"+(l?"</div>"+(i[0]>0&&D==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");N+=x}I+=N}I+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':
+"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var k=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),j='<div class="ui-datepicker-title">',o="";if(h||!k)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+
+a.id+"');\">";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&(!m||n<=f.getMonth()))o+='<option value="'+n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(j+=o+(h||!(k&&l)?"&#xa0;":""));if(h||!l)j+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,
+i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(j+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=g;b++)j+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";j+="</select>"}j+=this._get(a,"yearSuffix");if(u)j+=(h||!(k&&l)?"&#xa0;":"")+o;j+="</div>";return j},_adjustInstDate:function(a,b,c){var e=
+a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,
+"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);
+c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,
+"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=
+function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));
+return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new L;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.5";window["DP_jQuery_"+y]=d})(jQuery);
+;/*
+ * jQuery UI Progressbar 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Progressbar
  *
  * Depends:
- *   ui.core.js
+ *   jquery.ui.core.js
+ *   jquery.ui.widget.js
  */
-(function(a){a.widget("ui.progressbar",{_init:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=a('<div class="ui-progressbar-value ui-widget-header ui-corner-left"></div>').appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow").removeData("progressbar").unbind(".progressbar");this.valueDiv.remove();a.widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===undefined){return this._value()}this._setData("value",b);return this},_setData:function(b,c){switch(b){case"value":this.options.value=c;this._refreshValue();this._trigger("change",null,{});break}a.widget.prototype._setData.apply(this,arguments)},_value:function(){var b=this.options.value;if(b<this._valueMin()){b=this._valueMin()}if(b>this._valueMax()){b=this._valueMax()}return b},_valueMin:function(){var b=0;return b},_valueMax:function(){var b=100;return b},_refreshValue:function(){var b=this.value();this.valueDiv[b==this._valueMax()?"addClass":"removeClass"]("ui-corner-right");this.valueDiv.width(b+"%");this.element.attr("aria-valuenow",b)}});a.extend(a.ui.progressbar,{version:"1.7.2",defaults:{value:0}})})(jQuery);;/*
- * jQuery UI Effects 1.7.2
+(function(b,c){b.widget("ui.progressbar",{options:{value:0},min:0,max:100,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
+this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===c)return this._value();this._setOption("value",a);return this},_setOption:function(a,d){if(a==="value"){this.options.value=d;this._refreshValue();this._trigger("change")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.max,Math.max(this.min,a))},_refreshValue:function(){var a=this.value();this.valueDiv.toggleClass("ui-corner-right",
+a===this.max).width(a+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.5"})})(jQuery);
+;/*
+ * jQuery UI Effects 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/
  */
-jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.data("ec.storage."+h[f],g[0].style[h[f]])}}},restore:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.css(h[f],g.data("ec.storage."+h[f]))}}},setMode:function(f,g){if(g=="toggle"){g=f.is(":hidden")?"show":"hide"}return g},getBaseline:function(g,h){var i,f;switch(g[0]){case"top":i=0;break;case"middle":i=0.5;break;case"bottom":i=1;break;default:i=g[0]/h.height}switch(g[1]){case"left":f=0;break;case"center":f=0.5;break;case"right":f=1;break;default:f=g[1]/h.width}return{x:f,y:i}},createWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent()}var g={width:f.outerWidth(true),height:f.outerHeight(true),"float":f.css("float")};f.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(d.isFunction(arguments[0])||typeof arguments[0]=="boolean")){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return -(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f},easeOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return h*Math.pow(2,-10*i)*Math.sin((i*l-j)*(2*Math.PI)/k)+m+f},easeInOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l/2)==2){return f+m}if(!k){k=l*(0.3*1.5)}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}if(i<1){return -0.5*(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f}return h*Math.pow(2,-10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k)*0.5+m+f},easeInBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*(h/=j)*h*((i+1)*h-i)+f},easeOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*((h=h/j-1)*h*((i+1)*h+i)+1)+f},easeInOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}if((h/=j/2)<1){return k/2*(h*h*(((i*=(1.525))+1)*h-i))+f}return k/2*((h-=2)*h*(((i*=(1.525))+1)*h+i)+2)+f},easeInBounce:function(g,h,f,j,i){return j-d.easing.easeOutBounce(g,i-h,0,j,i)+f},easeOutBounce:function(g,h,f,j,i){if((h/=i)<(1/2.75)){return j*(7.5625*h*h)+f}else{if(h<(2/2.75)){return j*(7.5625*(h-=(1.5/2.75))*h+0.75)+f}else{if(h<(2.5/2.75)){return j*(7.5625*(h-=(2.25/2.75))*h+0.9375)+f}else{return j*(7.5625*(h-=(2.625/2.75))*h+0.984375)+f}}}},easeInOutBounce:function(g,h,f,j,i){if(h<i/2){return d.easing.easeInBounce(g,h*2,0,j,i)*0.5+f}return d.easing.easeOutBounce(g,h*2-i,0,j,i)*0.5+j*0.5+f}})})(jQuery);;/*
- * jQuery UI Effects Blind 1.7.2
+jQuery.effects||function(f,j){function l(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
+16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return m.transparent;return m[f.trim(c).toLowerCase()]}function r(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return l(b)}function n(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
+a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function o(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in s||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function t(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
+a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:f.fx.speeds[b]||f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=r(b.elem,a);b.end=l(b.end);b.colorInit=
+true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var m={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,
+183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,
+165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},p=["add","remove","toggle"],s={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,d){if(f.isFunction(b)){d=b;b=null}return this.each(function(){var e=f(this),g=e.attr("style")||" ",h=o(n.call(this)),q,u=e.attr("className");f.each(p,function(v,
+i){c[i]&&e[i+"Class"](c[i])});q=o(n.call(this));e.attr("className",u);e.animate(t(h,q),a,b,function(){f.each(p,function(v,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)})})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?
+f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.5",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==
+null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,a){var b;switch(c[0]){case "top":b=0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();
+var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});
+c.css({position:"relative",top:0,left:0})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments);a={options:a[1],duration:a[2],callback:a[3]};var b=f.effects[c];return b&&!f.fx.off?b.call(this,a):this},_show:f.fn.show,show:function(c){if(!c||
+typeof c=="number"||f.fx.speeds[c]||!f.effects[c])return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(!c||typeof c=="number"||f.fx.speeds[c]||!f.effects[c])return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(!c||typeof c=="number"||f.fx.speeds[c]||!f.effects[c]||typeof c==
+"boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,
+a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=
+e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+
+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/
+2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*
+a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;
+return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,
+a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
+;/*
+ * jQuery UI Effects Blind 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Blind
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.blind=function(b){return this.queue(function(){var d=a(this),c=["position","top","left"];var h=a.effects.setMode(d,b.options.mode||"hide");var g=b.options.direction||"vertical";a.effects.save(d,c);d.show();var j=a.effects.createWrapper(d).css({overflow:"hidden"});var e=(g=="vertical")?"height":"width";var i=(g=="vertical")?j.height():j.width();if(h=="show"){j.css(e,0)}var f={};f[e]=h=="show"?i:0;j.animate(f,b.duration,b.options.easing,function(){if(h=="hide"){d.hide()}a.effects.restore(d,c);a.effects.removeWrapper(d);if(b.callback){b.callback.apply(d[0],arguments)}d.dequeue()})})}})(jQuery);;/*
- * jQuery UI Effects Bounce 1.7.2
+(function(b){b.effects.blind=function(c){return this.queue(function(){var a=b(this),g=["position","top","left"],f=b.effects.setMode(a,c.options.mode||"hide"),d=c.options.direction||"vertical";b.effects.save(a,g);a.show();var e=b.effects.createWrapper(a).css({overflow:"hidden"}),h=d=="vertical"?"height":"width";d=d=="vertical"?e.height():e.width();f=="show"&&e.css(h,0);var i={};i[h]=f=="show"?d:0;e.animate(i,c.duration,c.options.easing,function(){f=="hide"&&a.hide();b.effects.restore(a,g);b.effects.removeWrapper(a);
+c.callback&&c.callback.apply(a[0],arguments);a.dequeue()})})}})(jQuery);
+;/*
+ * jQuery UI Effects Bounce 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Bounce
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.bounce=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"up";var c=b.options.distance||20;var d=b.options.times||5;var g=b.duration||250;if(/show|hide/.test(k)){l.push("opacity")}a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var c=b.options.distance||(f=="top"?e.outerHeight({margin:true})/3:e.outerWidth({margin:true})/3);if(k=="show"){e.css("opacity",0).css(f,p=="pos"?-c:c)}if(k=="hide"){c=c/(d*2)}if(k!="hide"){d--}if(k=="show"){var h={opacity:1};h[f]=(p=="pos"?"+=":"-=")+c;e.animate(h,g/2,b.options.easing);c=c/2;d--}for(var j=0;j<d;j++){var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing);c=(k=="hide")?c*2:c/2}if(k=="hide"){var h={opacity:0};h[f]=(p=="pos"?"-=":"+=")+c;e.animate(h,g/2,b.options.easing,function(){e.hide();a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}else{var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);;/*
- * jQuery UI Effects Clip 1.7.2
+(function(e){e.effects.bounce=function(b){return this.queue(function(){var a=e(this),l=["position","top","left"],h=e.effects.setMode(a,b.options.mode||"effect"),d=b.options.direction||"up",c=b.options.distance||20,m=b.options.times||5,i=b.duration||250;/show|hide/.test(h)&&l.push("opacity");e.effects.save(a,l);a.show();e.effects.createWrapper(a);var f=d=="up"||d=="down"?"top":"left";d=d=="up"||d=="left"?"pos":"neg";c=b.options.distance||(f=="top"?a.outerHeight({margin:true})/3:a.outerWidth({margin:true})/
+3);if(h=="show")a.css("opacity",0).css(f,d=="pos"?-c:c);if(h=="hide")c/=m*2;h!="hide"&&m--;if(h=="show"){var g={opacity:1};g[f]=(d=="pos"?"+=":"-=")+c;a.animate(g,i/2,b.options.easing);c/=2;m--}for(g=0;g<m;g++){var j={},k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing);c=h=="hide"?c*2:c/2}if(h=="hide"){g={opacity:0};g[f]=(d=="pos"?"-=":"+=")+c;a.animate(g,i/2,b.options.easing,function(){a.hide();e.effects.restore(a,l);e.effects.removeWrapper(a);
+b.callback&&b.callback.apply(this,arguments)})}else{j={};k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing,function(){e.effects.restore(a,l);e.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments)})}a.queue("fx",function(){a.dequeue()});a.dequeue()})}})(jQuery);
+;/*
+ * jQuery UI Effects Clip 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Clip
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.clip=function(b){return this.queue(function(){var f=a(this),j=["position","top","left","height","width"];var i=a.effects.setMode(f,b.options.mode||"hide");var k=b.options.direction||"vertical";a.effects.save(f,j);f.show();var c=a.effects.createWrapper(f).css({overflow:"hidden"});var e=f[0].tagName=="IMG"?c:f;var g={size:(k=="vertical")?"height":"width",position:(k=="vertical")?"top":"left"};var d=(k=="vertical")?e.height():e.width();if(i=="show"){e.css(g.size,0);e.css(g.position,d/2)}var h={};h[g.size]=i=="show"?d:0;h[g.position]=i=="show"?0:d/2;e.animate(h,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){f.hide()}a.effects.restore(f,j);a.effects.removeWrapper(f);if(b.callback){b.callback.apply(f[0],arguments)}f.dequeue()}})})}})(jQuery);;/*
- * jQuery UI Effects Drop 1.7.2
+(function(b){b.effects.clip=function(e){return this.queue(function(){var a=b(this),i=["position","top","left","height","width"],f=b.effects.setMode(a,e.options.mode||"hide"),c=e.options.direction||"vertical";b.effects.save(a,i);a.show();var d=b.effects.createWrapper(a).css({overflow:"hidden"});d=a[0].tagName=="IMG"?d:a;var g={size:c=="vertical"?"height":"width",position:c=="vertical"?"top":"left"};c=c=="vertical"?d.height():d.width();if(f=="show"){d.css(g.size,0);d.css(g.position,c/2)}var h={};h[g.size]=
+f=="show"?c:0;h[g.position]=f=="show"?0:c/2;d.animate(h,{queue:false,duration:e.duration,easing:e.options.easing,complete:function(){f=="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);e.callback&&e.callback.apply(a[0],arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Drop 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Drop
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.drop=function(b){return this.queue(function(){var e=a(this),d=["position","top","left","opacity"];var i=a.effects.setMode(e,b.options.mode||"hide");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e);var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true})/2:e.outerWidth({margin:true})/2);if(i=="show"){e.css("opacity",0).css(f,c=="pos"?-j:j)}var g={opacity:i=="show"?1:0};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
- * jQuery UI Effects Explode 1.7.2
+(function(c){c.effects.drop=function(d){return this.queue(function(){var a=c(this),h=["position","top","left","opacity"],e=c.effects.setMode(a,d.options.mode||"hide"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a);var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true})/2:a.outerWidth({margin:true})/2);if(e=="show")a.css("opacity",0).css(f,b=="pos"?-g:g);var i={opacity:e=="show"?1:
+0};i[f]=(e=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Explode 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Explode
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.explode=function(b){return this.queue(function(){var k=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;var e=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?(a(this).is(":visible")?"hide":"show"):b.options.mode;var h=a(this).show().css("visibility","hidden");var l=h.offset();l.top-=parseInt(h.css("marginTop"),10)||0;l.left-=parseInt(h.css("marginLeft"),10)||0;var g=h.outerWidth(true);var c=h.outerHeight(true);for(var f=0;f<k;f++){for(var d=0;d<e;d++){h.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-d*(g/e),top:-f*(c/k)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/e,height:c/k,left:l.left+d*(g/e)+(b.options.mode=="show"?(d-Math.floor(e/2))*(g/e):0),top:l.top+f*(c/k)+(b.options.mode=="show"?(f-Math.floor(k/2))*(c/k):0),opacity:b.options.mode=="show"?0:1}).animate({left:l.left+d*(g/e)+(b.options.mode=="show"?0:(d-Math.floor(e/2))*(g/e)),top:l.top+f*(c/k)+(b.options.mode=="show"?0:(f-Math.floor(k/2))*(c/k)),opacity:b.options.mode=="show"?1:0},b.duration||500)}}setTimeout(function(){b.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();if(b.callback){b.callback.apply(h[0])}h.dequeue();a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);;/*
- * jQuery UI Effects Fold 1.7.2
+(function(j){j.effects.explode=function(a){return this.queue(function(){var c=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3,d=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3;a.options.mode=a.options.mode=="toggle"?j(this).is(":visible")?"hide":"show":a.options.mode;var b=j(this).show().css("visibility","hidden"),g=b.offset();g.top-=parseInt(b.css("marginTop"),10)||0;g.left-=parseInt(b.css("marginLeft"),10)||0;for(var h=b.outerWidth(true),i=b.outerHeight(true),e=0;e<c;e++)for(var f=
+0;f<d;f++)b.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+
+e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery);
+;/*
+ * jQuery UI Effects Fade 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * http://docs.jquery.com/UI/Effects/Fade
+ *
+ * Depends:
+ *	jquery.effects.core.js
+ */
+(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Fold 1.8.5
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Fold
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.fold=function(b){return this.queue(function(){var e=a(this),k=["position","top","left"];var h=a.effects.setMode(e,b.options.mode||"hide");var o=b.options.size||15;var n=!(!b.options.horizFirst);var g=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(e,k);e.show();var d=a.effects.createWrapper(e).css({overflow:"hidden"});var i=((h=="show")!=n);var f=i?["width","height"]:["height","width"];var c=i?[d.width(),d.height()]:[d.height(),d.width()];var j=/([0-9]+)%/.exec(o);if(j){o=parseInt(j[1],10)/100*c[h=="hide"?0:1]}if(h=="show"){d.css(n?{height:0,width:o}:{height:o,width:0})}var m={},l={};m[f[0]]=h=="show"?c[0]:o;l[f[1]]=h=="show"?c[1]:0;d.animate(m,g,b.options.easing).animate(l,g,b.options.easing,function(){if(h=="hide"){e.hide()}a.effects.restore(e,k);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(e[0],arguments)}e.dequeue()})})}})(jQuery);;/*
- * jQuery UI Effects Highlight 1.7.2
+(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","left"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1],10)/100*
+f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery);
+;/*
+ * jQuery UI Effects Highlight 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Highlight
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.highlight=function(b){return this.queue(function(){var e=a(this),d=["backgroundImage","backgroundColor","opacity"];var h=a.effects.setMode(e,b.options.mode||"show");var c=b.options.color||"#ffff99";var g=e.css("backgroundColor");a.effects.save(e,d);e.show();e.css({backgroundImage:"none",backgroundColor:c});var f={backgroundColor:g};if(h=="hide"){f.opacity=0}e.animate(f,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(h=="hide"){e.hide()}a.effects.restore(e,d);if(h=="show"&&a.browser.msie){this.style.removeAttribute("filter")}if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
- * jQuery UI Effects Pulsate 1.7.2
+(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&&
+this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Pulsate 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Pulsate
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.pulsate=function(b){return this.queue(function(){var d=a(this);var g=a.effects.setMode(d,b.options.mode||"show");var f=b.options.times||5;var e=b.duration?b.duration/2:a.fx.speeds._default/2;if(g=="hide"){f--}if(d.is(":hidden")){d.css("opacity",0);d.show();d.animate({opacity:1},e,b.options.easing);f=f-2}for(var c=0;c<f;c++){d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing)}if(g=="hide"){d.animate({opacity:0},e,b.options.easing,function(){d.hide();if(b.callback){b.callback.apply(this,arguments)}})}else{d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing,function(){if(b.callback){b.callback.apply(this,arguments)}})}d.queue("fx",function(){d.dequeue()});d.dequeue()})}})(jQuery);;/*
- * jQuery UI Effects Scale 1.7.2
+(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c<times;c++){b.animate({opacity:animateTo},duration,a.options.easing);animateTo=(animateTo+1)%2}b.animate({opacity:animateTo},duration,
+a.options.easing,function(){animateTo==0&&b.hide();a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()}).dequeue()})}})(jQuery);
+;/*
+ * jQuery UI Effects Scale 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Scale
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.puff=function(b){return this.queue(function(){var f=a(this);var c=a.extend(true,{},b.options);var h=a.effects.setMode(f,b.options.mode||"hide");var g=parseInt(b.options.percent,10)||150;c.fade=true;var e={height:f.height(),width:f.width()};var d=g/100;f.from=(h=="hide")?e:{height:e.height*d,width:e.width*d};c.from=f.from;c.percent=(h=="hide")?g:100;c.mode=h;f.effect("scale",c,b.duration,b.callback);f.dequeue()})};a.effects.scale=function(b){return this.queue(function(){var g=a(this);var d=a.extend(true,{},b.options);var j=a.effects.setMode(g,b.options.mode||"effect");var h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:(j=="hide"?0:100));var i=b.options.direction||"both";var c=b.options.origin;if(j!="effect"){d.origin=c||["middle","center"];d.restore=true}var f={height:g.height(),width:g.width()};g.from=b.options.from||(j=="show"?{height:0,width:0}:f);var e={y:i!="horizontal"?(h/100):1,x:i!="vertical"?(h/100):1};g.to={height:f.height*e.y,width:f.width*e.x};if(b.options.fade){if(j=="show"){g.from.opacity=0;g.to.opacity=1}if(j=="hide"){g.from.opacity=1;g.to.opacity=0}}d.from=g.from;d.to=g.to;d.mode=j;g.effect("size",d,b.duration,b.callback);g.dequeue()})};a.effects.size=function(b){return this.queue(function(){var c=a(this),n=["position","top","left","width","height","overflow","opacity"];var m=["position","top","left","overflow","opacity"];var j=["width","height","overflow"];var p=["fontSize"];var k=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"];var f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"];var g=a.effects.setMode(c,b.options.mode||"effect");var i=b.options.restore||false;var e=b.options.scale||"both";var o=b.options.origin;var d={height:c.height(),width:c.width()};c.from=b.options.from||d;c.to=b.options.to||d;if(o){var h=a.effects.getBaseline(o,d);c.from.top=(d.height-c.from.height)*h.y;c.from.left=(d.width-c.from.width)*h.x;c.to.top=(d.height-c.to.height)*h.y;c.to.left=(d.width-c.to.width)*h.x}var l={from:{y:c.from.height/d.height,x:c.from.width/d.width},to:{y:c.to.height/d.height,x:c.to.width/d.width}};if(e=="box"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(k);c.from=a.effects.setTransition(c,k,l.from.y,c.from);c.to=a.effects.setTransition(c,k,l.to.y,c.to)}if(l.from.x!=l.to.x){n=n.concat(f);c.from=a.effects.setTransition(c,f,l.from.x,c.from);c.to=a.effects.setTransition(c,f,l.to.x,c.to)}}if(e=="content"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(p);c.from=a.effects.setTransition(c,p,l.from.y,c.from);c.to=a.effects.setTransition(c,p,l.to.y,c.to)}}a.effects.save(c,i?n:m);c.show();a.effects.createWrapper(c);c.css("overflow","hidden").css(c.from);if(e=="content"||e=="both"){k=k.concat(["marginTop","marginBottom"]).concat(p);f=f.concat(["marginLeft","marginRight"]);j=n.concat(k).concat(f);c.find("*[width]").each(function(){child=a(this);if(i){a.effects.save(child,j)}var q={height:child.height(),width:child.width()};child.from={height:q.height*l.from.y,width:q.width*l.from.x};child.to={height:q.height*l.to.y,width:q.width*l.to.x};if(l.from.y!=l.to.y){child.from=a.effects.setTransition(child,k,l.from.y,child.from);child.to=a.effects.setTransition(child,k,l.to.y,child.to)}if(l.from.x!=l.to.x){child.from=a.effects.setTransition(child,f,l.from.x,child.from);child.to=a.effects.setTransition(child,f,l.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){if(i){a.effects.restore(child,j)}})})}c.animate(c.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(g=="hide"){c.hide()}a.effects.restore(c,i?n:m);a.effects.removeWrapper(c);if(b.callback){b.callback.apply(this,arguments)}c.dequeue()}})})}})(jQuery);;/*
- * jQuery UI Effects Shake 1.7.2
+(function(c){c.effects.puff=function(b){return this.queue(function(){var a=c(this),e=c.effects.setMode(a,b.options.mode||"hide"),g=parseInt(b.options.percent,10)||150,h=g/100,i={height:a.height(),width:a.width()};c.extend(b.options,{fade:true,mode:e,percent:e=="hide"?g:100,from:e=="hide"?i:{height:i.height*h,width:i.width*h}});a.effect("scale",b.options,b.duration,b.callback);a.dequeue()})};c.effects.scale=function(b){return this.queue(function(){var a=c(this),e=c.extend(true,{},b.options),g=c.effects.setMode(a,
+b.options.mode||"effect"),h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:g=="hide"?0:100),i=b.options.direction||"both",f=b.options.origin;if(g!="effect"){e.origin=f||["middle","center"];e.restore=true}f={height:a.height(),width:a.width()};a.from=b.options.from||(g=="show"?{height:0,width:0}:f);h={y:i!="horizontal"?h/100:1,x:i!="vertical"?h/100:1};a.to={height:f.height*h.y,width:f.width*h.x};if(b.options.fade){if(g=="show"){a.from.opacity=0;a.to.opacity=1}if(g=="hide"){a.from.opacity=
+1;a.to.opacity=0}}e.from=a.from;e.to=a.to;e.mode=g;a.effect("size",e,b.duration,b.callback);a.dequeue()})};c.effects.size=function(b){return this.queue(function(){var a=c(this),e=["position","top","left","width","height","overflow","opacity"],g=["position","top","left","overflow","opacity"],h=["width","height","overflow"],i=["fontSize"],f=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],k=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=c.effects.setMode(a,
+b.options.mode||"effect"),n=b.options.restore||false,m=b.options.scale||"both",l=b.options.origin,j={height:a.height(),width:a.width()};a.from=b.options.from||j;a.to=b.options.to||j;if(l){l=c.effects.getBaseline(l,j);a.from.top=(j.height-a.from.height)*l.y;a.from.left=(j.width-a.from.width)*l.x;a.to.top=(j.height-a.to.height)*l.y;a.to.left=(j.width-a.to.width)*l.x}var d={from:{y:a.from.height/j.height,x:a.from.width/j.width},to:{y:a.to.height/j.height,x:a.to.width/j.width}};if(m=="box"||m=="both"){if(d.from.y!=
+d.to.y){e=e.concat(f);a.from=c.effects.setTransition(a,f,d.from.y,a.from);a.to=c.effects.setTransition(a,f,d.to.y,a.to)}if(d.from.x!=d.to.x){e=e.concat(k);a.from=c.effects.setTransition(a,k,d.from.x,a.from);a.to=c.effects.setTransition(a,k,d.to.x,a.to)}}if(m=="content"||m=="both")if(d.from.y!=d.to.y){e=e.concat(i);a.from=c.effects.setTransition(a,i,d.from.y,a.from);a.to=c.effects.setTransition(a,i,d.to.y,a.to)}c.effects.save(a,n?e:g);a.show();c.effects.createWrapper(a);a.css("overflow","hidden").css(a.from);
+if(m=="content"||m=="both"){f=f.concat(["marginTop","marginBottom"]).concat(i);k=k.concat(["marginLeft","marginRight"]);h=e.concat(f).concat(k);a.find("*[width]").each(function(){child=c(this);n&&c.effects.save(child,h);var o={height:child.height(),width:child.width()};child.from={height:o.height*d.from.y,width:o.width*d.from.x};child.to={height:o.height*d.to.y,width:o.width*d.to.x};if(d.from.y!=d.to.y){child.from=c.effects.setTransition(child,f,d.from.y,child.from);child.to=c.effects.setTransition(child,
+f,d.to.y,child.to)}if(d.from.x!=d.to.x){child.from=c.effects.setTransition(child,k,d.from.x,child.from);child.to=c.effects.setTransition(child,k,d.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){n&&c.effects.restore(child,h)})})}a.animate(a.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){a.to.opacity===0&&a.css("opacity",a.from.opacity);p=="hide"&&a.hide();c.effects.restore(a,n?e:g);c.effects.removeWrapper(a);b.callback&&
+b.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Shake 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Shake
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.shake=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"left";var c=b.options.distance||20;var d=b.options.times||3;var g=b.duration||b.options.duration||140;a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var h={},o={},m={};h[f]=(p=="pos"?"-=":"+=")+c;o[f]=(p=="pos"?"+=":"-=")+c*2;m[f]=(p=="pos"?"-=":"+=")+c*2;e.animate(h,g,b.options.easing);for(var j=1;j<d;j++){e.animate(o,g,b.options.easing).animate(m,g,b.options.easing)}e.animate(o,g,b.options.easing).animate(h,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}});e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);;/*
- * jQuery UI Effects Slide 1.7.2
+(function(d){d.effects.shake=function(a){return this.queue(function(){var b=d(this),j=["position","top","left"];d.effects.setMode(b,a.options.mode||"effect");var c=a.options.direction||"left",e=a.options.distance||20,l=a.options.times||3,f=a.duration||a.options.duration||140;d.effects.save(b,j);b.show();d.effects.createWrapper(b);var g=c=="up"||c=="down"?"top":"left",h=c=="up"||c=="left"?"pos":"neg";c={};var i={},k={};c[g]=(h=="pos"?"-=":"+=")+e;i[g]=(h=="pos"?"+=":"-=")+e*2;k[g]=(h=="pos"?"-=":"+=")+
+e*2;b.animate(c,f,a.options.easing);for(e=1;e<l;e++)b.animate(i,f,a.options.easing).animate(k,f,a.options.easing);b.animate(i,f,a.options.easing).animate(c,f/2,a.options.easing,function(){d.effects.restore(b,j);d.effects.removeWrapper(b);a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()});b.dequeue()})}})(jQuery);
+;/*
+ * jQuery UI Effects Slide 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Slide
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.slide=function(b){return this.queue(function(){var e=a(this),d=["position","top","left"];var i=a.effects.setMode(e,b.options.mode||"show");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e).css({overflow:"hidden"});var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true}):e.outerWidth({margin:true}));if(i=="show"){e.css(f,c=="pos"?-j:j)}var g={};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
- * jQuery UI Effects Transfer 1.7.2
+(function(c){c.effects.slide=function(d){return this.queue(function(){var a=c(this),h=["position","top","left"],e=c.effects.setMode(a,d.options.mode||"show"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a).css({overflow:"hidden"});var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true}):a.outerWidth({margin:true}));if(e=="show")a.css(f,b=="pos"?-g:g);var i={};i[f]=(e=="show"?b=="pos"?
+"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
+;/*
+ * jQuery UI Effects Transfer 1.8.5
  *
- * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * http://docs.jquery.com/UI/Effects/Transfer
  *
  * Depends:
- *	effects.core.js
+ *	jquery.effects.core.js
  */
-(function(a){a.effects.transfer=function(b){return this.queue(function(){var f=a(this),h=a(b.options.to),e=h.offset(),g={top:e.top,left:e.left,height:h.innerHeight(),width:h.innerWidth()},d=f.offset(),c=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);;
\ No newline at end of file
+(function(e){e.effects.transfer=function(a){return this.queue(function(){var b=e(this),c=e(a.options.to),d=c.offset();c={top:d.top,left:d.left,height:c.innerHeight(),width:c.innerWidth()};d=b.offset();var f=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments);
+b.dequeue()})})}})(jQuery);
+;
\ No newline at end of file
--- a/web/data/uiprops.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/data/uiprops.py	Wed Oct 13 08:37:21 2010 +0200
@@ -103,18 +103,36 @@
 pageContentPadding = '1em'
 pageMinHeight = '800px'
 
-# boxes
-boxTitleBg = lazystr('%(headerBgColor)s url("boxHeader.png") repeat-x 50%% 50%%')
-boxBodyBgColor = '#efefde'
+# boxes ########################################################################
+
+# title of contextFree / contextual boxes
+contextFreeBoxTitleBgColor = '#CFCEB7'
+contextFreeBoxTitleBg = lazystr('%(contextFreeBoxTitleBgColor)s url("contextFreeBoxHeader.png") repeat-x 50%% 50%%')
+contextFreeBoxTitleColor = '#000'
+
+contextualBoxTitleBgColor = '#FF9900'
+contextualBoxTitleBg = lazystr('%(contextualBoxTitleBgColor)s url("contextualBoxHeader.png") repeat-x 50%% 50%%')
+contextualBoxTitleColor = '#FFF'
 
-# action, search, sideBoxes
-actionBoxTitleBgColor = '#cfceb7'
-actionBoxTitleBg = lazystr('%(actionBoxTitleBgColor)s url("actionBoxHeader.png") repeat-x 50%% 50%%')
-sideBoxBodyBgColor = '#f8f8ee'
-sideBoxBodyBg = lazystr('%(sideBoxBodyBgColor)s')
-sideBoxBodyColor = '#555544'
+# title of 'incontext' boxes (eg displayed insinde the primary view)
+incontextBoxTitleBgColor = lazystr('%(contextFreeBoxTitleBgColor)s')
+incontextBoxTitleBg = lazystr('%(incontextBoxTitleBgColor)s url("incontextBoxHeader.png") repeat-x 50%% 50%%')
+incontextBoxTitleColor = '#000'
 
-# table listing & co
+# body of boxes in the left or right column (whatever contextFree / contextual)
+leftrightBoxBodyBgColor = '#FFF'
+leftrightBoxBodyBg = lazystr('%(leftrightBoxBodyBgColor)s')
+leftrightBoxBodyColor = '#black'
+leftrightBoxBodyHoverBgColor = '#EEEDD9'
+
+# body of 'incontext' boxes (eg displayed insinde the primary view)
+incontextBoxBodyBgColor = '#f8f8ee'
+incontextBoxBodyBg = lazystr('%(incontextBoxBodyBgColor)s')
+incontextBoxBodyColor = '#555544'
+incontextBoxBodyHoverBgColor = lazystr('%(incontextBoxBodyBgColor)s')
+
+
+# table listing & co ###########################################################
 listingBorderColor = '#ccc'
 listingHeaderBgColor = '#efefef'
 listingHihligthedBgColor = '#fbfbfb'
--- a/web/facet.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/facet.py	Wed Oct 13 08:37:21 2010 +0200
@@ -55,7 +55,7 @@
 from logilab.common.date import datetime2ticks
 from logilab.common.compat import all
 
-from rql import parse, nodes
+from rql import parse, nodes, utils
 
 from cubicweb import Unauthorized, typed_eid
 from cubicweb.schema import display_name
@@ -165,18 +165,27 @@
         return ovar
     return None
 
+def _make_relation(rqlst, mainvar, rtype, role):
+    newvar = rqlst.make_variable()
+    if role == 'object':
+        rel = nodes.make_relation(newvar, rtype, (mainvar,), nodes.VariableRef)
+    else:
+        rel = nodes.make_relation(mainvar, rtype, (newvar,), nodes.VariableRef)
+    return newvar, rel
+
 def _add_rtype_relation(rqlst, mainvar, rtype, role):
     """add a relation relying `mainvar` to entities linked by the `rtype`
     relation (where `mainvar` has `role`)
 
     return the inserted variable for linked entities.
     """
-    newvar = rqlst.make_variable()
-    if role == 'object':
-        rqlst.add_relation(newvar, rtype, mainvar)
-    else:
-        rqlst.add_relation(mainvar, rtype, newvar)
-    return newvar
+    newvar, newrel = _make_relation(rqlst, mainvar, rtype, role)
+    rqlst.add_restriction(newrel)
+    return newvar, newrel
+
+def _add_eid_restr(rel, restrvar, value):
+    rrel = nodes.make_constant_restriction(restrvar, 'eid', value, 'Int')
+    rel.parent.replace(rel, nodes.And(rel, rrel))
 
 def _prepare_vocabulary_rqlst(rqlst, mainvar, rtype, role,
                               select_target_entity=True):
@@ -187,7 +196,7 @@
     * add the new variable to GROUPBY clause if necessary
     * add the new variable to the selection
     """
-    newvar = _add_rtype_relation(rqlst, mainvar, rtype, role)
+    newvar = _add_rtype_relation(rqlst, mainvar, rtype, role)[0]
     if select_target_entity:
         if rqlst.groupby:
             rqlst.add_group_var(newvar)
@@ -240,7 +249,6 @@
     _cleanup_rqlst(rqlst, mainvar)
     var = _prepare_vocabulary_rqlst(rqlst, mainvar, rtype, role,
                                     select_target_entity)
-    # not found, create one
     attrvar = rqlst.make_variable()
     rqlst.add_relation(var, attrname, attrvar)
     # if query is grouped, we have to add the attribute variable
@@ -449,6 +457,10 @@
 
     The relation is defined by the `rtype` and `role` attributes.
 
+    The `no_relation` boolean flag tells if a special 'no relation' value should be
+    added (allowing to filter on entities which *do not* have the relation set).
+    Default is computed according the relation's cardinality.
+
     The values displayed for related entities will be:
 
     * result of calling their `label_vid` view if specified
@@ -456,7 +468,8 @@
     * else their eid (you usually want something nicer...)
 
     When no `label_vid` is set, you will get translated value if `i18nable` is
-    set.
+    set. By default, `i18nable` will be set according to the schema, but you can
+    force its value by setting it has a class attribute.
 
     You can filter out target entity types by specifying `target_type`
 
@@ -506,8 +519,6 @@
     role = 'subject'
     target_attr = 'eid'
     target_type = None
-    # should value be internationalized (XXX could be guessed from the schema)
-    i18nable = True
     # set this to a stored procedure name if you want to sort on the result of
     # this function's result instead of direct value
     sortfunc = None
@@ -520,6 +531,23 @@
     _select_target_entity = True
 
     title = property(rtype_facet_title)
+    no_relation_label = '<no relation>'
+
+    @property
+    def i18nable(self):
+        """should label be internationalized"""
+        if self.target_type:
+            eschema = self._cw.vreg.schema.eschema(self.target_type)
+        elif self.role == 'subject':
+            eschema = self._cw.vreg.schema.rschema(self.rtype).objects()[0]
+        else:
+            eschema = self._cw.vreg.schema.rschema(self.rtype).subjects()[0]
+        return eschema.rdef(self.target_attr).internationalizable
+
+    @property
+    def no_relation(self):
+        return (not self._cw.vreg.schema.rschema(self.rtype).final
+                and self._search_card('?*'))
 
     @property
     def rql_sort(self):
@@ -529,6 +557,7 @@
         """
         return self.sortfunc is not None or (self.label_vid is None
                                              and not self.i18nable)
+
     def vocabulary(self):
         """return vocabulary for this facet, eg a list of 2-uple (label, value)
         """
@@ -555,7 +584,10 @@
             rqlst.recover()
         # don't call rset_vocabulary on empty result set, it may be an empty
         # *list* (see rqlexec implementation)
-        return rset and self.rset_vocabulary(rset)
+        values = rset and self.rset_vocabulary(rset) or []
+        if self._include_no_relation():
+            values.insert(0, (self._cw._(self.no_relation_label), ''))
+        return values
 
     def possible_values(self):
         """return a list of possible values (as string since it's used to
@@ -572,12 +604,14 @@
                 insert_attr_select_relation(
                     rqlst, self.filtered_variable, self.rtype, self.role, self.target_attr,
                     select_target_entity=False)
-            return [str(x) for x, in self.rqlexec(rqlst.as_string())]
+            values = [str(x) for x, in self.rqlexec(rqlst.as_string())]
         except:
-            import traceback
-            traceback.print_exc()
+            self.exception('while computing values for %s', self)
         finally:
             rqlst.recover()
+        if self._include_no_relation():
+            values.append('')
+        return values
 
     def rset_vocabulary(self, rset):
         if self.i18nable:
@@ -585,56 +619,103 @@
         else:
             _ = unicode
         if self.rql_sort:
-            return [(_(label), eid) for eid, label in rset]
-        if self.label_vid is None:
-            assert self.i18nable
             values = [(_(label), eid) for eid, label in rset]
         else:
-            values = [(entity.view(self.label_vid), entity.eid)
-                      for entity in rset.entities()]
-        values = sorted(values)
-        if self.sortasc:
-            return values
-        return reversed(values)
+            if self.label_vid is None:
+                values = [(_(label), eid) for eid, label in rset]
+            else:
+                values = [(entity.view(self.label_vid), entity.eid)
+                          for entity in rset.entities()]
+            values = sorted(values)
+            if not self.sortasc:
+                values = list(reversed(values))
+        return values
+
+    def support_and(self):
+        return self._search_card('+*')
+
+    def add_rql_restrictions(self):
+        """add restriction for this facet into the rql syntax tree"""
+        value = self._cw.form.get(self.__regid__)
+        if value is None:
+            return
+        mainvar = self.filtered_variable
+        restrvar, rel = _add_rtype_relation(self.rqlst, mainvar, self.rtype,
+                                            self.role)
+        if isinstance(value, basestring):
+            # only one value selected
+            if value:
+                self.rqlst.add_eid_restriction(restrvar, value)
+            else:
+                rel.parent.replace(rel, nodes.Not(rel))
+        elif self.operator == 'OR':
+            # set_distinct only if rtype cardinality is > 1
+            if self.support_and():
+                self.rqlst.set_distinct(True)
+            # multiple ORed values: using IN is fine
+            if '' in value:
+                value.remove('')
+                self._add_not_rel_restr(rel)
+            _add_eid_restr(rel, restrvar, value)
+        else:
+            # multiple values with AND operator
+            if '' in value:
+                value.remove('')
+                self._add_not_rel_restr(rel)
+            _add_eid_restr(rel, restrvar, value.pop())
+            while value:
+                restrvar, rtrel = _make_relation(self.rqlst, mainvar,
+                                                 self.rtype, self.role)
+                _add_eid_restr(rel, restrvar, value.pop())
 
     @cached
-    def support_and(self):
+    def _search_card(self, cards):
+        for rdef in self._iter_rdefs():
+            if rdef.role_cardinality(self.role) in cards:
+                return True
+        return False
+
+    def _iter_rdefs(self):
         rschema = self._cw.vreg.schema.rschema(self.rtype)
         # XXX when called via ajax, no rset to compute possible types
         possibletypes = self.cw_rset and self.cw_rset.column_types(0)
         for rdef in rschema.rdefs.itervalues():
             if possibletypes is not None:
                 if self.role == 'subject':
-                    if not rdef.subject in possibletypes:
+                    if rdef.subject not in possibletypes:
                         continue
-                elif not rdef.object in possibletypes:
+                elif rdef.object not in possibletypes:
                     continue
-            if rdef.role_cardinality(self.role) in '+*':
-                return True
-        return False
+            if self.target_type is not None:
+                if self.role == 'subject':
+                    if rdef.object != self.target_type:
+                        continue
+                elif rdef.subject != self.target_type:
+                    continue
+            yield rdef
 
-    def add_rql_restrictions(self):
-        """add restriction for this facet into the rql syntax tree"""
-        value = self._cw.form.get(self.__regid__)
-        if not value:
-            return
-        mainvar = self.filtered_variable
-        restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype, self.role)
-        if isinstance(value, basestring):
-            # only one value selected
-            self.rqlst.add_eid_restriction(restrvar, value)
-        elif self.operator == 'OR':
-            # set_distinct only if rtype cardinality is > 1
-            if self.support_and():
-                self.rqlst.set_distinct(True)
-            # multiple ORed values: using IN is fine
-            self.rqlst.add_eid_restriction(restrvar, value)
+    def _include_no_relation(self):
+        if not self.no_relation:
+            return False
+        if self._cw.vreg.schema.rschema(self.rtype).final:
+            return False
+        if self.role == 'object':
+            subj = utils.rqlvar_maker(defined=self.rqlst.defined_vars,
+                                      aliases=self.rqlst.aliases).next()
+            obj = self.filtered_variable.name
         else:
-            # multiple values with AND operator
-            self.rqlst.add_eid_restriction(restrvar, value.pop())
-            while value:
-                restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype, self.role)
-                self.rqlst.add_eid_restriction(restrvar, value.pop())
+            subj = self.filtered_variable.name
+            obj = utils.rqlvar_maker(defined=self.rqlst.defined_vars,
+                                     aliases=self.rqlst.aliases).next()
+        rql = 'Any %s LIMIT 1 WHERE NOT %s %s %s, %s' % (
+            self.filtered_variable.name, subj, self.rtype, obj,
+            self.rqlst.where.as_string())
+        return bool(self.rqlexec(rql, self.cw_rset and self.cw_rset.args))
+
+    def _add_not_rel_restr(self, rel):
+        nrrel = nodes.Not(_make_relation(self.rqlst, self.filtered_variable,
+                                         self.rtype, self.role)[1])
+        rel.parent.replace(rel, nodes.Or(nrrel, rel))
 
 
 class RelationAttributeFacet(RelationFacet):
@@ -699,20 +780,25 @@
         if not value:
             return
         mainvar = self.filtered_variable
-        restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype, self.role)
+        restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype,
+                                       self.role)[0]
         self.rqlst.set_distinct(True)
         if isinstance(value, basestring) or self.operator == 'OR':
             # only one value selected or multiple ORed values: using IN is fine
-            self.rqlst.add_constant_restriction(restrvar, self.target_attr, value,
-                                                self.attrtype, self.comparator)
+            self.rqlst.add_constant_restriction(
+                restrvar, self.target_attr, value,
+                self.attrtype, self.comparator)
         else:
             # multiple values with AND operator
-            self.rqlst.add_constant_restriction(restrvar, self.target_attr, value.pop(),
-                                                self.attrtype, self.comparator)
+            self.rqlst.add_constant_restriction(
+                restrvar, self.target_attr, value.pop(),
+                self.attrtype, self.comparator)
             while value:
-                restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype, self.role)
-                self.rqlst.add_constant_restriction(restrvar, self.target_attr, value.pop(),
-                                                    self.attrtype, self.comparator)
+                restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype,
+                                               self.role)[0]
+                self.rqlst.add_constant_restriction(
+                    restrvar, self.target_attr, value.pop(),
+                    self.attrtype, self.comparator)
 
 
 class AttributeFacet(RelationAttributeFacet):
@@ -749,6 +835,16 @@
 
     _select_target_entity = True
 
+    @property
+    def i18nable(self):
+        """should label be internationalized"""
+        for rdef in self._iter_rdefs():
+            # no 'internationalizable' property for rdef whose object is not a
+            # String
+            if not getattr(rdef, 'internationalizable', False):
+                return False
+        return True
+
     def vocabulary(self):
         """return vocabulary for this facet, eg a list of 2-uple (label, value)
         """
--- a/web/formfields.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/formfields.py	Wed Oct 13 08:37:21 2010 +0200
@@ -73,6 +73,7 @@
                               FormatConstraint)
 
 from cubicweb import Binary, tags, uilib
+from cubicweb.utils import support_args
 from cubicweb.web import INTERNAL_FIELD_VALUE, ProcessFormError, eid_param, \
      formwidgets as fw, uicfg
 
@@ -332,7 +333,7 @@
         if self.eidparam and self.role is not None:
             entity = form.edited_entity
             if form._cw.vreg.schema.rschema(self.name).final:
-                if entity.has_eid() or self.name in entity:
+                if entity.has_eid() or self.name in entity.cw_attr_cache:
                     value = getattr(entity, self.name)
                     if value is not None or not self.fallback_on_none_attribute:
                         return value
@@ -345,7 +346,12 @@
     def initial_typed_value(self, form, load_bytes):
         if self.value is not _MARKER:
             if callable(self.value):
-                return self.value(form)
+                if support_args(self.value, 'form', 'field'):
+                    return self.value(form, self)
+                else:
+                    warn("[3.10] field's value callback must now take form and field as argument",
+                         DeprecationWarning)
+                    return self.value(form)
             return self.value
         formattr = '%s_%s_default' % (self.role, self.name)
         if hasattr(form, formattr):
@@ -427,7 +433,7 @@
         if self.eidparam and self.role == 'subject':
             entity = form.edited_entity
             if entity.e_schema.has_metadata(self.name, 'format') and (
-                entity.has_eid() or '%s_format' % self.name in entity):
+                entity.has_eid() or '%s_format' % self.name in entity.cw_attr_cache):
                 return form.edited_entity.cw_attr_metadata(self.name, 'format')
         return form._cw.property_value('ui.default-text-format')
 
--- a/web/formwidgets.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/formwidgets.py	Wed Oct 13 08:37:21 2010 +0200
@@ -93,6 +93,7 @@
 from logilab.common.date import todatetime
 
 from cubicweb import tags, uilib
+from cubicweb.utils import json_dumps
 from cubicweb.web import stdmsgs, INTERNAL_FIELD_VALUE, ProcessFormError
 
 
@@ -698,12 +699,13 @@
     controller. This method is expected to return allowed values for the input,
     that the widget will use to propose matching values as you type.
     """
-    needs_js = ('cubicweb.widgets.js', 'jquery.autocomplete.js')
-    needs_css = ('jquery.autocomplete.css',)
-    wdgtype = 'SuggestField'
-    loadtype = 'auto'
+    needs_js = ('cubicweb.widgets.js', 'jquery.ui.js')
+    needs_css = ('jquery.ui.css',)
+    default_settings = {}
 
     def __init__(self, *args, **kwargs):
+        self.autocomplete_settings = kwargs.pop('autocomplete_settings',
+                                                self.default_settings)
         try:
             self.autocomplete_initfunc = kwargs.pop('autocomplete_initfunc')
         except KeyError:
@@ -720,12 +722,17 @@
             values = ('',)
         return values
 
-    def attributes(self, form, field):
-        attrs = super(AutoCompletionWidget, self).attributes(form, field)
-        init_ajax_attributes(attrs, self.wdgtype, self.loadtype)
-        # XXX entity form specific
-        attrs['cubicweb:dataurl'] = self._get_url(form.edited_entity, field)
-        return attrs
+    def _render(self, form, field, renderer):
+        entity = form.edited_entity
+        domid = field.dom_id(form).replace(':', r'\\:')
+        if callable(self.autocomplete_initfunc):
+            data = self.autocomplete_initfunc(form, field)
+        else:
+            data = xml_escape(self._get_url(entity, field))
+        form._cw.add_onload(u'$("#%s").cwautocomplete(%s, %s);'
+                            % (domid, json_dumps(data),
+                               json_dumps(self.autocomplete_settings)))
+        return super(AutoCompletionWidget, self)._render(form, field, renderer)
 
     def _get_url(self, entity, field):
         if self.autocomplete_initfunc is None:
@@ -737,6 +744,7 @@
                                     pageid=entity._cw.pageid)
 
 
+
 class StaticFileAutoCompletionWidget(AutoCompletionWidget):
     """XXX describe me"""
     wdgtype = 'StaticFileSuggestField'
@@ -752,12 +760,11 @@
 
 class RestrictedAutoCompletionWidget(AutoCompletionWidget):
     """XXX describe me"""
-    wdgtype = 'RestrictedSuggestField'
+    default_settings = {'mustMatch': True}
 
 
 class LazyRestrictedAutoCompletionWidget(RestrictedAutoCompletionWidget):
     """remote autocomplete """
-    wdgtype = 'LazySuggestField'
 
     def values_and_attributes(self, form, field):
         """override values_and_attributes to handle initial displayed values"""
--- a/web/htmlwidgets.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/htmlwidgets.py	Wed Oct 13 08:37:21 2010 +0200
@@ -19,11 +19,10 @@
 
 those are in cubicweb since we need to know available widgets at schema
 serialization time
-
 """
 
+import random
 from math import floor
-import random
 
 from logilab.mtconverter import xml_escape
 
@@ -182,7 +181,10 @@
             toggle_action(ident), self.link_class, self.label))
         self._begin_menu(ident)
         for item in self.items:
-            item.render(self.w)
+            if hasattr(item, 'render'):
+                item.render(self.w)
+            else:
+                self.w(u'<li>%s</li>' % item)
         self._end_menu()
         if self.isitem:
             self.w(u'</li>')
--- a/web/test/unittest_breadcrumbs.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/unittest_breadcrumbs.py	Wed Oct 13 08:37:21 2010 +0200
@@ -31,8 +31,10 @@
         self.assertEqual(f2.view('breadcrumbs'),
                           '<a href="http://testing.fr/cubicweb/folder/%s" title="">chi&amp;ld</a>' % f2.eid)
         childrset = f2.as_rset()
-        ibc = self.vreg['components'].select('breadcrumbs', self.request(), rset=childrset)
-        self.assertEqual(ibc.render(),
+        ibc = self.vreg['ctxcomponents'].select('breadcrumbs', self.request(), rset=childrset)
+        l = []
+        ibc.render(l.append)
+        self.assertEqual(''.join(l),
                           """<span id="breadcrumbs" class="pathbar">&#160;&gt;&#160;<a href="http://testing.fr/cubicweb/Folder">folder_plural</a>&#160;&gt;&#160;<a href="http://testing.fr/cubicweb/folder/%s" title="">par&amp;ent</a>&#160;&gt;&#160;
 <a href="http://testing.fr/cubicweb/folder/%s" title="">chi&amp;ld</a></span>""" % (f1.eid, f2.eid))
 
--- a/web/test/unittest_facet.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/unittest_facet.py	Wed Oct 13 08:37:21 2010 +0200
@@ -14,26 +14,33 @@
         self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
         return req, rset, rqlst, mainvar
 
-    def test_relation_simple(self):
+    def _in_group_facet(self, cls=facet.RelationFacet, no_relation=False):
         req, rset, rqlst, mainvar = self.prepare_rqlst()
-        f = facet.RelationFacet(req, rset=rset,
-                                rqlst=rqlst.children[0],
-                                filtered_variable=mainvar)
+        cls.no_relation = no_relation
+        f = cls(req, rset=rset, rqlst=rqlst.children[0],
+                filtered_variable=mainvar)
+        f.__regid__ = 'in_group'
         f.rtype = 'in_group'
         f.role = 'subject'
         f.target_attr = 'name'
         guests, managers = [eid for eid, in self.execute('CWGroup G ORDERBY GN '
                                                          'WHERE G name GN, G name IN ("guests", "managers")')]
+        groups = [eid for eid, in self.execute('CWGroup G ORDERBY GN '
+                                               'WHERE G name GN, G name IN ("guests", "managers")')]
+        return f, groups
+
+    def test_relation_simple(self):
+        f, (guests, managers) = self._in_group_facet()
         self.assertEqual(f.vocabulary(),
-                          [(u'guests', guests), (u'managers', managers)])
+                      [(u'guests', guests), (u'managers', managers)])
         # ensure rqlst is left unmodified
-        self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
+        self.assertEqual(f.rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
         #rqlst = rset.syntax_tree()
         self.assertEqual(f.possible_values(),
                           [str(guests), str(managers)])
         # ensure rqlst is left unmodified
-        self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
-        req.form[f.__regid__] = str(guests)
+        self.assertEqual(f.rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
+        f._cw.form[f.__regid__] = str(guests)
         f.add_rql_restrictions()
         # selection is cluttered because rqlst has been prepared for facet (it
         # is not in real life)
@@ -72,25 +79,47 @@
         self.assertEqual(f.rqlst.as_string(),
                           'DISTINCT Any  GROUPBY X WHERE X in_group G?, G name GN, NOT G name "users", X in_group D, D eid %s' % guests)
 
+    def test_relation_no_relation_1(self):
+        f, (guests, managers) = self._in_group_facet(no_relation=True)
+        self.assertEqual(f.vocabulary(),
+                          [(u'guests', guests), (u'managers', managers)])
+        self.assertEqual(f.possible_values(),
+                          [str(guests), str(managers)])
+        f._cw.create_entity('CWUser', login=u'hop', upassword='toto')
+        self.assertEqual(f.vocabulary(),
+                          [(u'<no relation>', ''), (u'guests', guests), (u'managers', managers)])
+        self.assertEqual(f.possible_values(),
+                          [str(guests), str(managers), ''])
+        f._cw.form[f.__regid__] = ''
+        f.add_rql_restrictions()
+        self.assertEqual(f.rqlst.as_string(),
+                          'DISTINCT Any  WHERE X is CWUser, NOT X in_group G')
+
+    def test_relation_no_relation_2(self):
+        f, (guests, managers) = self._in_group_facet(no_relation=True)
+        f._cw.form[f.__regid__] = ['', guests]
+        f.rqlst.save_state()
+        f.add_rql_restrictions()
+        self.assertEqual(f.rqlst.as_string(),
+                          'DISTINCT Any  WHERE X is CWUser, (NOT X in_group B) OR (X in_group A, A eid %s)' % guests)
+        f.rqlst.recover()
+        self.assertEqual(f.rqlst.as_string(),
+                          'DISTINCT Any  WHERE X is CWUser')
+
+
 
     def test_relationattribute(self):
-        req, rset, rqlst, mainvar = self.prepare_rqlst()
-        f = facet.RelationAttributeFacet(req, rset=rset,
-                                         rqlst=rqlst.children[0],
-                                         filtered_variable=mainvar)
-        f.rtype = 'in_group'
-        f.role = 'subject'
-        f.target_attr = 'name'
+        f, (guests, managers) = self._in_group_facet(cls=facet.RelationAttributeFacet)
         self.assertEqual(f.vocabulary(),
                           [(u'guests', u'guests'), (u'managers', u'managers')])
         # ensure rqlst is left unmodified
-        self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
+        self.assertEqual(f.rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
         #rqlst = rset.syntax_tree()
         self.assertEqual(f.possible_values(),
                           ['guests', 'managers'])
         # ensure rqlst is left unmodified
-        self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
-        req.form[f.__regid__] = 'guests'
+        self.assertEqual(f.rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
+        f._cw.form[f.__regid__] = 'guests'
         f.add_rql_restrictions()
         # selection is cluttered because rqlst has been prepared for facet (it
         # is not in real life)
--- a/web/test/unittest_session.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/unittest_session.py	Wed Oct 13 08:37:21 2010 +0200
@@ -7,10 +7,11 @@
 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
 from cubicweb.devtools.testlib import CubicWebTC
+from cubicweb.web import InvalidSession
 
 class SessionTC(CubicWebTC):
 
-    def test_auto_reconnection(self):
+    def test_session_expiration(self):
         sm = self.app.session_handler.session_manager
         # make is if the web session has been opened by the session manager
         sm._sessions[self.cnx.sessionid] = self.websession
@@ -23,11 +24,8 @@
             # fake an incoming http query with sessionid in session cookie
             # don't use self.request() which try to call req.set_session
             req = self.requestcls(self.vreg)
-            websession = sm.get_session(req, sessionid)
-            self.assertEqual(len(sm._sessions), 1)
-            self.assertIs(websession, self.websession)
-            self.assertEqual(websession.sessionid, sessionid)
-            self.assertNotEquals(websession.sessionid, websession.cnx.sessionid)
+            self.assertRaises(InvalidSession, sm.get_session, req, sessionid)
+            self.assertEqual(len(sm._sessions), 0)
         finally:
             # avoid error in tearDown by telling this connection is closed...
             self.cnx._closed = True
--- a/web/test/unittest_urlpublisher.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/unittest_urlpublisher.py	Wed Oct 13 08:37:21 2010 +0200
@@ -77,7 +77,7 @@
         self.assertEqual(ctrl, 'view')
         self.assertEqual(len(rset), 1)
         self.assertEqual(rset.description[0][0], 'CWUser')
-        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X eid 5, X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
+        self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X eid %s, X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD' % rset[0][0])
         # test non-ascii paths
         ctrl, rset = self.process('CWUser/login/%C3%BFsa%C3%BFe')
         self.assertEqual(ctrl, 'view')
--- a/web/test/unittest_views_editforms.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/unittest_views_editforms.py	Wed Oct 13 08:37:21 2010 +0200
@@ -64,10 +64,10 @@
                                ])
         self.assertListEqual(rbc(e, 'main', 'metadata'),
                               [('last_login_time', 'subject'),
+                               ('creation_date', 'subject'),
+                               ('cwuri', 'subject'),
                                ('modification_date', 'subject'),
                                ('created_by', 'subject'),
-                               ('creation_date', 'subject'),
-                               ('cwuri', 'subject'),
                                ('owned_by', 'subject'),
                                ('bookmarked_by', 'object'),
                                ])
@@ -77,8 +77,8 @@
         self.assertListEqual([x for x in rbc(e, 'main', 'relations')
                                if x != ('tags', 'object')],
                               [('primary_email', 'subject'),
+                               ('connait', 'subject'),
                                ('custom_workflow', 'subject'),
-                               ('connait', 'subject'),
                                ('checked_by', 'object'),
                                ])
         self.assertListEqual(rbc(e, 'main', 'inlined'),
--- a/web/test/unittest_views_navigation.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/unittest_views_navigation.py	Wed Oct 13 08:37:21 2010 +0200
@@ -122,26 +122,26 @@
     #     view = mock_object(is_primary=lambda x: True)
     #     rset = self.execute('CWUser X LIMIT 1')
     #     req = self.request()
-    #     objs = self.vreg['contentnavigation'].poss_visible_objects(
+    #     objs = self.vreg['ctxcomponents'].poss_visible_objects(
     #         req, rset=rset, view=view, context='navtop')
     #     # breadcrumbs should be in headers by default
     #     clsids = set(obj.id for obj in objs)
     #     self.failUnless('breadcrumbs' in clsids)
-    #     objs = self.vreg['contentnavigation'].poss_visible_objects(
+    #     objs = self.vreg['ctxcomponents'].poss_visible_objects(
     #         req, rset=rset, view=view, context='navbottom')
     #     # breadcrumbs should _NOT_ be in footers by default
     #     clsids = set(obj.id for obj in objs)
     #     self.failIf('breadcrumbs' in clsids)
-    #     self.execute('INSERT CWProperty P: P pkey "contentnavigation.breadcrumbs.context", '
+    #     self.execute('INSERT CWProperty P: P pkey "ctxcomponents.breadcrumbs.context", '
     #                  'P value "navbottom"')
     #     # breadcrumbs should now be in footers
     #     req.cnx.commit()
-    #     objs = self.vreg['contentnavigation'].poss_visible_objects(
+    #     objs = self.vreg['ctxcomponents'].poss_visible_objects(
     #         req, rset=rset, view=view, context='navbottom')
 
     #     clsids = [obj.id for obj in objs]
     #     self.failUnless('breadcrumbs' in clsids)
-    #     objs = self.vreg['contentnavigation'].poss_visible_objects(
+    #     objs = self.vreg['ctxcomponents'].poss_visible_objects(
     #         req, rset=rset, view=view, context='navtop')
 
     #     clsids = [obj.id for obj in objs]
--- a/web/test/unittest_viewselector.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/unittest_viewselector.py	Wed Oct 13 08:37:21 2010 +0200
@@ -468,19 +468,18 @@
 
     def test_properties(self):
         self.assertEqual(sorted(k for k in self.vreg['propertydefs'].keys()
-                                 if k.startswith('boxes.edit_box')),
-                          ['boxes.edit_box.context',
-                           'boxes.edit_box.order',
-                           'boxes.edit_box.visible'])
+                                 if k.startswith('ctxcomponents.edit_box')),
+                          ['ctxcomponents.edit_box.context',
+                           'ctxcomponents.edit_box.order',
+                           'ctxcomponents.edit_box.visible'])
         self.assertEqual([k for k in self.vreg['propertyvalues'].keys()
                            if not k.startswith('system.version')],
                           [])
-        self.assertEqual(self.vreg.property_value('boxes.edit_box.visible'), True)
-        self.assertEqual(self.vreg.property_value('boxes.edit_box.order'), 2)
-        self.assertEqual(self.vreg.property_value('boxes.possible_views_box.visible'), False)
-        self.assertEqual(self.vreg.property_value('boxes.possible_views_box.order'), 10)
-        self.assertRaises(UnknownProperty, self.vreg.property_value, 'boxes.actions_box')
-
+        self.assertEqual(self.vreg.property_value('ctxcomponents.edit_box.visible'), True)
+        self.assertEqual(self.vreg.property_value('ctxcomponents.edit_box.order'), 2)
+        self.assertEqual(self.vreg.property_value('ctxcomponents.possible_views_box.visible'), False)
+        self.assertEqual(self.vreg.property_value('ctxcomponents.possible_views_box.order'), 10)
+        self.assertRaises(UnknownProperty, self.vreg.property_value, 'ctxcomponents.actions_box')
 
 
 
--- a/web/test/windmill/test_creation.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/windmill/test_creation.py	Wed Oct 13 08:37:21 2010 +0200
@@ -26,7 +26,7 @@
     client.type(text=u'myuser', id=u'upassword-subject:A')
     client.type(text=u'myuser', name=u'upassword-subject-confirm:A')
     client.type(text=u'myuser', id=u'firstname-subject:A')
-    client.select(val=u'4', id=u'in_group-subject:A')
+    client.select(option=u'managers', id=u'in_group-subject:A')
     client.waits.forPageLoad(timeout=u'20000')
     client.click(id=u'adduse_email:Alink')
     client.waits.forPageLoad(timeout=u'20000')
--- a/web/test/windmill/test_edit_relation.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/test/windmill/test_edit_relation.py	Wed Oct 13 08:37:21 2010 +0200
@@ -22,8 +22,8 @@
     client.type(text=u'folder1', id=u'name-subject:A')
     client.click(value=u'button_ok')
     client.waits.forPageLoad(timeout=u'20000')
-    client.waits.forElement(link=u'add add Folder filed_under Folder object', timeout=u'8000')
-    client.click(link=u'add add Folder filed_under Folder object')
+    client.waits.forElement(link=u'add Folder filed_under Folder object', timeout=u'8000')
+    client.click(link=u'add Folder filed_under Folder object')
     client.waits.forPageLoad(timeout=u'20000')
     client.waits.forElement(timeout=u'8000', id=u'name-subject:A')
     client.click(id=u'name-subject:A')
@@ -44,8 +44,8 @@
     client.click(link=u'x')
     client.click(value=u'button_ok')
     client.waits.forPageLoad(timeout=u'20000')
-    client.waits.forElement(link=u'add add Folder filed_under Folder object', timeout=u'8000')
-    client.click(link=u'add add Folder filed_under Folder object')
+    client.waits.forElement(link=u'add Folder filed_under Folder object', timeout=u'8000')
+    client.click(link=u'add Folder filed_under Folder object')
     client.waits.forPageLoad(timeout=u'20000')
     client.type(text=u'subfolder2', id=u'name-subject:A')
     client.click(value=u'button_ok')
--- a/web/views/__init__.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/__init__.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,9 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Views, forms, actions... for the CubicWeb web client
+"""Views, forms, actions... for the CubicWeb web client"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 import os
--- a/web/views/actions.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/actions.py	Wed Oct 13 08:37:21 2010 +0200
@@ -407,7 +407,7 @@
 
     category = 'footer'
     order = 3
-    title = _('powered by CubicWeb')
+    title = _('Powered by CubicWeb')
 
     def url(self):
         return 'http://www.cubicweb.org'
--- a/web/views/ajaxedit.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/ajaxedit.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,21 +15,19 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Set of views allowing edition of entities/relations using ajax
+"""Set of views allowing edition of entities/relations using ajax"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from cubicweb import role
+from cubicweb.view import View
 from cubicweb.selectors import match_form_params, match_kwargs
-from cubicweb.web.box import EditRelationBoxTemplate
+from cubicweb.web.component import EditRelationMixIn
 
-class AddRelationView(EditRelationBoxTemplate):
-    """base class for view which let add entities linked
-    by a given relation
+class AddRelationView(EditRelationMixIn, View):
+    """base class for view which let add entities linked by a given relation
 
-    subclasses should define at least id, rtype and target
-    class attributes.
+    subclasses should define at least id, rtype and target class attributes.
     """
     __registry__ = 'views'
     __regid__ = 'xaddrelation'
@@ -38,7 +36,7 @@
     cw_property_defs = {} # don't want to inherit this from Box
     expected_kwargs = form_params = ('rtype', 'target')
 
-    build_js = EditRelationBoxTemplate.build_reload_js_call
+    build_js = EditRelationMixIn.build_reload_js_call
 
     def cell_call(self, row, col, rtype=None, target=None, etype=None):
         self.rtype = rtype or self._cw.form['rtype']
@@ -53,13 +51,13 @@
                 etypes = rschema.subjects(entity.e_schema)
             if len(etypes) == 1:
                 self.etype = etypes[0]
-        self.w(u'<div id="%s">' % self.__regid__)
+        self.w(u'<div id="%s">' % self.domid)
         self.w(u'<h1>%s</h1>' % self._cw._('relation %(relname)s of %(ent)s')
                % {'relname': rschema.display_name(self._cw, role(self)),
                   'ent': entity.view('incontext')})
         self.w(u'<ul>')
         for boxitem in self.unrelated_boxitems(entity):
-            boxitem.render(self.w)
+            self.w('<li class="invisible">%s</li>' % botitem)
         self.w(u'</ul></div>')
 
     def unrelated_entities(self, entity):
@@ -74,11 +72,4 @@
                                     ordermethod='fetch_order')
             self.pagination(self._cw, rset, w=self.w)
             return rset.entities()
-        # in other cases, use vocabulary functions
-        entities = []
-        # XXX to update for 3.2
-        for _, eid in entity.vocabulary(self.rtype, role(self)):
-            if eid is not None:
-                rset = self._cw.eid_rset(eid)
-                entities.append(rset.get_entity(0, 0))
-        return entities
+        super(AddRelationView, self).unrelated_entities(self)
--- a/web/views/authentication.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/authentication.py	Wed Oct 13 08:37:21 2010 +0200
@@ -37,6 +37,7 @@
 class WebAuthInfoRetreiver(Component):
     __registry__ = 'webauth'
     order = None
+    __abstract__ = True
 
     def authentication_information(self, req):
         """retreive authentication information from the given request, raise
@@ -51,6 +52,18 @@
         """
         pass
 
+    def request_has_auth_info(self, req):
+        """tells from the request if it has enough information
+        to proceed to authentication, would the current session
+        be invalidated
+        """
+        raise NotImplementedError()
+
+    def revalidate_login(self, req):
+        """returns a login string or None, for repository session validation
+        purposes
+        """
+        raise NotImplementedError()
 
 class LoginPasswordRetreiver(WebAuthInfoRetreiver):
     __regid__ = 'loginpwdauth'
@@ -65,6 +78,11 @@
             raise NoAuthInfo()
         return login, {'password': password}
 
+    def request_has_auth_info(self, req):
+        return req.get_authorization()[0] is not None
+
+    def revalidate_login(self, req):
+        return req.get_authorization()[0]
 
 class RepositoryAuthenticationManager(AbstractAuthenticationManager):
     """authenticate user associated to a request and check session validity"""
@@ -73,8 +91,8 @@
         super(RepositoryAuthenticationManager, self).__init__(vreg)
         self.repo = vreg.config.repository(vreg)
         self.log_queries = vreg.config['query-log-file']
-        self.authinforetreivers = sorted(vreg['webauth'].possible_objects(vreg),
-                                    key=lambda x: x.order)
+        self.authinforetrievers = sorted(vreg['webauth'].possible_objects(vreg),
+                                         key=lambda x: x.order)
         # 2-uple login / password, login is None when no anonymous access
         # configured
         self.anoninfo = vreg.config.anonymous_user()
@@ -88,35 +106,30 @@
 
         raise :exc:`InvalidSession` if session is corrupted for a reason or
         another and should be closed
+
+        also invoked while going from anonymous to logged in
         """
         # with this authentication manager, session is actually a dbapi
         # connection
-        login = req.get_authorization()[0]
+        for retriever in self.authinforetrievers:
+            if retriever.request_has_auth_info(req):
+                login = retriever.revalidate_login(req)
+                return self._validate_session(req, session, login)
+        # let's try with the current session
+        return self._validate_session(req, session, None)
+
+    def _validate_session(self, req, session, login):
         # check session.login and not user.login, since in case of login by
         # email, login and cnx.login are the email while user.login is the
         # actual user login
         if login and session.login != login:
             raise InvalidSession('login mismatch')
         try:
-            lock = session.reconnection_lock
-        except AttributeError:
-            lock = session.reconnection_lock = Lock()
-        # need to be locked two avoid duplicated reconnections on concurrent
-        # requests
-        with lock:
-            cnx = session.cnx
-            try:
-                # calling cnx.user() check connection validity, raise
-                # BadConnectionId on failure
-                user = cnx.user(req)
-            except BadConnectionId:
-                # check if a connection should be automatically restablished
-                if (login is None or login == session.login):
-                    cnx = self._authenticate(session.login, session.authinfo)
-                    user = cnx.user(req)
-                    session.cnx = cnx
-                else:
-                    raise InvalidSession('bad connection id')
+            # calling cnx.user() check connection validity, raise
+            # BadConnectionId on failure
+            user = session.cnx.user(req)
+        except BadConnectionId:
+            raise InvalidSession('bad connection id')
         return user
 
     def authenticate(self, req):
@@ -128,18 +141,19 @@
         raise :exc:`cubicweb.AuthenticationError` if authentication failed
         (no authentication info found or wrong user/password)
         """
-        for retreiver in self.authinforetreivers:
+        for retriever in self.authinforetrievers:
             try:
-                login, authinfo = retreiver.authentication_information(req)
+                login, authinfo = retriever.authentication_information(req)
             except NoAuthInfo:
                 continue
             try:
                 cnx = self._authenticate(login, authinfo)
             except AuthenticationError:
                 continue # the next one may succeed
-            for retreiver_ in self.authinforetreivers:
-                retreiver_.authenticated(retreiver, req, cnx, login, authinfo)
+            for retriever_ in self.authinforetrievers:
+                retriever_.authenticated(retriever, req, cnx, login, authinfo)
             return cnx, login, authinfo
+
         # false if no authentication info found, eg this is not an
         # authentication failure
         if 'login' in locals():
--- a/web/views/autoform.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/autoform.py	Wed Oct 13 08:37:21 2010 +0200
@@ -826,40 +826,30 @@
                              'dunno what to do', rschema)
                 continue
             ttype = ttypes[0].type
-            if self.should_inline_relation_form(rschema, ttype, role):
-                formviews = list(self.inline_edition_form_view(rschema, ttype, role))
-                card = rschema.role_rdef(entity.e_schema, ttype, role).role_cardinality(role)
-                # there is no related entity and we need at least one: we need to
-                # display one explicit inline-creation view
-                if self.should_display_inline_creation_form(rschema, formviews, card):
-                    formviews += self.inline_creation_form_view(rschema, ttype, role)
-                # we can create more than one related entity, we thus display a link
-                # to add new related entities
-                if self.should_display_add_new_relation_link(rschema, formviews, card):
-                    addnewlink = self._cw.vreg['views'].select(
-                        'inline-addnew-link', self._cw,
-                        etype=ttype, rtype=rschema, role=role, card=card,
-                        peid=self.edited_entity.eid,
-                        petype=self.edited_entity.e_schema, pform=self)
-                    formviews.append(addnewlink)
-                allformviews += formviews
+            formviews = list(self.inline_edition_form_view(rschema, ttype, role))
+            card = rschema.role_rdef(entity.e_schema, ttype, role).role_cardinality(role)
+            # there is no related entity and we need at least one: we need to
+            # display one explicit inline-creation view
+            if self.should_display_inline_creation_form(rschema, formviews, card):
+                formviews += self.inline_creation_form_view(rschema, ttype, role)
+            # we can create more than one related entity, we thus display a link
+            # to add new related entities
+            if self.should_display_add_new_relation_link(rschema, formviews, card):
+                addnewlink = self._cw.vreg['views'].select(
+                    'inline-addnew-link', self._cw,
+                    etype=ttype, rtype=rschema, role=role, card=card,
+                    peid=self.edited_entity.eid,
+                    petype=self.edited_entity.e_schema, pform=self)
+                formviews.append(addnewlink)
+            allformviews += formviews
         return allformviews
 
-    def should_inline_relation_form(self, rschema, targettype, role):
-        """return true if the given relation with entity has role and a
-        targettype target should be inlined
-
-        At this point we now relation has inlined_attributes tag (eg is returned
-        by `inlined_relations()`. Overrides this for more finer control.
-        """
-        return True
-
     def should_display_inline_creation_form(self, rschema, existant, card):
         """return true if a creation form should be inlined
 
         by default true if there is no related entity and we need at least one
         """
-        return not existant and card in '1+' or self._cw.form.has_key('force_%s_display' % rschema)
+        return not existant and card in '1+'
 
     def should_display_add_new_relation_link(self, rschema, existant, card):
         """return true if we should add a link to add a new creation form
@@ -911,13 +901,12 @@
 _AFS.tag_attribute(('*', 'eid'), 'main', 'attributes')
 _AFS.tag_attribute(('*', 'eid'), 'muledit', 'attributes')
 _AFS.tag_attribute(('*', 'description'), 'main', 'attributes')
-_AFS.tag_attribute(('*', 'creation_date'), 'main', 'metadata')
-_AFS.tag_attribute(('*', 'modification_date'), 'main', 'metadata')
-_AFS.tag_attribute(('*', 'cwuri'), 'main', 'metadata')
 _AFS.tag_attribute(('*', 'has_text'), 'main', 'hidden')
 _AFS.tag_subject_of(('*', 'in_state', '*'), 'main', 'hidden')
-_AFS.tag_subject_of(('*', 'owned_by', '*'), 'main', 'metadata')
-_AFS.tag_subject_of(('*', 'created_by', '*'), 'main', 'metadata')
+for rtype in ('creation_date', 'modification_date', 'cwuri',
+              'owned_by', 'created_by', 'cw_source'):
+    _AFS.tag_subject_of(('*', rtype, '*'), 'main', 'metadata')
+
 _AFS.tag_subject_of(('*', 'require_permission', '*'), 'main', 'hidden')
 _AFS.tag_subject_of(('*', 'by_transition', '*'), 'main', 'attributes')
 _AFS.tag_subject_of(('*', 'by_transition', '*'), 'muledit', 'attributes')
--- a/web/views/basecomponents.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/basecomponents.py	Wed Oct 13 08:37:21 2010 +0200
@@ -20,16 +20,20 @@
 * the rql input form
 * the logged user link
 """
+from __future__ import with_statement
 
 __docformat__ = "restructuredtext en"
 _ = unicode
 
 from logilab.mtconverter import xml_escape
+from logilab.common.deprecation import class_renamed
 from rql import parse
 
 from cubicweb.selectors import (yes, multi_etypes_rset, match_form_params,
+                                match_context, configuration_values,
                                 anonymous_user, authenticated_user)
 from cubicweb.schema import display_name
+from cubicweb.utils import wrap_on_write
 from cubicweb.uilib import toggle_action
 from cubicweb.web import component
 from cubicweb.web.htmlwidgets import (MenuWidget, PopupBoxMenu, BoxSeparator,
@@ -68,55 +72,96 @@
         self.w(u'</form></div>')
 
 
-class ApplLogo(component.Component):
-    """build the instance logo, usually displayed in the header"""
-    __regid__ = 'logo'
-    cw_property_defs = VISIBLE_PROP_DEF
-    # don't want user to hide this component using an cwproperty
-    site_wide = True
 
-    def call(self):
-        self.w(u'<a href="%s"><img id="logo" src="%s" alt="logo"/></a>'
-               % (self._cw.base_url(), self._cw.uiprops['LOGO']))
-
-
-class ApplHelp(component.Component):
-    """build the help button, usually displayed in the header"""
-    __regid__ = 'help'
-    cw_property_defs = VISIBLE_PROP_DEF
-    def call(self):
-        self.w(u'<a href="%s" class="help" title="%s">&#160;</a>'
-               % (self._cw.build_url(_restpath='doc/main'),
-                  self._cw._(u'help'),))
-
-
-class _UserLink(component.Component):
+class HeaderComponent(component.CtxComponent): # XXX rename properly along with related context
     """if the user is the anonymous user, build a link to login else display a menu
     with user'action (preference, logout, etc...)
     """
-    cw_property_defs = VISIBLE_PROP_DEF
+    __abstract__ = True
+    cw_property_defs = component.override_ctx(
+        component.CtxComponent,
+        vocabulary=['header-left', 'header-center', 'header-right'])
     # don't want user to hide this component using an cwproperty
     site_wide = True
-    __regid__ = 'loggeduserlink'
+    context = _('header-center')
+
+
+class ApplLogo(HeaderComponent):
+    """build the instance logo, usually displayed in the header"""
+    __regid__ = 'logo'
+    order = -1
+
+    def render(self, w):
+        w(u'<a href="%s"><img id="logo" src="%s" alt="logo"/></a>'
+          % (self._cw.base_url(), self._cw.uiprops['LOGO']))
+
+
+class ApplicationName(HeaderComponent):
+    """display the instance name"""
+    __regid__ = 'appliname'
+    context = _('header-center')
+
+    def render(self, w):
+        title = self._cw.property_value('ui.site-title')
+        if title:
+            w(u'<span id="appliName"><a href="%s">%s</a></span>' % (
+                self._cw.base_url(), xml_escape(title)))
 
 
-class AnonUserLink(_UserLink):
-    __select__ = _UserLink.__select__ & anonymous_user()
+class CookieLoginComponent(HeaderComponent):
+    __regid__ = 'anonuserlink'
+    __select__ = (HeaderComponent.__select__ & anonymous_user()
+                  & configuration_values('auth-mode', 'cookie'))
+    context = 'header-right'
+    loginboxid = 'popupLoginBox'
+    _html = u"""[<a class="logout" title="%s" href="javascript:
+cw.htmlhelpers.popupLoginBox('%s', '__login');">%s</a>]"""
+
+    def render(self, w):
+        # XXX bw compat, though should warn about subclasses redefining call
+        self.w = w
+        self.call()
+
     def call(self):
-        if self._cw.vreg.config['auth-mode'] == 'cookie':
-            self.w(self._cw._('anonymous'))
-            self.w(u'''&#160;[<a class="logout" href="javascript: popupLoginBox();">%s</a>]'''
-                   % (self._cw._('i18n_login_popup')))
-        else:
-            self.w(self._cw._('anonymous'))
-            self.w(u'&#160;[<a class="logout" href="%s">%s</a>]'
-                   % (self._cw.build_url('login'), self._cw._('login')))
+        self.w(self._html % (self._cw._('login / password'),
+                             self.loginboxid, self._cw._('i18n_login_popup')))
+        self.view('logform', rset=self.cw_rset, id=self.loginboxid,
+                  klass='%s hidden' % self.loginboxid, title=False, showmessage=False,
+                  w=self.w)
 
 
-class UserLink(_UserLink):
-    __select__ = _UserLink.__select__ & authenticated_user()
+class HTTPLoginComponent(CookieLoginComponent):
+    __select__ = (HeaderComponent.__select__ & anonymous_user()
+                  & configuration_values('auth-mode', 'http'))
+
+    def render(self, w):
+        # this redirects to the 'login' controller which in turn
+        # will raise a 401/Unauthorized
+        req = self._cw
+        w(u'[<a class="logout" title="%s" href="%s">%s</a>]'
+          % (req._('login / password'), req.build_url('login'), req._('login')))
+
 
-    def call(self):
+_UserLink = class_renamed('_UserLink', HeaderComponent)
+AnonUserLink = class_renamed('AnonUserLink', CookieLoginComponent)
+AnonUserLink.__abstract__ = True
+AnonUserLink.__select__ &= yes(1)
+
+
+class AnonUserStatusLink(HeaderComponent):
+    __regid__ = 'userstatus'
+    __select__ = HeaderComponent.__select__ & anonymous_user()
+    context = _('header-right')
+    order = HeaderComponent.order - 10
+
+    def render(self, w):
+        w(u'<span class="caption">%s</span>' % self._cw._('anonymous'))
+
+
+class AuthenticatedUserStatus(AnonUserStatusLink):
+    __select__ = HeaderComponent.__select__ & authenticated_user()
+
+    def render(self, w):
         # display useractions and siteactions
         actions = self._cw.vreg['actions'].possible_actions(self._cw, rset=self.cw_rset)
         box = MenuWidget('', 'userActionsBox', _class='', islist=False)
@@ -130,7 +175,7 @@
         for action in actions.get('siteactions', ()):
             menu.append(BoxLink(action.url(), self._cw._(action.title),
                                 action.html_class()))
-        box.render(w=self.w)
+        box.render(w=w)
 
 
 class ApplicationMessage(component.Component):
@@ -148,37 +193,10 @@
         self.w(u'<div id="appMsg" onclick="%s" class="%s">\n' %
                (toggle_action('appMsg'), (msgs and ' ' or 'hidden')))
         for msg in msgs:
-            self.w(u'<div class="message" id="%s">%s</div>' % (
-                self.div_id(), msg))
+            self.w(u'<div class="message" id="%s">%s</div>' % (self.domid, msg))
         self.w(u'</div>')
 
 
-class ApplicationName(component.Component):
-    """display the instance name"""
-    __regid__ = 'appliname'
-    cw_property_defs = VISIBLE_PROP_DEF
-    # don't want user to hide this component using an cwproperty
-    site_wide = True
-
-    def call(self):
-        title = self._cw.property_value('ui.site-title')
-        if title:
-            self.w(u'<span id="appliName"><a href="%s">%s</a></span>' % (
-                self._cw.base_url(), xml_escape(title)))
-
-
-class SeeAlsoVComponent(component.RelatedObjectsVComponent):
-    """display any entity's see also"""
-    __regid__ = 'seealso'
-    context = 'navcontentbottom'
-    rtype = 'see_also'
-    role = 'subject'
-    order = 40
-    # register msg not generated since no entity use see_also in cubicweb itself
-    title = _('contentnavigation_seealso')
-    help = _('contentnavigation_seealso_description')
-
-
 class EtypeRestrictionComponent(component.Component):
     """displays the list of entity types contained in the resultset
     to be able to filter accordingly.
@@ -230,17 +248,48 @@
         self.w(u'&#160;|&#160;'.join(html))
         self.w(u'</div>')
 
+# contextual components ########################################################
 
-class MetaDataComponent(component.EntityVComponent):
+class SeeAlsoComponent(component.RelatedObjectsCtxComponent):
+    """display any entity's see also"""
+    __regid__ = 'seealso'
+    context = 'navcontentbottom'
+    rtype = 'see_also'
+    role = 'subject'
+    order = 40
+    title = _('see_also')
+    # register msg not generated since no entity use see_also in cubicweb itself
+    _('ctxcomponents_seealso')
+    _('ctxcomponents_seealso_description')
+
+
+
+class MetaDataComponent(component.EntityCtxComponent):
     __regid__ = 'metadata'
     context = 'navbottom'
     order = 1
 
-    def cell_call(self, row, col, view=None):
-        self.wview('metadata', self.cw_rset, row=row, col=col)
+    def render_body(self, w):
+        self.entity.view('metadata', w=w)
+
+
+class SectionLayout(component.Layout):
+    __select__ = match_context('navtop', 'navbottom',
+                               'navcontenttop', 'navcontentbottom')
+    cssclass = 'section'
+
+    def render(self, w):
+        if self.init_rendering():
+            view = self.cw_extra_kwargs['view']
+            w(u'<div class="%s %s" id="%s">' % (self.cssclass, view.cssclass,
+                                                view.domid))
+            with wrap_on_write(w, '<h4>') as wow:
+                view.render_title(wow)
+            view.render_body(w)
+            w(u'</div>\n')
 
 
 def registration_callback(vreg):
-    vreg.register_all(globals().values(), __name__, (SeeAlsoVComponent,))
+    vreg.register_all(globals().values(), __name__, (SeeAlsoComponent,))
     if 'see_also' in vreg.schema:
-        vreg.register(SeeAlsoVComponent)
+        vreg.register(SeeAlsoComponent)
--- a/web/views/basecontrollers.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/basecontrollers.py	Wed Oct 13 08:37:21 2010 +0200
@@ -26,7 +26,7 @@
 
 from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError,
                       AuthenticationError, typed_eid)
-from cubicweb.utils import json, json_dumps
+from cubicweb.utils import UStringIO, json, json_dumps
 from cubicweb.selectors import authenticated_user, anonymous_user, match_form_params
 from cubicweb.mail import format_mail
 from cubicweb.web import Redirect, RemoteCallFailed, DirectResponse
@@ -130,16 +130,6 @@
                 rset = self.process_rql()
             else:
                 rset = None
-        if rset and rset.rowcount == 1 and '__method' in req.form:
-            entity = rset.get_entity(0, 0)
-            try:
-                method = getattr(entity, req.form.pop('__method'))
-                method()
-            except Redirect: # propagate redirect that might occur in method()
-                raise
-            except Exception, ex:
-                self.exception('while handling __method')
-                req.set_message(req._("error while handling __method: %s") % req._(ex))
         vid = req.form.get('vid') or vid_from_rset(req, rset, self._cw.vreg.schema)
         try:
             view = self._cw.vreg['views'].select(vid, req, rset=rset)
@@ -345,9 +335,14 @@
         return None
 
     def _call_view(self, view, paginate=False, **kwargs):
-        # set stream first, in case we need to call pagination
-        stream = view.set_stream()
         divid = self._cw.form.get('divid')
+        # we need to call pagination before with the stream set
+        try:
+            stream = view.set_stream()
+        except AttributeError:
+            stream = UStringIO()
+            kwargs['w'] = stream.write
+            assert not paginate
         if divid == 'pageContent':
             # ensure divid isn't reused by the view (e.g. table view)
             del self._cw.form['divid']
--- a/web/views/basetemplates.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/basetemplates.py	Wed Oct 13 08:37:21 2010 +0200
@@ -127,7 +127,7 @@
         w(u'<div id="pageContent">\n')
         vtitle = self._cw.form.get('vtitle')
         if vtitle:
-            w(u'<h1 class="vtitle">%s</h1>\n' % xml_escape(vtitle))
+            w(u'<div class="vtitle">%s</div>\n' % xml_escape(vtitle))
         # display entity type restriction component
         etypefilter = self._cw.vreg['components'].select_or_none(
             'etypenavigation', self._cw, rset=self.cw_rset)
@@ -188,9 +188,10 @@
         self.w(u'</body>')
 
     def nav_column(self, view, context):
-        boxes = list(self._cw.vreg['boxes'].poss_visible_objects(
+        boxes = list(self._cw.vreg['ctxcomponents'].poss_visible_objects(
             self._cw, rset=self.cw_rset, view=view, context=context))
         if boxes:
+            getlayout = self._cw.vreg['components'].select
             self.w(u'<td id="navColumn%s"><div class="navboxes">\n' % context.capitalize())
             for box in boxes:
                 box.render(w=self.w, view=view)
@@ -257,7 +258,7 @@
         w(u'<table width="100%" height="100%" border="0"><tr>\n')
         w(u'<td id="navColumnLeft">\n')
         self.topleft_header()
-        boxes = list(self._cw.vreg['boxes'].poss_visible_objects(
+        boxes = list(self._cw.vreg['ctxcomponents'].poss_visible_objects(
             self._cw, rset=self.cw_rset, view=view, context='left'))
         if boxes:
             w(u'<div class="navboxes">\n')
@@ -269,17 +270,18 @@
         w(u'<div id="pageContent">\n')
         vtitle = self._cw.form.get('vtitle')
         if vtitle:
-            w(u'<h1 class="vtitle">%s</h1>' % xml_escape(vtitle))
+            w(u'<div class="vtitle">%s</div>' % xml_escape(vtitle))
 
     def topleft_header(self):
         logo = self._cw.vreg['components'].select_or_none('logo', self._cw,
                                                           rset=self.cw_rset)
         if logo and logo.cw_propval('visible'):
-            self.w(u'<table id="header"><tr>\n')
-            self.w(u'<td>')
-            logo.render(w=self.w)
-            self.w(u'</td>\n')
-            self.w(u'</tr></table>\n')
+            w = self.w
+            w(u'<table id="header"><tr>\n')
+            w(u'<td>')
+            logo.render(w=w)
+            w(u'</td>\n')
+            w(u'</tr></table>\n')
 
 
 # page parts templates ########################################################
@@ -334,35 +336,20 @@
 
     def main_header(self, view):
         """build the top menu with authentification info and the rql box"""
-        self.w(u'<table id="header"><tr>\n')
-        self.w(u'<td id="firstcolumn">')
-        logo = self._cw.vreg['components'].select_or_none(
-            'logo', self._cw, rset=self.cw_rset)
-        if logo and logo.cw_propval('visible'):
-            logo.render(w=self.w)
-        self.w(u'</td>\n')
-        # appliname and breadcrumbs
-        self.w(u'<td id="headtext">')
-        for cid in self.main_cell_components:
-            comp = self._cw.vreg['components'].select_or_none(
-                cid, self._cw, rset=self.cw_rset)
-            if comp and comp.cw_propval('visible'):
-                comp.render(w=self.w)
-        self.w(u'</td>')
-        # logged user and help
-        self.w(u'<td>\n')
-        comp = self._cw.vreg['components'].select_or_none(
-            'loggeduserlink', self._cw, rset=self.cw_rset)
-        if comp and comp.cw_propval('visible'):
-            comp.render(w=self.w)
-        self.w(u'</td>')
-        # lastcolumn
-        self.w(u'<td id="lastcolumn">')
-        self.w(u'</td>\n')
-        self.w(u'</tr></table>\n')
-        if self._cw.session.anonymous_session:
-            self.wview('logform', rset=self.cw_rset, id='popupLoginBox',
-                       klass='hidden', title=False, showmessage=False)
+        w = self.w
+        w(u'<table id="header"><tr>\n')
+        for colid, context in (('firstcolumn', 'header-left'),
+                               ('headtext', 'header-center'),
+                               ('header-right', 'header-right'),
+                               ):
+            w(u'<td id="%s">' % colid)
+            components = self._cw.vreg['ctxcomponents'].poss_visible_objects(
+                self._cw, rset=self.cw_rset, view=view, context=context)
+            for comp in components:
+                comp.render(w=w)
+                w(u'&nbsp;')
+            w(u'</td>')
+        w(u'</tr></table>\n')
 
     def state_header(self):
         state = self._cw.search_state
@@ -379,7 +366,6 @@
         return self.w(u'<div class="stateMessage">%s</div>' % msg)
 
 
-
 class HTMLPageFooter(View):
     """default html page footer: include footer actions
     """
@@ -392,10 +378,8 @@
                                                             rset=self.cw_rset)
         footeractions = actions.get('footer', ())
         for i, action in enumerate(footeractions):
-            self.w(u'<a href="%s"' % action.url())
-            if getattr(action, 'html_class'):
-                self.w(u' class="%s"' % action.html_class())
-            self.w(u'>%s</a>' % self._cw._(action.title))
+            self.w(u'<a href="%s">%s</a>' % (action.url(),
+                                             self._cw._(action.title)))
             if i < (len(footeractions) - 1):
                 self.w(u' | ')
         self.w(u'</div>')
@@ -410,7 +394,7 @@
 
     def call(self, view, **kwargs):
         """by default, display informal messages in content header"""
-        components = self._cw.vreg['contentnavigation'].poss_visible_objects(
+        components = self._cw.vreg['ctxcomponents'].poss_visible_objects(
             self._cw, rset=self.cw_rset, view=view, context='navtop')
         if components:
             self.w(u'<div id="contentheader">')
@@ -426,7 +410,7 @@
     __regid__ = 'contentfooter'
 
     def call(self, view, **kwargs):
-        components = self._cw.vreg['contentnavigation'].poss_visible_objects(
+        components = self._cw.vreg['ctxcomponents'].poss_visible_objects(
             self._cw, rset=self.cw_rset, view=view, context='navbottom')
         if components:
             self.w(u'<div id="contentfooter">')
@@ -439,12 +423,16 @@
     __regid__ = 'logform'
     domid = 'loginForm'
     needs_css = ('cubicweb.login.css',)
+    onclick = "javascript: cw.htmlhelpers.popupLoginBox('%s', '%s');"
     # XXX have to recall fields name since python is mangling __login/__password
     __login = ff.StringField('__login', widget=fw.TextInput({'class': 'data'}))
     __password = ff.StringField('__password', label=_('password'),
                                 widget=fw.PasswordSingleInput({'class': 'data'}))
     form_buttons = [fw.SubmitButton(label=_('log in'),
-                                    attrs={'class': 'loginButton'})]
+                                    attrs={'class': 'loginButton'}),
+                    fw.ResetButton(label=_('cancel'),
+                                   attrs={'class': 'loginButton',
+                                          'onclick': onclick % ('popupLoginBox', '__login')}),]
 
     def form_action(self):
         if self.action is None:
@@ -453,32 +441,35 @@
 
 
 class LogFormView(View):
+    # XXX an awfull lot of hardcoded assumptions there
+    #     makes it unobvious to reuse/specialize
     __regid__ = 'logform'
     __select__ = match_kwargs('id', 'klass')
 
     title = 'log in'
 
     def call(self, id, klass, title=True, showmessage=True):
-        self.w(u'<div id="%s" class="%s">' % (id, klass))
+        w = self.w
+        w(u'<div id="%s" class="%s">' % (id, klass))
         if title:
             stitle = self._cw.property_value('ui.site-title')
             if stitle:
                 stitle = xml_escape(stitle)
             else:
                 stitle = u'&#160;'
-            self.w(u'<div id="loginTitle">%s</div>' % stitle)
-        self.w(u'<div id="loginContent">\n')
+            w(u'<div class="loginTitle">%s</div>' % stitle)
+        w(u'<div class="loginContent">\n')
         if showmessage and self._cw.message:
-            self.w(u'<div class="loginMessage">%s</div>\n' % self._cw.message)
+            w(u'<div class="loginMessage">%s</div>\n' % self._cw.message)
         config = self._cw.vreg.config
         if config['auth-mode'] != 'http':
             self.login_form(id) # Cookie authentication
-        self.w(u'</div>')
+        w(u'</div>')
         if self._cw.https and config.anonymous_user()[0]:
             path = xml_escape(config['base-url'] + self._cw.relative_path())
-            self.w(u'<div class="loginMessage"><a href="%s">%s</a></div>\n'
-                   % (path, self._cw._('No account? Try public access at %s') % path))
-        self.w(u'</div>\n')
+            w(u'<div class="loginMessage"><a href="%s">%s</a></div>\n'
+              % (path, self._cw._('No account? Try public access at %s') % path))
+        w(u'</div>\n')
 
     def login_form(self, id):
         cw = self._cw
@@ -488,7 +479,7 @@
         else:
             label = cw.pgettext('CWUser', 'login')
         form.field_by_name('__login').label = label
-        self.w(form.render(table_class='', display_progress_div=False))
+        form.render(w=self.w, table_class='', display_progress_div=False)
         cw.html_headers.add_onload('jQuery("#__login:visible").focus()')
 
 LogFormTemplate = class_renamed('LogFormTemplate', LogFormView)
--- a/web/views/baseviews.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/baseviews.py	Wed Oct 13 08:37:21 2010 +0200
@@ -33,11 +33,12 @@
 
 from logilab.mtconverter import TransformError, xml_escape, xml_escape
 
-from cubicweb import NoSelectableObject
-from cubicweb.selectors import yes, empty_rset, one_etype_rset
+from cubicweb import NoSelectableObject, tags
+from cubicweb.selectors import yes, empty_rset, one_etype_rset, match_kwargs
 from cubicweb.schema import display_name
 from cubicweb.view import EntityView, AnyRsetView, View
 from cubicweb.uilib import cut, printable_value
+from cubicweb.web.views import calendar
 
 
 class NullView(AnyRsetView):
@@ -436,3 +437,109 @@
 RssView = class_moved(xmlrss.RSSView)
 RssItemView = class_moved(xmlrss.RSSItemView)
 
+
+class GroupByView(EntityView):
+    """grouped view of a result set. The `group_key` method return the group
+    key of an entities (a string or tuple of string).
+
+    For each group, display a link to entities of this group by generating url
+    like <basepath>/<key> or <basepath>/<key item 1>/<key item 2>.
+    """
+    __abstrack__ = True
+    __select__ = EntityView.__select__ & match_kwargs('basepath')
+    entity_attribute = None
+    reversed = False
+
+    def index_url(self, basepath, key, **kwargs):
+        if isinstance(key, (list, tuple)):
+            key = '/'.join(key)
+        return self._cw.build_url('%s/%s' % (basepath, key),
+                                  **kwargs)
+
+    def index_link(self, basepath, key, items):
+        url = self.index_url(basepath, key)
+        if isinstance(key, (list, tuple)):
+            key = ' '.join(key)
+        return tags.a(key, href=url)
+
+    def group_key(self, entity, **kwargs):
+        value = getattr(entity, self.entity_attribute)
+        if callable(value):
+            value = value()
+        return value
+
+    def call(self, basepath, maxentries=None, **kwargs):
+        index = {}
+        for entity in self.cw_rset.entities():
+            index.setdefault(self.group_key(entity, **kwargs), []).append(entity)
+        displayed = sorted(index)
+        if self.reversed:
+            displayed = reversed(displayed)
+        if maxentries is None:
+            needmore = False
+        else:
+            needmore = len(index) > maxentries
+            displayed = tuple(displayed)[:maxentries]
+        w = self.w
+        w(u'<ul class="boxListing">')
+        for key in displayed:
+            w(u'<li>%s</li>\n' %
+              self.index_link(basepath, key, index[key]))
+        if needmore:
+            url = self._cw.build_url('view', vid=self.__regid__,
+                                     rql=self.cw_rset.printable_rql())
+            w( u'<li>%s</li>\n' % tags.a(u'[%s]' % self._cw._('see more'),
+                                         href=url))
+        w(u'</ul>\n')
+
+
+class ArchiveView(GroupByView):
+    """archive view of a result set. Links to months are built using a basepath
+    parameters, eg using url like <basepath>/<year>/<month>
+    """
+    __regid__ = 'cw.archive.by_date'
+    entity_attribute = 'creation_date'
+    reversed = True
+
+    def group_key(self, entity, **kwargs):
+        value = super(ArchiveView, self).group_key(entity, **kwargs)
+        return '%04d' % value.year, '%02d' % value.month
+
+    def index_link(self, basepath, key, items):
+        """represent a single month entry"""
+        year, month = key
+        label = u'%s %s [%s]' % (self._cw._(calendar.MONTHNAMES[int(month)-1]),
+                                 year, len(items))
+        etypes = set(entity.__regid__ for entity in items)
+        vtitle = '%s %s' % (', '.join(display_name(self._cw, etype, 'plural')
+                                      for etype in etypes),
+                            label)
+        title = self._cw._('archive for %(month)s/%(year)s') % {
+            'month': month, 'year': year}
+        url = self.index_url(basepath, key, vtitle=vtitle)
+        return tags.a(label, href=url, title=title)
+
+
+class AuthorView(GroupByView):
+    """author view of a result set. Links to month are built using a basepath
+    parameters, eg using url like <basepath>/<author>
+    """
+    __regid__ = 'cw.archive.by_author'
+    entity_attribute = 'creator'
+
+    def group_key(self, entity, **kwargs):
+        value = super(AuthorView, self).group_key(entity, **kwargs)
+        if value:
+            return value.login
+        return value
+
+    def index_link(self, basepath, key, items):
+        label = u'%s [%s]' % (key, len(items))
+        etypes = set(entity.__regid__ for entity in items)
+        vtitle = self._cw._('%(etype)s by %(author)s') % {
+            'etype': ', '.join(display_name(self._cw, etype, 'plural')
+                               for etype in etypes),
+            'author': label}
+        url = self.index_url(basepath, key, vtitle=vtitle)
+        title = self._cw._('archive for %(author)s') % {'author': key}
+        return tags.a(label, href=url, title=title)
--- a/web/views/bookmark.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/bookmark.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,9 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Primary view for bookmarks + user's bookmarks box
+"""Primary view for bookmarks + user's bookmarks box"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from logilab.mtconverter import xml_escape
@@ -25,7 +24,7 @@
 from cubicweb import Unauthorized
 from cubicweb.selectors import is_instance, one_line_rset
 from cubicweb.web.htmlwidgets import BoxWidget, BoxMenu, RawBoxItem
-from cubicweb.web import action, box, uicfg, formwidgets as fw
+from cubicweb.web import action, component, uicfg, formwidgets as fw
 from cubicweb.web.views import primary
 
 _abaa = uicfg.actionbox_appearsin_addmenu
@@ -70,58 +69,55 @@
         self.w(u'</div>')
 
 
-class BookmarksBox(box.UserRQLBoxTemplate):
+class BookmarksBox(component.CtxComponent):
     """display a box containing all user's bookmarks"""
     __regid__ = 'bookmarks_box'
+
+    title = _('bookmarks')
     order = 40
-    title = _('bookmarks')
     rql = ('Any B,T,P ORDERBY lower(T) '
            'WHERE B is Bookmark,B title T, B path P, B bookmarked_by U, '
            'U eid %(x)s')
-    etype = 'Bookmark'
-    rtype = 'bookmarked_by'
 
+    def init_rendering(self):
+        ueid = self._cw.user.eid
+        self.bookmarks_rset = self._cw.execute(self.rql, {'x': ueid})
+        rschema = self._cw.vreg.schema.rschema('bookmarked_by')
+        eschema = self._cw.vreg.schema.eschema('Bookmark')
+        self.can_delete = rschema.has_perm(self._cw, 'delete', toeid=ueid)
+        self.can_edit = (eschema.has_perm(self._cw, 'add') and
+                         rschema.has_perm(self._cw, 'add', toeid=ueid))
+        if not self.bookmarks_rset and not self.can_edit:
+            raise component.EmptyComponent()
+        self.items = []
 
-    def call(self, **kwargs):
+    def render_body(self, w):
+        ueid = self._cw.user.eid
         req = self._cw
-        ueid = req.user.eid
-        try:
-            rset = req.execute(self.rql, {'x': ueid})
-        except Unauthorized:
-            # can't access to something in the query, forget this box
-            return
-        box = BoxWidget(req._(self.title), self.__regid__)
-        box.listing_class = 'sideBox'
-        rschema = self._cw.vreg.schema.rschema(self.rtype)
-        eschema = self._cw.vreg.schema.eschema(self.etype)
-        candelete = rschema.has_perm(req, 'delete', toeid=ueid)
-        if candelete:
+        if self.can_delete:
             req.add_js('cubicweb.ajax.js')
-        else:
-            dlink = None
-        for bookmark in rset.entities():
-            label = '<a href="%s">%s</a>' % (xml_escape(bookmark.action_url()),
-                                             xml_escape(bookmark.title))
-            if candelete:
+        for bookmark in self.bookmarks_rset.entities():
+            label = self.build_link(bookmark.title, bookmark.action_url())
+            if self.can_delete:
                 dlink = u'[<a href="javascript:removeBookmark(%s)" title="%s">-</a>]' % (
                     bookmark.eid, _('delete this bookmark'))
-                label = '%s %s' % (dlink, label)
-            box.append(RawBoxItem(label))
-        if eschema.has_perm(req, 'add') and rschema.has_perm(req, 'add', toeid=ueid):
-            boxmenu = BoxMenu(req._('manage bookmarks'))
+                label = '<div>%s %s</div>' % (dlink, label)
+            self.append(label)
+        if self.can_edit:
+            menu = BoxMenu(req._('manage bookmarks'))
             linkto = 'bookmarked_by:%s:subject' % ueid
             # use a relative path so that we can move the instance without
             # loosing bookmarks
             path = req.relative_path()
-            # XXX if vtitle specified in params, extract it and use it as default value
-            # for bookmark's title
-            url = self.create_url(self.etype, __linkto=linkto, path=path)
-            boxmenu.append(self.mk_action(req._('bookmark this page'), url,
-                                          category='manage', id='bookmark'))
-            if rset:
+            # XXX if vtitle specified in params, extract it and use it as
+            # default value for bookmark's title
+            url = req.vreg['etypes'].etype_class('Bookmark').cw_create_url(
+                req, __linkto=linkto, path=path)
+            menu.append(self.build_link(req._('bookmark this page'), url))
+            if self.bookmarks_rset:
                 if req.user.is_in_group('managers'):
                     bookmarksrql = 'Bookmark B WHERE B bookmarked_by U, U eid %s' % ueid
-                    erset = rset
+                    erset = self.bookmarks_rset
                 else:
                     # we can't edit shared bookmarks we don't own
                     bookmarksrql = 'Bookmark B WHERE B bookmarked_by U, B owned_by U, U eid %(x)s'
@@ -129,11 +125,10 @@
                                         build_descr=False)
                     bookmarksrql %= {'x': ueid}
                 if erset:
-                    url = self._cw.build_url(vid='muledit', rql=bookmarksrql)
-                    boxmenu.append(self.mk_action(self._cw._('edit bookmarks'), url, category='manage'))
+                    url = req.build_url(vid='muledit', rql=bookmarksrql)
+                    menu.append(self.build_link(req._('edit bookmarks'), url))
             url = req.user.absolute_url(vid='xaddrelation', rtype='bookmarked_by',
                                         target='subject')
-            boxmenu.append(self.mk_action(self._cw._('pick existing bookmarks'), url, category='manage'))
-            box.append(boxmenu)
-        if not box.is_empty():
-            box.render(self.w)
+            menu.append(self.build_link(req._('pick existing bookmarks'), url))
+            self.append(menu)
+        self.render_items(w)
--- a/web/views/boxes.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/boxes.py	Wed Oct 13 08:37:21 2010 +0200
@@ -18,12 +18,14 @@
 """Generic boxes for CubicWeb web client:
 
 * actions box
-* possible views box
+* search box
 
-additional (disabled by default) boxes
+Additional boxes (disabled by default):
 * schema box
+* possible views box
 * startup views box
 """
+from __future__ import with_statement
 
 __docformat__ = "restructuredtext en"
 _ = unicode
@@ -31,42 +33,43 @@
 from warnings import warn
 
 from logilab.mtconverter import xml_escape
+from logilab.common.deprecation import class_deprecated
 
-from cubicweb.selectors import match_user_groups, non_final_entity
+from cubicweb import Unauthorized
+from cubicweb.selectors import (match_user_groups, match_kwargs,
+                                non_final_entity, nonempty_rset,
+                                match_context, contextual)
+from cubicweb.utils import wrap_on_write
 from cubicweb.view import EntityView
 from cubicweb.schema import display_name
-from cubicweb.web.htmlwidgets import BoxWidget, BoxMenu, BoxHtml, RawBoxItem
-from cubicweb.web.box import BoxTemplate
+from cubicweb.web import component, box, htmlwidgets
 
+# XXX bw compat, some cubes import this class from here
+BoxTemplate = box.BoxTemplate
+BoxHtml = htmlwidgets.BoxHtml
 
-class EditBox(BoxTemplate): # XXX rename to ActionsBox
+class EditBox(component.CtxComponent): # XXX rename to ActionsBox
     """
     box with all actions impacting the entity displayed: edit, copy, delete
     change state, add related entities
     """
     __regid__ = 'edit_box'
-    __select__ = BoxTemplate.__select__ & non_final_entity()
+    __select__ = component.CtxComponent.__select__ & non_final_entity()
 
     title = _('actions')
     order = 2
+    contextual = True
 
-    def call(self, view=None, **kwargs):
+    def init_rendering(self):
+        super(EditBox, self).init_rendering()
         _ = self._cw._
-        title = _(self.title)
-        if self.cw_rset:
-            etypes = self.cw_rset.column_types(0)
-            if len(etypes) == 1:
-                plural = self.cw_rset.rowcount > 1 and 'plural' or ''
-                etypelabel = display_name(self._cw, iter(etypes).next(), plural)
-                title = u'%s - %s' % (title, etypelabel.lower())
-        box = BoxWidget(title, self.__regid__, _class="greyBoxFrame")
         self._menus_in_order = []
         self._menus_by_id = {}
         # build list of actions
         actions = self._cw.vreg['actions'].possible_actions(self._cw, self.cw_rset,
-                                                            view=view)
+                                                            **self.cw_extra_kwargs)
         other_menu = self._get_menu('moreactions', _('more actions'))
-        for category, defaultmenu in (('mainactions', box),
+        for category, defaultmenu in (('mainactions', self),
                                       ('moreactions', other_menu),
                                       ('addrelated', None)):
             for action in actions.get(category, ()):
@@ -81,16 +84,28 @@
                     menu = defaultmenu
                 action.fill_menu(self, menu)
         # if we've nothing but actions in the other_menu, add them directly into the box
-        if box.is_empty() and len(self._menus_by_id) == 1 and not other_menu.is_empty():
-            box.items = other_menu.items
-            other_menu.items = []
+        if not self.items and len(self._menus_by_id) == 1 and not other_menu.is_empty():
+            self.items = other_menu.items
         else: # ensure 'more actions' menu appears last
             self._menus_in_order.remove(other_menu)
             self._menus_in_order.append(other_menu)
-        for submenu in self._menus_in_order:
-            self.add_submenu(box, submenu)
-        if not box.is_empty():
-            box.render(self.w)
+            for submenu in self._menus_in_order:
+                self.add_submenu(self, submenu)
+        if not self.items:
+            raise component.EmptyComponent()
+
+    def render_title(self, w):
+        title = self._cw._(self.title)
+        if self.cw_rset:
+            etypes = self.cw_rset.column_types(0)
+            if len(etypes) == 1:
+                plural = self.cw_rset.rowcount > 1 and 'plural' or ''
+                etypelabel = display_name(self._cw, iter(etypes).next(), plural)
+                title = u'%s - %s' % (title, etypelabel.lower())
+        w(title)
+
+    def render_body(self, w):
+        self.render_items(w)
 
     def _get_menu(self, id, title=None, label_prefix=None):
         try:
@@ -98,7 +113,7 @@
         except KeyError:
             if title is None:
                 title = self._cw._(id)
-            self._menus_by_id[id] = menu = BoxMenu(title)
+            self._menus_by_id[id] = menu = htmlwidgets.BoxMenu(title)
             menu.label_prefix = label_prefix
             self._menus_in_order.append(menu)
             return menu
@@ -108,19 +123,22 @@
         if len(submenu.items) == 1 and not appendanyway:
             boxlink = submenu.items[0]
             if submenu.label_prefix:
-                boxlink.label = u'%s %s' % (submenu.label_prefix, boxlink.label)
+                # XXX iirk
+                if hasattr(boxlink, 'label'):
+                    boxlink.label = u'%s %s' % (submenu.label_prefix, boxlink.label)
+                else:
+                    submenu.items[0] = u'%s %s' % (submenu.label_prefix, boxlink)
             box.append(boxlink)
         elif submenu.items:
             box.append(submenu)
         elif appendanyway:
-            box.append(RawBoxItem(xml_escape(submenu.label)))
+            box.append(xml_escape(submenu.label))
 
 
-class SearchBox(BoxTemplate):
+class SearchBox(component.CtxComponent):
     """display a box with a simple search form"""
     __regid__ = 'search_box'
 
-    visible = True # enabled by default
     title = _('search')
     order = 0
     formdef = u"""<form action="%s">
@@ -130,77 +148,122 @@
 <input type="hidden" name="subvid" value="tsearch" />
 </td><td>
 <input tabindex="%s" type="submit" id="rqlboxsubmit" class="rqlsubmit" value="" />
-</td></tr></table>
-</form>"""
+ </td></tr></table>
+ </form>"""
 
-    def call(self, view=None, **kwargs):
-        req = self._cw
-        if req.form.pop('__fromsearchbox', None):
-            rql = req.form.get('rql', '')
+    def render_title(self, w):
+        w(u"""<span onclick="javascript: toggleVisibility('rqlinput')">%s</span>"""
+          % self._cw._(self.title))
+
+    def render_body(self, w):
+        if self._cw.form.pop('__fromsearchbox', None):
+            rql = self._cw.form.get('rql', '')
         else:
             rql = ''
-        form = self.formdef % (req.build_url('view'), req.next_tabindex(),
-                               xml_escape(rql), req.next_tabindex())
-        title = u"""<span onclick="javascript: toggleVisibility('rqlinput')">%s</span>""" % req._(self.title)
-        box = BoxWidget(title, self.__regid__, _class="searchBoxFrame", islist=False, escape=False)
-        box.append(BoxHtml(form))
-        box.render(self.w)
+        w(self.formdef % (self._cw.build_url('view'), self._cw.next_tabindex(),
+                          xml_escape(rql), self._cw.next_tabindex()))
 
 
 # boxes disabled by default ###################################################
 
-class PossibleViewsBox(BoxTemplate):
+class PossibleViewsBox(component.CtxComponent):
     """display a box containing links to all possible views"""
     __regid__ = 'possible_views_box'
-    __select__ = BoxTemplate.__select__ & match_user_groups('users', 'managers')
 
     visible = False
     title = _('possible views')
     order = 10
 
-    def call(self, **kwargs):
-        box = BoxWidget(self._cw._(self.title), self.__regid__)
-        views = [v for v in self._cw.vreg['views'].possible_views(self._cw,
-                                                              rset=self.cw_rset)
-                 if v.category != 'startupview']
-        for category, views in self.sort_actions(views):
-            menu = BoxMenu(category)
+    def init_rendering(self):
+        self.views = [v for v in self._cw.vreg['views'].possible_views(self._cw,
+                                                                       rset=self.cw_rset)
+                      if v.category != 'startupview']
+        if not self.views:
+            raise component.EmptyComponent()
+        self.items = []
+
+    def render_body(self, w):
+        for category, views in box.sort_by_category(self.views):
+            menu = htmlwidgets.BoxMenu(category)
             for view in views:
                 menu.append(self.box_action(view))
-            box.append(menu)
-        if not box.is_empty():
-            box.render(self.w)
+            self.append(menu)
+        self.render_items(w)
 
 
-class StartupViewsBox(BoxTemplate):
+class StartupViewsBox(PossibleViewsBox):
     """display a box containing links to all startup views"""
     __regid__ = 'startup_views_box'
+
     visible = False # disabled by default
     title = _('startup views')
     order = 70
 
-    def call(self, **kwargs):
-        box = BoxWidget(self._cw._(self.title), self.__regid__)
-        for view in self._cw.vreg['views'].possible_views(self._cw, None):
-            if view.category == 'startupview':
-                box.append(self.box_action(view))
-        if not box.is_empty():
-            box.render(self.w)
+    def init_rendering(self):
+        self.views = [v for v in self._cw.vreg['views'].possible_views(self._cw)
+                      if v.category == 'startupview']
+        if not self.views:
+            raise component.EmptyComponent()
+        self.items = []
 
 
-# helper classes ##############################################################
+class RsetBox(component.CtxComponent):
+    """helper view class to display an rset in a sidebox"""
+    __select__ = nonempty_rset() & match_kwargs('title', 'vid')
+    __regid__ = 'rsetbox'
+    cw_property_defs = {}
+    context = 'incontext'
+
+    @property
+    def domid(self):
+        return super(RsetBox, self).domid + unicode(abs(id(self)))
+
+    def render_title(self, w):
+        w(self.cw_extra_kwargs['title'])
+
+    def render_body(self, w):
+        self._cw.view(self.cw_extra_kwargs['vid'], self.cw_rset, w=w)
+
+ # helper classes ##############################################################
 
 class SideBoxView(EntityView):
     """helper view class to display some entities in a sidebox"""
+    __metaclass__ = class_deprecated
+    __deprecation_warning__ = '[3.10] SideBoxView is deprecated, use RsetBox instead (%(cls)s)'
+
     __regid__ = 'sidebox'
 
-    def call(self, boxclass='sideBox', title=u''):
+    def call(self, **kwargs):
         """display a list of entities by calling their <item_vid> view"""
-        if title:
-            self.w(u'<div class="sideBoxTitle"><span>%s</span></div>' % title)
         if 'dispctrl' in self.cw_extra_kwargs:
             # XXX do not modify dispctrl!
             self.cw_extra_kwargs['dispctrl'].setdefault('subvid', 'outofcontext')
-        self.w(u'<div class="%s"><div class="sideBoxBody">' % boxclass)
-        self.wview('autolimited', self.cw_rset, **self.cw_extra_kwargs)
-        self.w(u'</div>\n</div>\n')
+        box = self._cw.vreg['ctxcomponents'].select(
+            'rsetbox', self._cw, rset=self.cw_rset, vid='autolimited',
+            title=title, **self.cw_extra_kwargs)
+        box.render(self.w)
+
+
+class ContextualBoxLayout(component.Layout):
+    __select__ = match_context('incontext', 'left', 'right') & contextual()
+    # predefined class in cubicweb.css: contextualBox | contextFreeBox
+    # XXX: navigationBox | actionBox
+    cssclass = 'contextualBox'
+
+    def render(self, w):
+        if self.init_rendering():
+            view = self.cw_extra_kwargs['view']
+            w(u'<div class="%s %s" id="%s">' % (self.cssclass, view.cssclass,
+                                                view.domid))
+            with wrap_on_write(w, u'<div class="boxTitle"><span>',
+                               u'</span></div>') as wow:
+                view.render_title(wow)
+            w(u'<div class="boxBody">')
+            view.render_body(w)
+            # boxFooter div is a CSS place holder (for shadow for example)
+            w(u'</div><div class="boxFooter"></div></div>\n')
+
+
+class ContextFreeBoxLayout(ContextualBoxLayout):
+    __select__ = match_context('incontext', 'left', 'right') & ~contextual()
+    cssclass = 'contextFreeBox'
--- a/web/views/cwproperties.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/cwproperties.py	Wed Oct 13 08:37:21 2010 +0200
@@ -45,7 +45,7 @@
 _('ui')
 _('boxes')
 _('components')
-_('contentnavigation')
+_('ctxcomponents')
 _('navigation.combobox-limit')
 _('navigation.page-size')
 _('navigation.related-limit')
@@ -200,8 +200,8 @@
         else:
             entity = self._cw.vreg['etypes'].etype_class('CWProperty')(self._cw)
             entity.eid = self._cw.varmaker.next()
-            entity['pkey'] = key
-            entity['value'] = self._cw.vreg.property_value(key)
+            entity.cw_attr_cache['pkey'] = key
+            entity.cw_attr_cache['value'] = self._cw.vreg.property_value(key)
         return entity
 
     def form(self, formid, keys, splitlabel=False):
@@ -219,7 +219,9 @@
             self.form_row(form, key, splitlabel)
         renderer = self._cw.vreg['formrenderers'].select('cwproperties', self._cw,
                                                      display_progress_div=False)
-        return form.render(renderer=renderer)
+        data = []
+        form.render(w=data.append, renderer=renderer)
+        return u'\n'.join(data)
 
     def form_row(self, form, key, splitlabel):
         entity = self.entity_for_key(key)
@@ -329,7 +331,7 @@
 
     def form_init(self, form):
         entity = form.edited_entity
-        if not (entity.has_eid() or 'pkey' in entity):
+        if not (entity.has_eid() or 'pkey' in entity.cw_attr_cache):
             # no key set yet, just include an empty div which will be filled
             # on key selection
             return
@@ -353,7 +355,7 @@
         if vocab is not None:
             if callable(vocab):
                 # list() just in case its a generator function
-                self.choices = list(vocab(form._cw))
+                self.choices = list(vocab())
             else:
                 self.choices = vocab
             wdg = Select()
--- a/web/views/debug.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/debug.py	Wed Oct 13 08:37:21 2010 +0200
@@ -119,10 +119,15 @@
             if sessions:
                 w(u'<ul>')
                 for session in sessions:
+                    try:
+                        last_usage_time = session.cnx.check()
+                    except BadConnectionId:
+                        w(u'<li>%s (INVALID)</li>' % session.sessionid)
+                        continue
                     w(u'<li>%s (%s: %s)<br/>' % (
                         session.sessionid,
                         _('last usage'),
-                        strftime(dtformat, localtime(session.last_usage_time))))
+                        strftime(dtformat, localtime(last_usage_time))))
                     dict_to_html(w, session.data)
                     w(u'</li>')
                 w(u'</ul>')
@@ -145,6 +150,8 @@
         self.w(u'<p>%s</p>\n' % ' - '.join('<a href="%s#%s">%s</a>'
                                            % (url, key, key) for key in keys))
         for key in keys:
+            if key in ('boxes', 'contentnavigation'): # those are bw compat registries
+                continue
             self.w(u'<h2 id="%s">%s</h2>' % (key, key))
             if self._cw.vreg[key]:
                 values = sorted(self._cw.vreg[key].iteritems())
--- a/web/views/editcontroller.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/editcontroller.py	Wed Oct 13 08:37:21 2010 +0200
@@ -115,19 +115,14 @@
         form = req.form
         # so we're able to know the main entity from the repository side
         if '__maineid' in form:
-            req.set_shared_data('__maineid', form['__maineid'], querydata=True)
+            req.set_shared_data('__maineid', form['__maineid'], txdata=True)
         # no specific action, generic edition
         self._to_create = req.data['eidmap'] = {}
         self._pending_fields = req.data['pendingfields'] = set()
         try:
-            methodname = req.form.pop('__method', None)
             for eid in req.edited_eids():
                 # __type and eid
                 formparams = req.extract_entity_params(eid, minparams=2)
-                if methodname is not None:
-                    entity = req.entity_from_eid(eid)
-                    method = getattr(entity, methodname)
-                    method(formparams)
                 eid = self.edit_entity(formparams)
         except (RequestError, NothingToEdit), ex:
             if '__linkto' in req.form and 'eid' in req.form:
--- a/web/views/editforms.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/editforms.py	Wed Oct 13 08:37:21 2010 +0200
@@ -90,7 +90,7 @@
             w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'),
                                       href=entity.absolute_url()))
         w(u'</ul>\n')
-        w(form.render())
+        form.render(w=self.w)
 
 
 class EditionFormView(FormViewMixIn, EntityView):
@@ -112,7 +112,7 @@
         form = self._cw.vreg['forms'].select('edition', self._cw, entity=entity,
                                              submitmsg=self.submited_message())
         self.init_form(form, entity)
-        self.w(form.render())
+        form.render(w=self.w)
 
     def init_form(self, form, entity):
         """customize your form before rendering here"""
@@ -169,7 +169,9 @@
 
     def url(self):
         """return the url associated with this view"""
-        return self.create_url(self._cw.form.get('etype'))
+        req = self._cw
+        return req.vreg["etypes"].etype_class(req.form['etype']).cw_create_url(
+            req)
 
     def submited_message(self):
         """return the message that will be displayed on successful edition"""
@@ -256,7 +258,7 @@
                                              rset=self.cw_rset,
                                              copy_nav_params=True,
                                              formvid='edition')
-        self.w(form.render())
+        form.render(w=self.w)
 
 
 # click and edit handling ('reledit') ##########################################
--- a/web/views/facets.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/facets.py	Wed Oct 13 08:37:21 2010 +0200
@@ -25,7 +25,7 @@
 from cubicweb.selectors import (non_final_entity, multi_lines_rset,
                                 match_context_prop, yes, relation_possible)
 from cubicweb.utils import json_dumps
-from cubicweb.web.box import BoxTemplate
+from cubicweb.web import component
 from cubicweb.web.facet import (AbstractFacet, FacetStringWidget, RelationFacet,
                                 prepare_facets_rqlst, filter_hiddens, _cleanup_rqlst,
                                 _prepare_vocabulary_rqlst)
@@ -38,14 +38,13 @@
     return 0
 
 
-class FilterBox(BoxTemplate):
+class FilterBox(component.CtxComponent):
     """filter results of a query"""
-    __regid__ = 'filter_box'
-    __select__ = (((non_final_entity() & multi_lines_rset())
-                   | contextview_selector()
-                   ) & match_context_prop())
-    context = 'left'
-    title = _('boxes_filter_box')
+    __regid__ = 'facet.filters'
+    __select__ = ((non_final_entity() & multi_lines_rset())
+                  | contextview_selector())
+    context = 'left' # XXX doesn't support 'incontext', only 'left' or 'right'
+    title = _('facet.filters')
     visible = True # functionality provided by the search box by default
     order = 1
     roundcorners = True
@@ -61,7 +60,8 @@
         """
         return {}
 
-    def _get_context(self, view):
+    def _get_context(self):
+        view = self.cw_extra_kwargs.get('view')
         context = getattr(view, 'filter_box_context_info', lambda: None)()
         if context:
             rset, vid, divid, paginate = context
@@ -71,14 +71,15 @@
             paginate = view and view.paginable
         return rset, vid, divid, paginate
 
-    def call(self, view=None):
+    def render(self, w, **kwargs):
         req = self._cw
         req.add_js( self.needs_js )
         req.add_css( self.needs_css)
         if self.roundcorners:
             req.html_headers.add_onload('jQuery(".facet").corner("tl br 10px");')
-        rset, vid, divid, paginate = self._get_context(view)
-        if rset.rowcount < 2: # XXX done by selectors, though maybe necessary when rset has been hijacked
+        rset, vid, divid, paginate = self._get_context()
+        # XXX done by selectors, though maybe necessary when rset has been hijacked
+        if rset.rowcount < 2:
             return
         rqlst = rset.syntax_tree()
         # union not yet supported
@@ -97,9 +98,8 @@
             return
         if vid is None:
             vid = req.form.get('vid')
-        if self.bk_linkbox_template:
-            self.display_bookmark_link(rset)
-        w = self.w
+        if self.bk_linkbox_template and req.vreg.schema['Bookmark'].has_perm(req, 'add'):
+            w(self.bookmark_link(rset))
         w(u'<form method="post" id="%sForm" cubicweb:facetargs="%s" action="">'  % (
             divid, xml_escape(json_dumps([divid, vid, paginate, self.facetargs()]))))
         w(u'<fieldset>')
@@ -110,25 +110,25 @@
                 hiddens[param] = req.form[param]
         filter_hiddens(w, **hiddens)
         for wdg in widgets:
-            wdg.render(w=self.w)
+            wdg.render(w=w)
         w(u'</fieldset>\n</form>\n')
 
-    def display_bookmark_link(self, rset):
-        eschema = self._cw.vreg.schema.eschema('Bookmark')
-        if eschema.has_perm(self._cw, 'add'):
-            bk_path = 'rql=%s' % self._cw.url_quote(rset.printable_rql())
-            if self._cw.form.get('vid'):
-                bk_path += '&vid=%s' % self._cw.url_quote(self._cw.form['vid'])
-            bk_path = 'view?' + bk_path
-            bk_title = self._cw._('my custom search')
-            linkto = 'bookmarked_by:%s:subject' % self._cw.user.eid
-            bk_add_url = self._cw.build_url('add/Bookmark', path=bk_path, title=bk_title, __linkto=linkto)
-            bk_base_url = self._cw.build_url('add/Bookmark', title=bk_title, __linkto=linkto)
-            bk_link = u'<a cubicweb:target="%s" id="facetBkLink" href="%s">%s</a>' % (
-                    xml_escape(bk_base_url),
-                    xml_escape(bk_add_url),
-                    self._cw._('bookmark this search'))
-            self.w(self.bk_linkbox_template % bk_link)
+    def bookmark_link(self, rset):
+        req = self._cw
+        bk_path = u'rql=%s' % req.url_quote(rset.printable_rql())
+        if req.form.get('vid'):
+            bk_path += u'&vid=%s' % req.url_quote(req.form['vid'])
+        bk_path = u'view?' + bk_path
+        bk_title = req._('my custom search')
+        linkto = u'bookmarked_by:%s:subject' % req.user.eid
+        bkcls = req.vreg['etypes'].etype_class('Bookmark')
+        bk_add_url = bkcls.cw_create_url(req, path=bk_path, title=bk_title,
+                                         __linkto=linkto)
+        bk_base_url = bkcls.cw_create_url(req, title=bk_title, __linkto=linkto)
+        bk_link = u'<a cubicweb:target="%s" id="facetBkLink" href="%s">%s</a>' % (
+                xml_escape(bk_base_url), xml_escape(bk_add_url),
+                req._('bookmark this search'))
+        return self.bk_linkbox_template % bk_link
 
     def get_facets(self, rset, rqlst, mainvar):
         return self._cw.vreg['facets'].poss_visible_objects(
@@ -137,6 +137,11 @@
 
 # facets ######################################################################
 
+class CWSourceFacet(RelationFacet):
+    __regid__ = 'cw_source-facet'
+    rtype = 'cw_source'
+    target_attr = 'name'
+
 class CreatedByFacet(RelationFacet):
     __regid__ = 'created_by-facet'
     rtype = 'created_by'
--- a/web/views/formrenderers.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/formrenderers.py	Wed Oct 13 08:37:21 2010 +0200
@@ -41,7 +41,7 @@
 from cubicweb import tags
 from cubicweb.appobject import AppObject
 from cubicweb.selectors import is_instance, yes
-from cubicweb.utils import json_dumps
+from cubicweb.utils import json_dumps, support_args
 from cubicweb.web import eid_param, formwidgets as fwdgs
 
 
@@ -53,6 +53,8 @@
         name, value, checked, attrs)
 
 def field_label(form, field):
+    if callable(field.label):
+        return field.label(form, field)
     # XXX with 3.6 we can now properly rely on 'if field.role is not None' and
     # stop having a tuple for label
     if isinstance(field.label, tuple): # i.e. needs contextual translation
@@ -102,11 +104,9 @@
 
     # renderer interface ######################################################
 
-    def render(self, form, values):
+    def render(self, w, form, values):
         self._set_options(values)
         form.add_media()
-        data = []
-        w = data.append
         w(self.open_form(form, values))
         if self.display_progress_div:
             w(u'<div id="progress">%s</div>' % self._cw._('validating...'))
@@ -118,7 +118,6 @@
         errormsg = self.error_message(form)
         if errormsg:
             data.insert(0, errormsg)
-        return '\n'.join(data)
 
     def render_label(self, form, field):
         if field.label is None:
@@ -133,7 +132,12 @@
         help = []
         descr = field.help
         if callable(descr):
-            descr = descr(form)
+            if support_args(descr, 'form', 'field'):
+                descr = descr(form, field)
+            else:
+                warn("[3.10] field's help callback must now take form and field as argument",
+                     DeprecationWarning)
+                descr = descr(form)
         if descr:
             help.append('<div class="helper">%s</div>' % self._cw._(descr))
         example = field.example_format(self._cw)
@@ -172,29 +176,29 @@
 
     def open_form(self, form, values):
         if form.needs_multipart:
-            enctype = 'multipart/form-data'
+            enctype = u'multipart/form-data'
         else:
-            enctype = 'application/x-www-form-urlencoded'
-        tag = ('<form action="%s" method="post" enctype="%s"' % (
+            enctype = u'application/x-www-form-urlencoded'
+        tag = (u'<form action="%s" method="post" enctype="%s"' % (
             xml_escape(form.form_action() or '#'), enctype))
         if form.domid:
-            tag += ' id="%s"' % form.domid
+            tag += u' id="%s"' % form.domid
         if form.onsubmit:
-            tag += ' onsubmit="%s"' % xml_escape(form.onsubmit % dictattr(form))
+            tag += u' onsubmit="%s"' % xml_escape(form.onsubmit % dictattr(form))
         if form.cssstyle:
-            tag += ' style="%s"' % xml_escape(form.cssstyle)
+            tag += u' style="%s"' % xml_escape(form.cssstyle)
         if form.cssclass:
-            tag += ' class="%s"' % xml_escape(form.cssclass)
+            tag += u' class="%s"' % xml_escape(form.cssclass)
         if form.cwtarget:
-            tag += ' cubicweb:target="%s"' % xml_escape(form.cwtarget)
-        return tag + '>'
+            tag += u' cubicweb:target="%s"' % xml_escape(form.cwtarget)
+        return tag + u'>'
 
     def close_form(self, form, values):
         """seems dumb but important for consistency w/ close form, and necessary
         for form renderers overriding open_form to use something else or more than
         and <form>
         """
-        return '</form>'
+        return u'</form>'
 
     def render_fields(self, w, form, values):
         fields = self._render_hidden_fields(w, form)
@@ -237,9 +241,9 @@
                 w(u'<tr class="%s_%s_row">' % (field.name, field.role))
                 if self.display_label and field.label is not None:
                     w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
-                w('<td')
+                w(u'<td')
                 if field.label is None:
-                    w(' colspan="2"')
+                    w(u' colspan="2"')
                 error = form.field_error(field)
                 if error:
                     w(u' class="error"')
@@ -441,10 +445,8 @@
     """
     __regid__ = 'inline'
 
-    def render(self, form, values):
+    def render(self, w, form, values):
         form.add_media()
-        data = []
-        w = data.append
         try:
             w(u'<div id="div-%(divid)s" onclick="%(divonclick)s">' % values)
         except KeyError:
@@ -470,7 +472,6 @@
             values.pop(key, None)
         self.render_fields(w, form, values)
         w(u'</div></div>')
-        return '\n'.join(data)
 
     def render_fields(self, w, form, values):
         w(u'<fieldset id="fs-%(divid)s">' % values)
--- a/web/views/forms.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/forms.py	Wed Oct 13 08:37:21 2010 +0200
@@ -168,10 +168,20 @@
             warn('[3.6] rendervalues argument is deprecated, all named arguments will be given instead',
                  DeprecationWarning, stacklevel=2)
             kwargs = rendervalues
+        w = kwargs.pop('w', None)
+        if w is None:
+            warn('[3.10] you should specify "w" to form.render() named arguments',
+                 DeprecationWarning, stacklevel=2)
+            data = []
+            w = data.append
+        else:
+            data = None
         self.build_context(formvalues)
         if renderer is None:
             renderer = self.default_renderer()
-        return renderer.render(self, kwargs)
+        renderer.render(w, self, kwargs)
+        if data is not None:
+            return '\n'.join(data)
 
     def default_renderer(self):
         return self._cw.vreg['formrenderers'].select(
--- a/web/views/ibreadcrumbs.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/ibreadcrumbs.py	Wed Oct 13 08:37:21 2010 +0200
@@ -25,12 +25,13 @@
 from logilab.mtconverter import xml_escape
 
 #from cubicweb.interfaces import IBreadCrumbs
+from cubicweb import tags, uilib
+from cubicweb.entity import Entity
 from cubicweb.selectors import (is_instance, one_line_rset, adaptable,
                                 one_etype_rset, multi_lines_rset, any_rset)
-from cubicweb.view import EntityView, Component, EntityAdapter
+from cubicweb.view import EntityView, EntityAdapter
+from cubicweb.web.views import basecomponents
 # don't use AnyEntity since this may cause bug with isinstance() due to reloading
-from cubicweb.entity import Entity
-from cubicweb import tags, uilib
 
 
 # ease bw compat
@@ -61,7 +62,7 @@
             return itree.parent()
         return None
 
-    def breadcrumbs(self, view=None, recurs=False):
+    def breadcrumbs(self, view=None, recurs=None):
         """return a list containing some:
 
         * tuple (url, label)
@@ -70,14 +71,30 @@
 
         defining path from a root to the current view
 
-        the main view is given as argument so breadcrumbs may vary according
-        to displayed view (may be None). When recursing on a parent entity,
-        the `recurs` argument should be set to True.
+        the main view is given as argument so breadcrumbs may vary according to
+        displayed view (may be None). When recursing on a parent entity, the
+        `recurs` argument should be a set of already traversed nodes (infinite
+        loop safety belt).
         """
         parent = self.parent_entity()
         if parent is not None:
+            if recurs is True:
+                _recurs = set()
+                warn('[3.10] recurs argument should be a set() or None',
+                     DeprecationWarning, stacklevel=2)
+            elif recurs:
+                _recurs = recurs
+            else:
+                if recurs is False:
+                    warn('[3.10] recurs argument should be a set() or None',
+                         DeprecationWarning, stacklevel=2)
+                _recurs = set()
+            if _recurs and parent.eid in _recurs:
+                self.error('cycle in breadcrumbs for entity %s' % self.entity)
+                return []
+            _recurs.add(parent.eid)
             adapter = ibreadcrumb_adapter(parent)
-            path = adapter.breadcrumbs(view, True) + [self.entity]
+            path = adapter.breadcrumbs(view, _recurs) + [self.entity]
         else:
             path = [self.entity]
         if not recurs:
@@ -90,84 +107,82 @@
         return path
 
 
-class BreadCrumbEntityVComponent(Component):
+class BreadCrumbEntityVComponent(basecomponents.HeaderComponent):
     __regid__ = 'breadcrumbs'
-    __select__ = one_line_rset() & adaptable('IBreadCrumbs')
-
-    cw_property_defs = {
-        _('visible'):  dict(type='Boolean', default=True,
-                            help=_('display the component or not')),
-        }
-    title = _('contentnavigation_breadcrumbs')
-    help = _('contentnavigation_breadcrumbs_description')
+    __select__ = (basecomponents.HeaderComponent.__select__
+                  & one_line_rset() & adaptable('IBreadCrumbs'))
+    order = basecomponents.ApplicationName.order + 1
     separator = u'&#160;&gt;&#160;'
     link_template = u'<a href="%s">%s</a>'
+    first_separator = True
 
-    def call(self, view=None, first_separator=True):
+    def render(self, w):
         entity = self.cw_rset.get_entity(0, 0)
         adapter = ibreadcrumb_adapter(entity)
+        view = self.cw_extra_kwargs.get('view')
         path = adapter.breadcrumbs(view)
         if path:
-            self.open_breadcrumbs()
-            if first_separator:
-                self.w(self.separator)
-            self.render_breadcrumbs(entity, path)
-            self.close_breadcrumbs()
+            self.open_breadcrumbs(w)
+            if self.first_separator:
+                w(self.separator)
+            self.render_breadcrumbs(w, entity, path)
+            self.close_breadcrumbs(w)
 
-    def open_breadcrumbs(self):
-        self.w(u'<span id="breadcrumbs" class="pathbar">')
+    def open_breadcrumbs(self, w):
+        w(u'<span id="breadcrumbs" class="pathbar">')
 
-    def close_breadcrumbs(self):
-        self.w(u'</span>')
+    def close_breadcrumbs(self, w):
+        w(u'</span>')
 
-    def render_breadcrumbs(self, contextentity, path):
+    def render_breadcrumbs(self, w, contextentity, path):
         root = path.pop(0)
         if isinstance(root, Entity):
-            self.w(self.link_template % (self._cw.build_url(root.__regid__),
+            w(self.link_template % (self._cw.build_url(root.__regid__),
                                          root.dc_type('plural')))
-            self.w(self.separator)
-        self.wpath_part(root, contextentity, not path)
+            w(self.separator)
+        self.wpath_part(w, root, contextentity, not path)
         for i, parent in enumerate(path):
-            self.w(self.separator)
-            self.w(u"\n")
-            self.wpath_part(parent, contextentity, i == len(path) - 1)
+            w(self.separator)
+            w(u"\n")
+            self.wpath_part(w, parent, contextentity, i == len(path) - 1)
 
-    def wpath_part(self, part, contextentity, last=False): # XXX deprecates last argument?
+    def wpath_part(self, w, part, contextentity, last=False): # XXX deprecates last argument?
         if isinstance(part, Entity):
-            self.w(part.view('breadcrumbs'))
+            w(part.view('breadcrumbs'))
         elif isinstance(part, tuple):
             url, title = part
             textsize = self._cw.property_value('navigation.short-line-size')
-            self.w(self.link_template % (
+            w(self.link_template % (
                 xml_escape(url), xml_escape(uilib.cut(title, textsize))))
         else:
             textsize = self._cw.property_value('navigation.short-line-size')
-            self.w(uilib.cut(unicode(part), textsize))
+            w(uilib.cut(unicode(part), textsize))
 
 
 class BreadCrumbETypeVComponent(BreadCrumbEntityVComponent):
-    __select__ = multi_lines_rset() & one_etype_rset() & \
-                 adaptable('IBreadCrumbs')
+    __select__ = (basecomponents.HeaderComponent.__select__
+                  & multi_lines_rset() & one_etype_rset()
+                  & adaptable('IBreadCrumbs'))
 
-    def render_breadcrumbs(self, contextentity, path):
+    def render_breadcrumbs(self, w, contextentity, path):
         # XXX hack: only display etype name or first non entity path part
         root = path.pop(0)
         if isinstance(root, Entity):
-            self.w(u'<a href="%s">%s</a>' % (self._cw.build_url(root.__regid__),
-                                             root.dc_type('plural')))
+            w(u'<a href="%s">%s</a>' % (self._cw.build_url(root.__regid__),
+                                        root.dc_type('plural')))
         else:
-            self.wpath_part(root, contextentity, not path)
+            self.wpath_part(w, root, contextentity, not path)
 
 
 class BreadCrumbAnyRSetVComponent(BreadCrumbEntityVComponent):
-    __select__ = any_rset()
+    __select__ = basecomponents.HeaderComponent.__select__ & any_rset()
 
-    def call(self, view=None, first_separator=True):
-        self.w(u'<span id="breadcrumbs" class="pathbar">')
-        if first_separator:
-            self.w(self.separator)
-        self.w(self._cw._('search'))
-        self.w(u'</span>')
+    def render(self, w):
+        w(u'<span id="breadcrumbs" class="pathbar">')
+        if self.first_separator:
+            w(self.separator)
+        w(self._cw._('search'))
+        w(u'</span>')
 
 
 class BreadCrumbView(EntityView):
--- a/web/views/idownloadable.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/idownloadable.py	Wed Oct 13 08:37:21 2010 +0200
@@ -27,7 +27,7 @@
 from cubicweb.selectors import (one_line_rset, is_instance, match_context_prop,
                                 adaptable, has_mimetype)
 from cubicweb.mttransforms import ENGINE
-from cubicweb.web import box, httpcache
+from cubicweb.web import component, httpcache
 from cubicweb.web.views import primary, baseviews
 
 
@@ -42,22 +42,25 @@
     w(u'<a href="%s"><img src="%s" alt="%s"/> %s</a>'
       % (xml_escape(entity.cw_adapt_to('IDownloadable').download_url()),
          req.uiprops['DOWNLOAD_ICON'],
-         _('download icon'), xml_escape(label or entity.dc_title())))
+         req._('download icon'), xml_escape(label or entity.dc_title())))
     w(u'%s</div>' % footer)
     w(u'</div></div>\n')
 
 
-class DownloadBox(box.EntityBoxTemplate):
+class DownloadBox(component.EntityCtxComponent):
     __regid__ = 'download_box'
     # no download box for images
-    # XXX primary_view selector ?
-    __select__ = (one_line_rset() & match_context_prop()
-                  & adaptable('IDownloadable') & ~has_mimetype('image/'))
+    __select__ = (component.EntityCtxComponent.__select__ &
+                  adaptable('IDownloadable') & ~has_mimetype('image/'))
+
     order = 10
+    title = _('download')
 
-    def cell_call(self, row, col, title=None, label=None, **kwargs):
-        entity = self.cw_rset.get_entity(row, col)
-        download_box(self.w, entity, title, label)
+    def render_body(self, w):
+        w(u'<a href="%s"><img src="%s" alt="%s"/> %s</a>'
+          % (xml_escape(self.entity.cw_adapt_to('IDownloadable').download_url()),
+             self._cw.uiprops['DOWNLOAD_ICON'],
+             self._cw._('download icon'), xml_escape(self.entity.dc_title())))
 
 
 class DownloadView(EntityView):
--- a/web/views/management.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/management.py	Wed Oct 13 08:37:21 2010 +0200
@@ -84,7 +84,7 @@
                                          __redirectpath=entity.rest_path())
         field = guess_field(entity.e_schema, self._cw.vreg.schema.rschema('owned_by'))
         form.append_field(field)
-        self.w(form.render(display_progress_div=False))
+        form.render(w=self.w, display_progress_div=False)
 
     def owned_by_information(self, entity):
         ownersrset = entity.related('owned_by')
@@ -154,7 +154,7 @@
         form.append_field(field)
         renderer = self._cw.vreg['formrenderers'].select(
             'htable', self._cw, rset=None, display_progress_div=False)
-        self.w(form.render(renderer=renderer))
+        form.render(w=self.w, renderer=renderer)
 
 
 class ErrorView(AnyRsetView):
@@ -217,7 +217,7 @@
             form.add_hidden('__bugreporting', '1')
             form.form_buttons = [wdgs.SubmitButton(MAIL_SUBMIT_MSGID)]
             form.action = req.build_url('reportbug')
-            w(form.render())
+            form.render(w=w)
 
 
 def exc_message(ex, encoding):
--- a/web/views/navigation.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/navigation.py	Wed Oct 13 08:37:21 2010 +0200
@@ -29,7 +29,7 @@
                                 adaptable, implements)
 from cubicweb.uilib import cut
 from cubicweb.view import EntityAdapter, implements_adapter_compat
-from cubicweb.web.component import EntityVComponent, NavigationComponent
+from cubicweb.web.component import EmptyComponent, EntityCtxComponent, NavigationComponent
 
 
 class PageNavigation(NavigationComponent):
@@ -201,59 +201,55 @@
         raise NotImplementedError
 
 
-class NextPrevNavigationComponent(EntityVComponent):
+class NextPrevNavigationComponent(EntityCtxComponent):
     __regid__ = 'prevnext'
     # register msg not generated since no entity implements IPrevNext in cubicweb
     # itself
-    title = _('contentnavigation_prevnext')
-    help = _('contentnavigation_prevnext_description')
-    __select__ = EntityVComponent.__select__ & adaptable('IPrevNext')
+    help = _('ctxcomponents_prevnext_description')
+    __select__ = EntityCtxComponent.__select__ & adaptable('IPrevNext')
     context = 'navbottom'
     order = 10
 
-    def call(self, view=None):
-        self.cell_call(0, 0, view=view)
+    def init_rendering(self):
+        adapter = self.entity.cw_adapt_to('IPrevNext')
+        self.previous = adapter.previous_entity()
+        self.next = adapter.next_entity()
+        if not (self.previous or self.next):
+            raise EmptyComponent()
 
-    def cell_call(self, row, col, view=None):
-        entity = self.cw_rset.get_entity(row, col)
-        adapter = entity.cw_adapt_to('IPrevNext')
-        previous = adapter.previous_entity()
-        next = adapter.next_entity()
-        if previous or next:
-            textsize = self._cw.property_value('navigation.short-line-size')
-            self.w(u'<div class="prevnext">')
-            if previous:
-                self.previous_div(previous, textsize)
-            if next:
-                self.next_div(next, textsize)
-            self.w(u'</div>')
-            self.w(u'<div class="clear"></div>')
+    def render_body(self, w):
+        w(u'<div class="prevnext">')
+        self.prevnext(w)
+        w(u'</div>')
+        w(u'<div class="clear"></div>')
+
+    def prevnext(self, w):
+        if self.previous:
+            self.prevnext_entity(w, self.previous, 'prev')
+        if self.next:
+            self.prevnext_entity(w, self.next, 'next')
 
-    def previous_div(self, previous, textsize):
-        self.w(u'<div class="previousEntity left">')
-        self.w(self.previous_link(previous, textsize))
-        self.w(u'</div>')
-        self._cw.html_headers.add_raw('<link rel="prev" href="%s" />'
-                                      % xml_escape(previous.absolute_url()))
-
-    def previous_link(self, previous, textsize):
-        return u'<a href="%s" title="%s">&lt;&lt; %s</a>' % (
-            xml_escape(previous.absolute_url()),
-            self._cw._('i18nprevnext_previous'),
-            xml_escape(cut(previous.dc_title(), textsize)))
+    def prevnext_entity(self, w, entity, type):
+        textsize = self._cw.property_value('navigation.short-line-size')
+        if type == 'prev':
+            title = self._cw._('i18nprevnext_previous')
+            icon = u'&lt;&lt; '
+            cssclass = u'previousEntity left'
+        else:
+            title = self._cw._('i18nprevnext_next')
+            icon = u'&gt;&gt; '
+            cssclass = u'nextEntity right'
+        self.prevnext_div(w, type, cssclass, entity.absolute_url(),
+                          title, icon + xml_escape(cut(entity.dc_title(), textsize)))
 
-    def next_div(self, next, textsize):
-        self.w(u'<div class="nextEntity right">')
-        self.w(self.next_link(next, textsize))
-        self.w(u'</div>')
-        self._cw.html_headers.add_raw('<link rel="next" href="%s" />'
-                                      % xml_escape(next.absolute_url()))
-
-    def next_link(self, next, textsize):
-        return u'<a href="%s" title="%s">%s &gt;&gt;</a>' % (
-            xml_escape(next.absolute_url()),
-            self._cw._('i18nprevnext_next'),
-            xml_escape(cut(next.dc_title(), textsize)))
+    def prevnext_div(self, w, type, cssclass, url, title, content):
+        w(u'<div class="%s">' % cssclass)
+        w(u'<a href="%s" title="%s">%s</a>' % (xml_escape(url),
+                                               xml_escape(title),
+                                               content))
+        w(u'</div>')
+        self._cw.html_headers.add_raw('<link rel="%s" href="%s" />' % (
+              type, xml_escape(url)))
 
 
 def do_paginate(view, rset=None, w=None, show_all_option=True, page_size=None):
--- a/web/views/primary.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/primary.py	Wed Oct 13 08:37:21 2010 +0200
@@ -25,10 +25,11 @@
 from logilab.mtconverter import xml_escape
 
 from cubicweb import Unauthorized, NoSelectableObject
-from cubicweb.selectors import match_kwargs
+from cubicweb.utils import support_args
+from cubicweb.selectors import match_kwargs, match_context
 from cubicweb.view import EntityView
-from cubicweb.schema import VIRTUAL_RTYPES, display_name
-from cubicweb.web import uicfg
+from cubicweb.schema import META_RTYPES, VIRTUAL_RTYPES, display_name
+from cubicweb.web import uicfg, component
 
 
 class PrimaryView(EntityView):
@@ -88,7 +89,7 @@
 
     def content_navigation_components(self, context):
         self.w(u'<div class="%s">' % context)
-        for comp in self._cw.vreg['contentnavigation'].poss_visible_objects(
+        for comp in self._cw.vreg['ctxcomponents'].poss_visible_objects(
             self._cw, rset=self.cw_rset, row=self.cw_row, view=self, context=context):
             try:
                 comp.render(w=self.w, row=self.cw_row, view=self)
@@ -142,20 +143,20 @@
         if display_attributes:
             self.w(u'<table>')
             for rschema, role, dispctrl, value in display_attributes:
-                try:
-                    self._render_attribute(dispctrl, rschema, value,
-                                           role=role, table=True)
+                if not hasattr(self, '_render_attribute'):
+                    label = self._rel_label(entity, rschema, role, dispctrl)
+                    self.render_attribute(label, value, table=True)
+                elif support_args(self._render_attribute, 'dispctrl'):
                     warn('[3.9] _render_attribute prototype has changed and '
                          'renamed to render_attribute, please update %s'
                          % self.__class___, DeprecationWarning)
-                except TypeError:
+                    self._render_attribute(dispctrl, rschema, value, role=role,
+                                           table=True)
+                else:
                     self._render_attribute(rschema, value, role=role, table=True)
                     warn('[3.6] _render_attribute prototype has changed and '
                          'renamed to render_attribute, please update %s'
                          % self.__class___, DeprecationWarning)
-                except AttributeError:
-                    label = self._rel_label(entity, rschema, role, dispctrl)
-                    self.render_attribute(label, value, table=True)
             self.w(u'</table>')
 
     def render_attribute(self, label, value, table=False):
@@ -179,12 +180,12 @@
                 if not rset:
                     continue
                 if hasattr(self, '_render_relation'):
-                    try:
+                    if not support_args(self._render_relation, 'showlabel'):
                         self._render_relation(dispctrl, rset, 'autolimited')
                         warn('[3.9] _render_relation prototype has changed and has '
                              'been renamed to render_relation, please update %s'
                              % self.__class__, DeprecationWarning)
-                    except TypeError:
+                    else:
                         self._render_relation(rset, dispctrl, 'autolimited',
                                               self.show_rel_label)
                         warn('[3.6] _render_relation prototype has changed and has '
@@ -217,42 +218,45 @@
                 try:
                     label, rset, vid, dispctrl  = box
                 except ValueError:
-                    warn('[3.5] box views should now be defined as a 4-uple (label, rset, vid, dispctrl), '
-                         'please update %s' % self.__class__.__name__,
-                         DeprecationWarning)
                     label, rset, vid = box
                     dispctrl = {}
+                warn('[3.10] box views should now be a RsetBox instance, '
+                     'please update %s' % self.__class__.__name__,
+                     DeprecationWarning)
                 self.w(u'<div class="sideBox">')
                 self.wview(vid, rset, title=label, initargs={'dispctrl': dispctrl})
                 self.w(u'</div>')
             else:
-                try:
-                    box.render(w=self.w, row=self.cw_row)
-                except NotImplementedError:
-                    # much probably a context insensitive box, which only implements
-                    # .call() and not cell_call()
+                 try:
+                     box.render(w=self.w, row=self.cw_row)
+                 except NotImplementedError:
+                    # much probably a context insensitive box, which only
+                    # implements .call() and not cell_call()
+                    # XXX shouldn't occurs with the new box system
                     box.render(w=self.w)
 
     def _prepare_side_boxes(self, entity):
         sideboxes = []
+        boxesreg = self._cw.vreg['ctxcomponents']
         for rschema, tschemas, role, dispctrl in self._section_def(entity, 'sideboxes'):
             rset = self._relation_rset(entity, rschema, role, dispctrl)
             if not rset:
                 continue
-            label = display_name(self._cw, rschema.type, role)
-            vid = dispctrl.get('vid', 'sidebox')
-            sideboxes.append( (label, rset, vid, dispctrl) )
-        sideboxes += self._cw.vreg['boxes'].poss_visible_objects(
-            self._cw, rset=self.cw_rset, row=self.cw_row, view=self,
-            context='incontext')
+            label = self._rel_label(entity, rschema, role, dispctrl)
+            vid = dispctrl.get('vid', 'autolimited')
+            box = boxesreg.select('rsetbox', self._cw, rset=rset,
+                                  vid=vid, title=label, dispctrl=dispctrl,
+                                  context='incontext')
+            sideboxes.append(box)
+        sideboxes += boxesreg.poss_visible_objects(
+             self._cw, rset=self.cw_rset, row=self.cw_row, view=self,
+             context='incontext')
         # XXX since we've two sorted list, it may be worth using bisect
         def get_order(x):
-            if isinstance(x, tuple):
-                # x is a view box (label, rset, vid, dispctrl)
-                # default to 1000 so view boxes occurs after component boxes
-                return x[-1].get('order', 1000)
-            # x is a component box
-            return x.cw_propval('order')
+            if 'order' in x.cw_property_defs:
+                return x.cw_propval('order')
+            # default to 9999 so view boxes occurs after component boxes
+            return x.cw_extra_kwargs.get('dispctrl', {}).get('order', 9999)
         return sorted(sideboxes, key=get_order)
 
     def _section_def(self, entity, where):
@@ -379,11 +383,19 @@
                 self.wview('autolimited', rset, initargs={'dispctrl': dispctrl})
 
 
+
+class ToolbarLayout(component.Layout):
+    __select__ = match_context('ctxtoolbar')
+
+    def render(self, w):
+        if self.init_rendering():
+            self.cw_extra_kwargs['view'].render_body(w)
+
 ## default primary ui configuration ###########################################
 
 _pvs = uicfg.primaryview_section
-for rtype in ('eid', 'creation_date', 'modification_date', 'cwuri',
-              'is', 'is_instance_of', 'identity', 'owned_by', 'created_by',
-              'require_permission', 'see_also'):
+for rtype in META_RTYPES:
     _pvs.tag_subject_of(('*', rtype, '*'), 'hidden')
     _pvs.tag_object_of(('*', rtype, '*'), 'hidden')
+_pvs.tag_subject_of(('*', 'require_permission', '*'), 'hidden')
+_pvs.tag_object_of(('*', 'require_permission', '*'), 'hidden')
--- a/web/views/sessions.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/sessions.py	Wed Oct 13 08:37:21 2010 +0200
@@ -51,9 +51,6 @@
         if not sessionid in self._sessions:
             raise InvalidSession()
         session = self._sessions[sessionid]
-        if self.has_expired(session):
-            self.close_session(session)
-            raise InvalidSession()
         try:
             user = self.authmanager.validate_session(req, session)
         except InvalidSession:
--- a/web/views/startup.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/startup.py	Wed Oct 13 08:37:21 2010 +0200
@@ -159,15 +159,14 @@
             url = self._cw.build_url(etype)
             etypelink = u'&#160;<a href="%s">%s</a> (%d)' % (
                 xml_escape(url), label, nb)
-            yield (label, etypelink, self.add_entity_link(eschema, req))
+            if eschema.has_perm(req, 'add'):
+                yield (label, etypelink, self.add_entity_link(etype))
 
-    def add_entity_link(self, eschema, req):
-        """creates a [+] link for adding an entity if user has permission to do so"""
-        if not eschema.has_perm(req, 'add'):
-            return u''
+    def add_entity_link(self, etype):
+        """creates a [+] link for adding an entity"""
+        url = self._cw.vreg["etypes"].etype_class(etype).cw_create_url(self._cw)
         return u'[<a href="%s" title="%s">+</a>]' % (
-            xml_escape(self.create_url(eschema.type)),
-            self._cw.__('add a %s' % eschema))
+            xml_escape(url), self._cw.__('add a %s' % etype))
 
 
 class IndexView(ManageView):
--- a/web/views/tabs.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/tabs.py	Wed Oct 13 08:37:21 2010 +0200
@@ -15,9 +15,7 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""base classes to handle tabbed views
-
-"""
+"""base classes to handle tabbed views"""
 
 __docformat__ = "restructuredtext en"
 
--- a/web/views/treeview.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/treeview.py	Wed Oct 13 08:37:21 2010 +0200
@@ -110,7 +110,7 @@
     __regid__ = 'treeview'
     itemvid = 'treeitemview'
     subvid = 'oneline'
-    css_classes = 'treeview widget'
+    cssclass = 'treeview widget'
     title = _('tree view')
 
     def _init_params(self, subvid, treeid, initial_load, initial_thru_ajax, morekwargs):
@@ -144,7 +144,7 @@
         if toplevel:
             self._init_headers(treeid, toplevel_thru_ajax)
             ulid = ' id="tree-%s"' % treeid
-        self.w(u'<ul%s class="%s">' % (ulid, self.css_classes))
+        self.w(u'<ul%s class="%s">' % (ulid, self.cssclass))
         # XXX force sorting on x.sortvalue() (which return dc_title by default)
         # we need proper ITree & co specification to avoid this.
         # (pb when type ambiguity at the other side of the tree relation,
@@ -171,7 +171,7 @@
     """specific version of the treeview to display file trees
     """
     __regid__ = 'filetree'
-    css_classes = 'treeview widget filetree'
+    cssclass = 'treeview widget filetree'
     title = _('file tree view')
 
     def call(self, subvid=None, treeid=None, initial_load=True, **kwargs):
--- a/web/views/wdoc.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/wdoc.py	Wed Oct 13 08:37:21 2010 +0200
@@ -283,7 +283,7 @@
 
     category = 'footer'
     order = 2
-    title = _('about this site')
+    title = _('About this site')
 
     def url(self):
         return self._cw.build_url('doc/about')
--- a/web/views/workflow.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/workflow.py	Wed Oct 13 08:37:21 2010 +0200
@@ -25,6 +25,7 @@
 _ = unicode
 
 import os
+from warnings import warn
 
 from logilab.mtconverter import xml_escape
 from logilab.common.graph import escape
@@ -160,15 +161,21 @@
                        displaycols=displaycols, headers=headers)
 
 
-class WFHistoryVComponent(component.EntityVComponent):
+class WFHistoryVComponent(component.EntityCtxComponent):
     """display the workflow history for entities supporting it"""
     __regid__ = 'wfhistory'
-    __select__ = component.EntityVComponent.__select__ & WFHistoryView.__select__
+    __select__ = component.EntityCtxComponent.__select__ & WFHistoryView.__select__
     context = 'navcontentbottom'
     title = _('Workflow history')
 
-    def cell_call(self, row, col, view=None):
-        self.wview('wfhistory', self.cw_rset, row=row, col=col, view=view)
+    def render_body(self, w):
+        if hasattr(self, 'cell_call'):
+            warn('[3.10] %s should now implement render_body instead of cell_call'
+                 % self.__class__, DeprecationWarning)
+            self.w = w
+            self.cell_call(self.entity.cw_row, self.entity.cw_col)
+        else:
+            self.entity.view('wfhistory', w=w)
 
 
 # workflow actions #############################################################
--- a/web/views/xmlrss.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/views/xmlrss.py	Wed Oct 13 08:37:21 2010 +0200
@@ -29,7 +29,7 @@
 from cubicweb.view import EntityView, EntityAdapter, AnyRsetView, Component
 from cubicweb.view import implements_adapter_compat
 from cubicweb.uilib import simple_sgml_tag
-from cubicweb.web import httpcache, box
+from cubicweb.web import httpcache, component
 
 
 # base xml views ##############################################################
@@ -68,7 +68,7 @@
                 value = entity.eid
             else:
                 try:
-                    value = entity[attr]
+                    value = entity.cw_attr_cache[attr]
                 except KeyError:
                     # Bytes
                     continue
@@ -148,25 +148,25 @@
         return entity.cw_adapt_to('IFeed').rss_feed_url()
 
 
-class RSSIconBox(box.BoxTemplate):
+class RSSIconBox(component.CtxComponent):
     """just display the RSS icon on uniform result set"""
     __regid__ = 'rss'
-    __select__ = (box.BoxTemplate.__select__
+    __select__ = (component.CtxComponent.__select__
                   & appobject_selectable('components', 'rss_feed_url'))
 
     visible = False
     order = 999
 
-    def call(self, **kwargs):
+    def render(self, w, **kwargs):
         try:
             rss = self._cw.uiprops['RSS_LOGO']
         except KeyError:
             self.error('missing RSS_LOGO external resource')
             return
         urlgetter = self._cw.vreg['components'].select('rss_feed_url', self._cw,
-                                                   rset=self.cw_rset)
+                                                       rset=self.cw_rset)
         url = urlgetter.feed_url()
-        self.w(u'<a href="%s"><img src="%s" alt="rss"/></a>\n' % (xml_escape(url), rss))
+        w(u'<a href="%s"><img src="%s" alt="rss"/></a>\n' % (xml_escape(url), rss))
 
 
 class RSSView(XMLView):
--- a/web/wdoc/ChangeLog_en	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/wdoc/ChangeLog_en	Wed Oct 13 08:37:21 2010 +0200
@@ -4,7 +4,13 @@
 .. _SPARQL: http://www.w3.org/TR/rdf-sparql-query/
 .. _schema: schema
 .. _OWL: http://www.w3.org/TR/owl-features/
-.. _pdfexport: http://www.cubicweb.org/project/cubicweb-pdfexport
+.. _guide: http://www.learningjquery.com/2010/06/autocomplete-migration-guide
+
+  --  3.10.0
+  * upgraded jQuery and jQuery UI respectively to version 1.4.2 and 1.8. Removed
+    jquery.autocomplete.js since jQuery UI provides its own autocomplete
+    plugin. It's not backward compatible but required changes should be minimal
+    and this guide_ describes how to migrate from one version to another.
 
 2010-06-11  --  3.8.4
    * support full text prefix search for instances using postgres > 8.4 as database: try it
--- a/web/wdoc/ChangeLog_fr	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/wdoc/ChangeLog_fr	Wed Oct 13 08:37:21 2010 +0200
@@ -5,6 +5,12 @@
 .. _schema: schema
 .. _OWL: http://www.w3.org/TR/owl-features/
 .. _pdfexport: http://www.cubicweb.org/project/cubicweb-pdfexport
+.. _guide: http://www.learningjquery.com/2010/06/autocomplete-migration-guide
+
+  --  3.10.0
+  * passage à jQuery 1.4.2, et jQuery UI 1.8 : jquery.autocomplete.js disparait
+    car intégré à jQuery UI. L'API n'est pas exactement la même mais ce guide_
+    expliquer comment migrer de l'un vers l'autre.
 
 2010-06-11  --  3.8.4
    * support pour la recherche de préfixe pour les instances utilisant postgres > 8.4 :
--- a/web/webconfig.py	Wed Oct 13 08:37:09 2010 +0200
+++ b/web/webconfig.py	Wed Oct 13 08:37:21 2010 +0200
@@ -135,17 +135,6 @@
           "Should be 0 or greater than repository\'s session-time.",
           'group': 'web', 'level': 2,
           }),
-        ('cleanup-session-time',
-         {'type' : 'time',
-          'default': '24h',
-          'help': 'duration of inactivity after which a connection '
-          'will be closed, to limit memory consumption (avoid sessions that '
-          'never expire and cause memory leak when http-session-time is 0). '
-          'So even if http-session-time is 0 and the user don\'t close his '
-          'browser, he will have to reauthenticate after this time of '
-          'inactivity. Default to 24h.',
-          'group': 'web', 'level': 3,
-          }),
         ('cleanup-anonymous-session-time',
          {'type' : 'time',
           'default': '5min',