[pkg-horde] [SCM] Debian Horde Packages repository: turba2 package branch, upstream+patches, updated. b41014692822fd7cb0cf734e0dedcf91b09df1fc

Gregory Colpart reg at foulademer.gcolpart.com
Wed Oct 21 00:07:31 UTC 2009


The following commit has been merged in the upstream+patches branch:
commit b41014692822fd7cb0cf734e0dedcf91b09df1fc
Author: Gregory Colpart <reg at foulademer.gcolpart.com>
Date:   Wed Oct 21 01:43:45 2009 +0200

    Import new upstream sources
    
    Summary: Import new upstream sources
    Keywords:
    
    Imported turba-h3-2.3.2
    into Git repository

diff --git a/LICENSE b/LICENSE
index 83cf4a4..85f58ff 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 Version 1.0
 
-Copyright (c) 2000-2002 The Horde Project. All rights reserved.
+Copyright 2000-2009 The Horde Project. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -48,4 +48,4 @@ individuals on behalf of the Horde Project. For more information on
 the Horde Project, please see <http://www.horde.org/>.
 
 ----------
-$Horde: turba/LICENSE,v 1.1.2.4 2007/12/20 14:34:23 jan Exp $
+$Horde: turba/LICENSE,v 1.1.2.5 2009/01/06 15:27:38 jan Exp $
diff --git a/add.php b/add.php
index e98496b..61ff020 100644
--- a/add.php
+++ b/add.php
@@ -2,9 +2,9 @@
 /**
  * The Turba script to add a new entry into an address book.
  *
- * $Horde: turba/add.php,v 1.54.4.14 2008/01/02 11:32:38 jan Exp $
+ * $Horde: turba/add.php,v 1.54.4.15 2009/01/06 15:27:38 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you did
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/addressbooks/create.php b/addressbooks/create.php
index 23dfed5..45f452f 100644
--- a/addressbooks/create.php
+++ b/addressbooks/create.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/addressbooks/create.php,v 1.1.2.2 2008/01/02 11:32:39 jan Exp $
+ * $Horde: turba/addressbooks/create.php,v 1.1.2.3 2009/01/06 15:27:40 jan Exp $
  *
- * Copyright 2001-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL). If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/addressbooks/delete.php b/addressbooks/delete.php
index 5c291cc..32f4ff4 100644
--- a/addressbooks/delete.php
+++ b/addressbooks/delete.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/addressbooks/delete.php,v 1.1.2.2 2008/01/02 11:32:39 jan Exp $
+ * $Horde: turba/addressbooks/delete.php,v 1.1.2.3 2009/01/06 15:27:41 jan Exp $
  *
- * Copyright 2001-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL). If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/addressbooks/edit.php b/addressbooks/edit.php
index d54ccbc..d1f08ee 100644
--- a/addressbooks/edit.php
+++ b/addressbooks/edit.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/addressbooks/edit.php,v 1.1.2.2 2008/01/02 11:32:39 jan Exp $
+ * $Horde: turba/addressbooks/edit.php,v 1.1.2.3 2009/01/06 15:27:41 jan Exp $
  *
- * Copyright 2001-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL). If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/addressbooks/index.php b/addressbooks/index.php
index 75551ed..e7d68a7 100644
--- a/addressbooks/index.php
+++ b/addressbooks/index.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/addressbooks/index.php,v 1.1.2.4 2008/04/22 15:53:05 chuck Exp $
+ * $Horde: turba/addressbooks/index.php,v 1.1.2.5 2009/01/06 15:27:41 jan Exp $
  *
- * Copyright 2001-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL). If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/browse.php b/browse.php
index cf0fafe..2d17ca8 100644
--- a/browse.php
+++ b/browse.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/browse.php,v 1.76.2.28 2008/01/11 03:48:31 chuck Exp $
+ * $Horde: turba/browse.php,v 1.76.2.29 2009/01/06 15:27:38 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you did
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/config/sources.php.dist b/config/sources.php.dist
index bf8ab52..ae62dce 100644
--- a/config/sources.php.dist
+++ b/config/sources.php.dist
@@ -1,6 +1,6 @@
 <?php
 /**
- * $Horde: turba/config/sources.php.dist,v 1.97.6.38 2008/11/12 06:29:26 wrobel Exp $
+ * $Horde: turba/config/sources.php.dist,v 1.97.6.41 2009/08/05 21:06:10 jan Exp $
  *
  * This file is where you specify the sources of contacts available to users
  * at your installation. It contains a large number of EXAMPLES. Please
@@ -60,16 +60,46 @@
  *   dn:            Only applies to LDAP servers. Defines the list of LDAP
  *                  attributes that build a valid DN.
  *
+ *   root:          Only applies to LDAP servers. Defines the base DN where to
+ *                  start the search, i.e. dc=example,dc=com.
+ *
+ *   bind_dn:       Only applies to LDAP servers which do not allow anonymous
+ *                  connections. Active Directory servers do not allow it by
+ *                  default, so before using one as a Turba source, you must
+ *                  create a "rightless" user, which is only allowed to connect
+ *                  to the server, and set the bind_dn parameter like
+ *                  'rightless at example.com' (not cn=rightless,dc=example,dc=com)
+ *
+ *   bind_password: Only applies to LDAP servers which do not allow anonymous
+ *                  connection. You should set this to the cleartext password
+ *                  for the user specified in 'bind_dn'.
+ *
+ *   referrals:     Only applies to LDAP servers. If set, should be 0 or 1.
+ *                  See the LDAP documentation about the corresponding
+ *                  parameter REFERRALS. Windows 2003 Server requires that you
+ *                  set this parameter to 0.
+ *
+ *   sizelimit:     Only applies to LDAP servers. If set, limit the search to
+ *                  the specified number of entries. Value 0 or no value means
+ *                  no limit. Keep in mind that servers can impose their own
+ *                  search limits.
+ *
  *   objectclass:   Only applies to LDAP servers. Defines a list of
- *                  objectclasses that contacts must belong to, and
- *                  that new objects will be created with.
+ *                  objectclasses that contacts must belong to, and that new
+ *                  objects will be created with.
  *
  *   filter:        Filter helps to filter your result based on certain
  *                  condition in SQL and LDAP backends. A filter can be
  *                  specified to avoid some unwanted data. For example, if the
  *                  source is an external sql database, to select records with
- *                  the delete flag = 0:
- *                  'filter' = 'deleted=0'
+ *                  the delete flag = 0: 'filter' => 'deleted=0'.
+ *                  Don't enclose filter in brackets - this will done
+ *                  automatically. Also keep in mind that a full filter line
+ *                  will be built from 'filter' and 'objectclass' parameters.
+ *
+ *   version:       Only applies to LDAP servers. If set, specify LDAP server
+ *                  version, can be 2 or 3. Active Directory servers
+ *                  require version 3.
  *
  * map:         This is a list of mappings from the Turba attribute names (on
  *              the left) to the attribute names by which they are known in
@@ -294,8 +324,12 @@ $cfgSources['localsql'] = array(
 //         'tls' => false,
 //         'root' => 'dc=example,dc=com',
 //         'bind_dn' => 'cn=admin,ou=users,dc=example,dc=com',
+//         // For Active Directory:
+//         // 'bind_dn' => 'username at example.com',
 //         'bind_password' => '********',
 //         'sizelimit' => 200,
+//         // For Active Directory:
+//         // 'sizelimit' => 0,
 //         'dn' => array('cn'),
 //         'objectclass' => array('top',
 //                                'person',
@@ -304,7 +338,14 @@ $cfgSources['localsql'] = array(
 //                                // Add 'turbaContact' to this array if using
 //                                // 'turbaType' attribute below, and 'calEntry'
 //                                // if using 'freebusyUrl'.
+//         // For Active Directory:
+//         // 'objectclass' => array('organizationalPerson',
+//         //                        'user',
+//         //                        'group',
+//         //                        'contact'),
 //         'scope' => 'one',
+//         // For Active Directory:
+//         // 'scope' => 'sub',
 //         'charset' => 'utf-8',
 //         // Consult the LDAP schema to verify that all required attributes for
 //         // an entry are set and add them if needed.
@@ -315,10 +356,18 @@ $cfgSources['localsql'] = array(
 //         // field is assumed to have postalAddress syntax; otherwise the schema
 //         // is consulted for the syntax to use.
 //         'checksyntax' => false,
-//         'version' => 3
+//         'version' => 3,
+//
+//         // For Active Directory you probably want to also set the following
+//         // parameters:
+//         // 'deref' => LDAP_DEREF_ALWAYS,
+//         // 'filter' => '&(SAMAccountName=*)(mail=*)',
+//         // 'referrals' => 0,
 //     ),
 //     'map' => array(
 //         '__key' => 'dn',
+//
+//         // Remove this mapping if using Active Directory server:
 //         '__uid' => 'uid',
 //
 //         // From horde.schema.  Make sure you have 'turbaContact' objectClass
@@ -335,6 +384,13 @@ $cfgSources['localsql'] = array(
 //
 //         // From rfc2739.schema:
 //         // 'freebusyUrl' => 'calFBURL',
+//
+//         // For Active Directory servers:
+//         // 'name' => 'displayname',
+//         // 'title' => 'title',
+//         // 'cellPhone' => 'mobile',
+//         // 'department' => 'department',
+//         // 'company' => 'company',
 //     ),
 //     'search' => array(
 //         'name',
@@ -350,6 +406,11 @@ $cfgSources['localsql'] = array(
 //     'approximate' => array(
 //         'cn',
 //     ),
+//     // For Active Directory servers:
+//     // 'approximate' => array(
+//     //     'displayname',
+//     //     'samaccountname',
+//     // ),
 //     'export' => true,
 //     'browse' => true,
 // );
diff --git a/contact.php b/contact.php
index 1b43fd7..643f018 100644
--- a/contact.php
+++ b/contact.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/contact.php,v 1.8.2.6 2008/07/10 22:52:41 jan Exp $
+ * $Horde: turba/contact.php,v 1.8.2.7 2009/01/06 15:27:38 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/data.php b/data.php
index d6c867d..5b481bb 100644
--- a/data.php
+++ b/data.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/data.php,v 1.70.4.20 2008/08/11 12:50:18 jan Exp $
+ * $Horde: turba/data.php,v 1.70.4.21 2009/01/06 15:27:38 jan Exp $
  *
- * Copyright 2001-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/delete.php b/delete.php
index 352edd4..f32c356 100644
--- a/delete.php
+++ b/delete.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/delete.php,v 1.29.4.7 2008/01/02 11:32:38 jan Exp $
+ * $Horde: turba/delete.php,v 1.29.4.8 2009/01/06 15:27:38 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/deletefile.php b/deletefile.php
index 4809926..408b593 100644
--- a/deletefile.php
+++ b/deletefile.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/deletefile.php,v 1.6.2.2 2008/01/02 11:32:38 jan Exp $
+ * $Horde: turba/deletefile.php,v 1.6.2.3 2009/01/06 15:27:38 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/docs/CHANGES b/docs/CHANGES
index a8a3a27..a89ee54 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,4 +1,20 @@
 ------
+v2.3.2
+------
+
+[mms] Upgrade prototype.js to v1.6.1.
+[jan] Fix synchronization with output compression enabled (Bug #7769).
+[mjr] Fix contacts being deleted during synchronization when moved from one
+      address book to another (ryu at ryux.org, Bug #8487).
+[mjr] Add new API method for retrieving the default share for a source.
+[jan] Don't overwrite the compositing fields, when importing composite fields.
+[cjh] Fix searches for multiple strict fields and at least one non-strict field
+      (tinu at humbapa.ch, Bug #7876).
+[mjr] Specific timeobject categories are now only advertised when they are
+      present in a configured source.
+
+
+------
 v2.3.1
 ------
 
diff --git a/docs/CREDITS b/docs/CREDITS
index c56d36b..dbfd5e1 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -31,6 +31,7 @@ Czech                   Pavel Chytil <pchytil at asp.ogi.edu>
                         Jan Krivanek <honza at atack.cz>
 Danish                  Martin List-Petersen <martin at list-petersen.dk>
                         Brian Truelsen <horde+i18n at briantruelsen.dk>
+                        Niels Baggesen <nba at users.sourceforge.net>
 Dutch                   Jan Kuipers <jrkuipers at lauwerscollege.nl>
                         Han Spruyt <han.spruyt at ijsselgroep.nl>
 Estonian                Toomas Aas <toomas.aas at raad.tartu.ee>
diff --git a/docs/RELEASE_NOTES b/docs/RELEASE_NOTES
index 6c08eb8..0742b00 100644
--- a/docs/RELEASE_NOTES
+++ b/docs/RELEASE_NOTES
@@ -1,48 +1,35 @@
 <?php
 /**
- * Release focus. Possible values:
- * 0 - N/A
- * 1 - Initial freshmeat announcement
- * 2 - Documentation
- * 3 - Code cleanup
- * 4 - Minor feature enhancements
- * 5 - Major feature enhancements
- * 6 - Minor bugfixes
- * 7 - Major bugfixes
- * 8 - Minor security fixes
- * 9 - Major security fixes
+ * Release focus. Possible values (multiple possible with arrays):
+ * Horde_Release::FOCUS_INITIAL - Initial announcement
+ * Horde_Release::FOCUS_MINORFEATURE - Minor feature enhancement
+ * Horde_Release::FOCUS_MAJORFEATURE - Major feature enhancement
+ * Horde_Release::FOCUS_MINORBUG - Minor bugfixes
+ * Horde_Release::FOCUS_MAJORBUG - Major bugfixes
+ * Horde_Release::FOCUS_MINORSECURITY - Minor security fixes
+ * Horde_Release::FOCUS_MAJORSECURITY - Major security fixes
+ * Horde_Release::FOCUS_DOCS - Documentation improvements
  */
-$this->notes['fm']['focus'] = 8;
+$this->notes['fm']['focus'] = Horde_Release::FOCUS_MINORBUG;
 
 /* Mailing list release notes. */
 $this->notes['ml']['changes'] = <<<ML
 The Horde Team is pleased to announce the final release of the Turba Contact
-Manager version H3 (2.3.1). The original release was packaged with the wrong
-name; this second release of 2.3.1 has no changes to the package or the code,
-only to the version name.
-
-This is a minor security release that fixes unescaped output in the test
-script. All users are encouraged to upgrade to this release. In addition all
-users are encouraged to disable test.php in production, per the install
-documentation.
+Manager version H3 (2.3.2).
 
 Turba is the Horde contact management application. It is a production level
 address book, and makes heavy use of the Horde framework to provide
 integration with IMP and other Horde applications. It supports SQL, LDAP,
 Kolab, and IMSP address books.
 
-The major changes compared to the Turba version H3 (2.3) are:
-    * SECURITY: Escape output in test.php
-    * A SquirrelMail contact import script.
-    * Kolab fixes for free/busy URLs and photos.
-    * prototype.js has been upgraded to 1.6.0.3.
+The major changes compared to the Turba version H3 (2.3.1) are:
+    * Improved synchronization support.
+    * Other minor bugfixes and improvements.
 ML;
 
 /* Freshmeat release notes, not more than 600 characters. */
 $this->notes['fm']['changes'] = <<<FM
-This release fixes unescaped output in a utility test script. In addition, an
-import script for SquirrelMail contacts has been added, several Kolab issues
-have been fixed, and prototype.js has been upgraded to 1.6.0.3.
+Synchronization support has been improved. Other minor bugfixes and improvements have been made.
 FM;
 
 $this->notes['name'] = 'Turba';
diff --git a/docs/UPGRADING b/docs/UPGRADING
index 24f5648..71e1906 100644
--- a/docs/UPGRADING
+++ b/docs/UPGRADING
@@ -2,8 +2,8 @@
  Upgrading Turba
 =================
 
-:Last update:   $Date: 2008/11/14 17:27:39 $
-:Revision:      $Revision: 1.3.6.27 $
+:Last update:   $Date: 2009/04/16 21:57:35 $
+:Revision:      $Revision: 1.3.6.28 $
 :Contact:       turba at lists.horde.org
 
 
@@ -23,7 +23,7 @@ Some fields in the SQL share driver tables have been changed. Execute the
 provided SQL script to update your database if you are using the native SQL
 share driver.
 
-   mysql --user=root --password=<MySQL-root-password>  <db name> < scripts/upgrade/2.2.1_to_2.3.sql
+   mysql --user=root --password=<MySQL-root-password>  <db name> < scripts/upgrades/2.2.1_to_2.3.sql
 
 
 New fields
@@ -66,7 +66,7 @@ variables at the top of the script ``$db_user``, ``$db_pass`` and
 ``$db_table`` to fit your current Turba installation. You can then run the
 script to see how the data //would// be changed::
 
-   php scripts/upgrade/2.1_to_2.2_sql_schema.php
+   php scripts/upgrades/2.1_to_2.2_sql_schema.php
 
 If you are happy with the results, you can edit the script again and change
 the ``$for_real`` variable::
diff --git a/edit.php b/edit.php
index 41cd0f8..68b51d5 100644
--- a/edit.php
+++ b/edit.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/edit.php,v 1.70.4.10 2008/01/02 11:32:38 jan Exp $
+ * $Horde: turba/edit.php,v 1.70.4.11 2009/01/06 15:27:38 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/index.php b/index.php
index 8ce6784..16ac14a 100644
--- a/index.php
+++ b/index.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/index.php,v 1.29.10.11 2008/01/11 03:48:31 chuck Exp $
+ * $Horde: turba/index.php,v 1.29.10.12 2009/01/06 15:27:39 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you did
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/js/prototype.js b/js/prototype.js
index 3c2493f..74bee61 100644
--- a/js/prototype.js
+++ b/js/prototype.js
@@ -1 +1 @@
-var Prototype={Version:"1.6.0.3",Browser:{IE:!!(window.attachEvent&&navigator.userAgent.indexOf("Opera")===-1),Opera:navigator.userAgent.indexOf("Opera")>-1,WebKit:navigator.userAgent.indexOf("AppleWebKit/")>-1,Gecko:navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("KHTML")===-1,MobileSafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/)},BrowserFeatures:{XPath:!!document.evaluate,SelectorsAPI:!!document.querySelector,ElementExtensions:!!window.HTMLElement,SpecificElementExtensions:document.createElement("div")["__proto__"]&&document.createElement("div")["__proto__"]!==document.createElement("form")["__proto__"]},ScriptFragment:"<script[^>]*>([\\S\\s]*?)<\/script>",JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,emptyFunction:function(){},K:function(a){return a}};if(Prototype.Browser.MobileSafari){Prototype.BrowserFeatures.SpecificElementExtensions=false}var Class={create:function(){var e=null,d=$A(arguments);if(Object.isFunction(d[0])){e=d.shift()}function a(){this.initialize.apply(this,arguments)}Object.extend(a,Class.Methods);a.superclass=e;a.subclasses=[];if(e){var b=function(){};b.prototype=e.prototype;a.prototype=new b;e.subclasses.push(a)}for(var c=0;c<d.length;c++){a.addMethods(d[c])}if(!a.prototype.initialize){a.prototype.initialize=Prototype.emptyFunction}a.prototype.constructor=a;return a}};Class.Methods={addMethods:function(g){var c=this.superclass&&this.superclass.prototype;var b=Object.keys(g);if(!Object.keys({toString:true}).length){b.push("toString","valueOf")}for(var a=0,d=b.length;a<d;a++){var f=b[a],e=g[f];if(c&&Object.isFunction(e)&&e.argumentNames().first()=="$super"){var h=e;e=(function(i){return function(){return c[i].apply(this,arguments)}})(f).wrap(h);e.valueOf=h.valueOf.bind(h);e.toString=h.toString.bind(h)}this.prototype[f]=e}return this}};var Abstract={};Object.extend=function(a,c){for(var b in c){a[b]=c[b]}return a};Object.extend(Object,{inspect:function(a){try{if(Object.isUndefined(a)){return"undefined"}if(a===null){return"null"}return a.inspect?a.inspect():String(a)}catch(b){if(b instanceof RangeError){return"..."}throw b}},toJSON:function(a){var c=typeof a;switch(c){case"undefined":case"function":case"unknown":return;case"boolean":return a.toString()}if(a===null){return"null"}if(a.toJSON){return a.toJSON()}if(Object.isElement(a)){return}var b=[];for(var e in a){var d=Object.toJSON(a[e]);if(!Object.isUndefined(d)){b.push(e.toJSON()+": "+d)}}return"{"+b.join(", ")+"}"},toQueryString:function(a){return $H(a).toQueryString()},toHTML:function(a){return a&&a.toHTML?a.toHTML():String.interpret(a)},keys:function(a){var b=[];for(var c in a){b.push(c)}return b},values:function(b){var a=[];for(var c in b){a.push(b[c])}return a},clone:function(a){return Object.extend({},a)},isElement:function(a){return!!(a&&a.nodeType==1)},isArray:function(a){return a!=null&&typeof a=="object"&&"splice"in a&&"join"in a},isHash:function(a){return a instanceof Hash},isFunction:function(a){return typeof a=="function"},isString:function(a){return typeof a=="string"},isNumber:function(a){return typeof a=="number"},isUndefined:function(a){return typeof a=="undefined"}});Object.extend(Function.prototype,{argumentNames:function(){var a=this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1].replace(/\s+/g,"").split(",");return a.length==1&&!a[0]?[]:a},bind:function(){if(arguments.length<2&&Object.isUndefined(arguments[0])){return this}var a=this,c=$A(arguments),b=c.shift();return function(){return a.apply(b,c.concat($A(arguments)))}},bindAsEventListener:function(){var a=this,c=$A(arguments),b=c.shift();return function(d){return a.apply(b,[d||window.event].concat(c))}},curry:function(){if(!arguments.length){return this}var a=this,b=$A(arguments);return function(){return a.apply(this,b.concat($A(arguments)))}},delay:function(){var a=this,b=$A(arguments),c=b.shift()*1000;return window.setTimeout(function(){return a.apply(a,b)},c)},defer:function(){var a=[0.01].concat($A(arguments));return this.delay.apply(this,a)},wrap:function(b){var a=this;return function(){return b.apply(this,[a.bind(this)].concat($A(arguments)))}},methodize:function(){if(this._methodized){return this._methodized}var a=this;return this._methodized=function(){return a.apply(null,[this].concat($A(arguments)))}}});Date.prototype.toJSON=function(){return'"'+this.getUTCFullYear()+"-"+(this.getUTCMonth()+1).toPaddedString(2)+"-"+this.getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString(2)+":"+this.getUTCMinutes().toPaddedString(2)+":"+this.getUTCSeconds().toPaddedString(2)+'Z"'};var Try={these:function(){var c;for(var b=0,d=arguments.length;b<d;b++){var a=arguments[b];try{c=a();break}catch(f){}}return c}};RegExp.prototype.match=RegExp.prototype.test;RegExp.escape=function(a){return String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")};var PeriodicalExecuter=Class.create({initialize:function(b,a){this.callback=b;this.frequency=a;this.currentlyExecuting=false;this.registerCallback()},registerCallback:function(){this.timer=setInterval(this.onTimerEvent.bind(this),this.frequency*1000)},execute:function(){this.callback(this)},stop:function(){if(!this.timer){return}clearInterval(this.timer);this.timer=null},onTimerEvent:function(){if(!this.currentlyExecuting){try{this.currentlyExecuting=true;this.execute()}finally{this.currentlyExecuting=false}}}});Object.extend(String,{interpret:function(a){return a==null?"":String(a)},specialChar:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r","\\":"\\\\"}});Object.extend(String.prototype,{gsub:function(e,c){var a="",d=this,b;c=arguments.callee.prepareReplacement(c);while(d.length>0){if(b=d.match(e)){a+=d.slice(0,b.index);a+=String.interpret(c(b));d=d.slice(b.index+b[0].length)}else{a+=d,d=""}}return a},sub:function(c,a,b){a=this.gsub.prepareReplacement(a);b=Object.isUndefined(b)?1:b;return this.gsub(c,function(d){if(--b<0){return d[0]}return a(d)})},scan:function(b,a){this.gsub(b,a);return String(this)},truncate:function(b,a){b=b||30;a=Object.isUndefined(a)?"...":a;return this.length>b?this.slice(0,b-a.length)+a:String(this)},strip:function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")},stripTags:function(){return this.replace(/<\/?[^>]+>/gi,"")},stripScripts:function(){return this.replace(new RegExp(Prototype.ScriptFragment,"img"),"")},extractScripts:function(){var b=new RegExp(Prototype.ScriptFragment,"img");var a=new RegExp(Prototype.ScriptFragment,"im");return(this.match(b)||[]).map(function(c){return(c.match(a)||["",""])[1]})},evalScripts:function(){return this.extractScripts().map(function(script){return eval(script)})},escapeHTML:function(){var a=arguments.callee;a.text.data=this;return a.div.innerHTML},unescapeHTML:function(){var a=new Element("div");a.innerHTML=this.stripTags();return a.childNodes[0]?(a.childNodes.length>1?$A(a.childNodes).inject("",function(b,c){return b+c.nodeValue}):a.childNodes[0].nodeValue):""},toQueryParams:function(b){var a=this.strip().match(/([^?#]*)(#.*)?$/);if(!a){return{}}return a[1].split(b||"&").inject({},function(e,f){if((f=f.split("="))[0]){var c=decodeURIComponent(f.shift());var d=f.length>1?f.join("="):f[0];if(d!=undefined){d=decodeURIComponent(d)}if(c in e){if(!Object.isArray(e[c])){e[c]=[e[c]]}e[c].push(d)}else{e[c]=d}}return e})},toArray:function(){return this.split("")},succ:function(){return this.slice(0,this.length-1)+String.fromCharCode(this.charCodeAt(this.length-1)+1)},times:function(a){return a<1?"":new Array(a+1).join(this)},camelize:function(){var d=this.split("-"),a=d.length;if(a==1){return d[0]}var c=this.charAt(0)=="-"?d[0].charAt(0).toUpperCase()+d[0].substring(1):d[0];for(var b=1;b<a;b++){c+=d[b].charAt(0).toUpperCase()+d[b].substring(1)}return c},capitalize:function(){return this.charAt(0).toUpperCase()+this.substring(1).toLowerCase()},underscore:function(){return this.gsub(/::/,"/").gsub(/([A-Z]+)([A-Z][a-z])/,"#{1}_#{2}").gsub(/([a-z\d])([A-Z])/,"#{1}_#{2}").gsub(/-/,"_").toLowerCase()},dasherize:function(){return this.gsub(/_/,"-")},inspect:function(b){var a=this.gsub(/[\x00-\x1f\\]/,function(c){var d=String.specialChar[c[0]];return d?d:"\\u00"+c[0].charCodeAt().toPaddedString(2,16)});if(b){return'"'+a.replace(/"/g,'\\"')+'"'}return"'"+a.replace(/'/g,"\\'")+"'"},toJSON:function(){return this.inspect(true)},unfilterJSON:function(a){return this.sub(a||Prototype.JSONFilter,"#{1}")},isJSON:function(){var a=this;if(a.blank()){return false}a=this.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,"");return(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(a)},evalJSON:function(sanitize){var json=this.unfilterJSON();try{if(!sanitize||json.isJSON()){return eval("("+json+")")}}catch(e){}throw new SyntaxError("Badly formed JSON string: "+this.inspect())},include:function(a){return this.indexOf(a)>-1},startsWith:function(a){return this.indexOf(a)===0},endsWith:function(a){var b=this.length-a.length;return b>=0&&this.lastIndexOf(a)===b},empty:function(){return this==""},blank:function(){return/^\s*$/.test(this)},interpolate:function(a,b){return new Template(this,b).evaluate(a)}});if(Prototype.Browser.WebKit||Prototype.Browser.IE){Object.extend(String.prototype,{escapeHTML:function(){return this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},unescapeHTML:function(){return this.stripTags().replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}})}String.prototype.gsub.prepareReplacement=function(b){if(Object.isFunction(b)){return b}var a=new Template(b);return function(c){return a.evaluate(c)}};String.prototype.parseQuery=String.prototype.toQueryParams;Object.extend(String.prototype.escapeHTML,{div:document.createElement("div"),text:document.createTextNode("")});String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);var Template=Class.create({initialize:function(a,b){this.template=a.toString();this.pattern=b||Template.Pattern},evaluate:function(a){if(Object.isFunction(a.toTemplateReplacements)){a=a.toTemplateReplacements()}return this.template.gsub(this.pattern,function(d){if(a==null){return""}var f=d[1]||"";if(f=="\\"){return d[2]}var b=a,g=d[3];var e=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;d=e.exec(g);if(d==null){return f}while(d!=null){var c=d[1].startsWith("[")?d[2].gsub("\\\\]","]"):d[1];b=b[c];if(null==b||""==d[3]){break}g=g.substring("["==d[3]?d[1].length:d[0].length);d=e.exec(g)}return f+String.interpret(b)})}});Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;var $break={};var Enumerable={each:function(c,b){var a=0;try{this._each(function(e){c.call(b,e,a++)})}catch(d){if(d!=$break){throw d}}return this},eachSlice:function(d,c,b){var a=-d,e=[],f=this.toArray();if(d<1){return f}while((a+=d)<f.length){e.push(f.slice(a,a+d))}return e.collect(c,b)},all:function(c,b){c=c||Prototype.K;var a=true;this.each(function(e,d){a=a&&!!c.call(b,e,d);if(!a){throw $break}});return a},any:function(c,b){c=c||Prototype.K;var a=false;this.each(function(e,d){if(a=!!c.call(b,e,d)){throw $break}});return a},collect:function(c,b){c=c||Prototype.K;var a=[];this.each(function(e,d){a.push(c.call(b,e,d))});return a},detect:function(c,b){var a;this.each(function(e,d){if(c.call(b,e,d)){a=e;throw $break}});return a},findAll:function(c,b){var a=[];this.each(function(e,d){if(c.call(b,e,d)){a.push(e)}});return a},grep:function(d,c,b){c=c||Prototype.K;var a=[];if(Object.isString(d)){d=new RegExp(d)}this.each(function(f,e){if(d.match(f)){a.push(c.call(b,f,e))}});return a},include:function(a){if(Object.isFunction(this.indexOf)){if(this.indexOf(a)!=-1){return true}}var b=false;this.each(function(c){if(c==a){b=true;throw $break}});return b},inGroupsOf:function(b,a){a=Object.isUndefined(a)?null:a;return this.eachSlice(b,function(c){while(c.length<b){c.push(a)}return c})},inject:function(a,c,b){this.each(function(e,d){a=c.call(b,a,e,d)});return a},invoke:function(b){var a=$A(arguments).slice(1);return this.map(function(c){return c[b].apply(c,a)})},max:function(c,b){c=c||Prototype.K;var a;this.each(function(e,d){e=c.call(b,e,d);if(a==null||e>=a){a=e}});return a},min:function(c,b){c=c||Prototype.K;var a;this.each(function(e,d){e=c.call(b,e,d);if(a==null||e<a){a=e}});return a},partition:function(d,b){d=d||Prototype.K;var c=[],a=[];this.each(function(f,e){(d.call(b,f,e)?c:a).push(f)});return[c,a]},pluck:function(b){var a=[];this.each(function(c){a.push(c[b])});return a},reject:function(c,b){var a=[];this.each(function(e,d){if(!c.call(b,e,d)){a.push(e)}});return a},sortBy:function(b,a){return this.map(function(d,c){return{value:d,criteria:b.call(a,d,c)}}).sort(function(f,e){var d=f.criteria,c=e.criteria;return d<c?-1:d>c?1:0}).pluck("value")},toArray:function(){return this.map()},zip:function(){var b=Prototype.K,a=$A(arguments);if(Object.isFunction(a.last())){b=a.pop()}var c=[this].concat(a).map($A);return this.map(function(e,d){return b(c.pluck(d))})},size:function(){return this.toArray().length},inspect:function(){return"#<Enumerable:"+this.toArray().inspect()+">"}};Object.extend(Enumerable,{map:Enumerable.collect,find:Enumerable.detect,select:Enumerable.findAll,filter:Enumerable.findAll,member:Enumerable.include,entries:Enumerable.toArray,every:Enumerable.all,some:Enumerable.any});function $A(c){if(!c){return[]}if(c.toArray){return c.toArray()}var b=c.length||0,a=new Array(b);while(b--){a[b]=c[b]}return a}if(Prototype.Browser.WebKit){$A=function(c){if(!c){return[]}if(!(typeof c==="function"&&typeof c.length==="number"&&typeof c.item==="function")&&c.toArray){return c.toArray()}var b=c.length||0,a=new Array(b);while(b--){a[b]=c[b]}return a}}Array.from=$A;Object.extend(Array.prototype,Enumerable);if(!Array.prototype._reverse){Array.prototype._reverse=Array.prototype.reverse}Object.extend(Array.prototype,{_each:function(b){for(var a=0,c=this.length;a<c;a++){b(this[a])}},clear:function(){this.length=0;return this},first:function(){return this[0]},last:function(){return this[this.length-1]},compact:function(){return this.select(function(a){return a!=null})},flatten:function(){return this.inject([],function(b,a){return b.concat(Object.isArray(a)?a.flatten():[a])})},without:function(){var a=$A(arguments);return this.select(function(b){return!a.include(b)})},reverse:function(a){return(a!==false?this:this.toArray())._reverse()},reduce:function(){return this.length>1?this:this[0]},uniq:function(a){return this.inject([],function(d,c,b){if(0==b||(a?d.last()!=c:!d.include(c))){d.push(c)}return d})},intersect:function(a){return this.uniq().findAll(function(b){return a.detect(function(c){return b===c})})},clone:function(){return[].concat(this)},size:function(){return this.length},inspect:function(){return"["+this.map(Object.inspect).join(", ")+"]"},toJSON:function(){var a=[];this.each(function(b){var c=Object.toJSON(b);if(!Object.isUndefined(c)){a.push(c)}});return"["+a.join(", ")+"]"}});if(Object.isFunction(Array.prototype.forEach)){Array.prototype._each=Array.prototype.forEach}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(c,a){a||(a=0);var b=this.length;if(a<0){a=b+a}for(;a<b;a++){if(this[a]===c){return a}}return-1}}if(!Array.prototype.lastIndexOf){Array.prototype.lastIndexOf=function(b,a){a=isNaN(a)?this.length:(a<0?this.length+a:a)+1;var c=this.slice(0,a).reverse().indexOf(b);return(c<0)?c:a-c-1}}Array.prototype.toArray=Array.prototype.clone;function $w(a){if(!Object.isString(a)){return[]}a=a.strip();return a?a.split(/\s+/):[]}if(Prototype.Browser.Opera){Array.prototype.concat=function(){var e=[];for(var b=0,c=this.length;b<c;b++){e.push(this[b])}for(var b=0,c=arguments.length;b<c;b++){if(Object.isArray(arguments[b])){for(var a=0,d=arguments[b].length;a<d;a++){e.push(arguments[b][a])}}else{e.push(arguments[b])}}return e}}Object.extend(Number.prototype,{toColorPart:function(){return this.toPaddedString(2,16)},succ:function(){return this+1},times:function(b,a){$R(0,this,true).each(b,a);return this},toPaddedString:function(c,b){var a=this.toString(b||10);return"0".times(c-a.length)+a},toJSON:function(){return isFinite(this)?this.toString():"null"}});$w("abs round ceil floor").each(function(a){Number.prototype[a]=Math[a].methodize()});function $H(a){return new Hash(a)}var Hash=Class.create(Enumerable,(function(){function a(b,c){if(Object.isUndefined(c)){return b}return b+"="+encodeURIComponent(String.interpret(c))}return{initialize:function(b){this._object=Object.isHash(b)?b.toObject():Object.clone(b)},_each:function(c){for(var b in this._object){var d=this._object[b],e=[b,d];e.key=b;e.value=d;c(e)}},set:function(b,c){return this._object[b]=c},get:function(b){if(this._object[b]!==Object.prototype[b]){return this._object[b]}},unset:function(b){var c=this._object[b];delete this._object[b];return c},toObject:function(){return Object.clone(this._object)},keys:function(){return this.pluck("key")},values:function(){return this.pluck("value")},index:function(c){var b=this.detect(function(d){return d.value===c});return b&&b.key},merge:function(b){return this.clone().update(b)},update:function(b){return new Hash(b).inject(this,function(c,d){c.set(d.key,d.value);return c})},toQueryString:function(){return this.inject([],function(d,e){var c=encodeURIComponent(e.key),b=e.value;if(b&&typeof b=="object"){if(Object.isArray(b)){return d.concat(b.map(a.curry(c)))}}else{d.push(a(c,b))}return d}).join("&")},inspect:function(){return"#<Hash:{"+this.map(function(b){return b.map(Object.inspect).join(": ")}).join(", ")+"}>"},toJSON:function(){return Object.toJSON(this.toObject())},clone:function(){return new Hash(this)}}})());Hash.prototype.toTemplateReplacements=Hash.prototype.toObject;Hash.from=$H;var ObjectRange=Class.create(Enumerable,{initialize:function(c,a,b){this.start=c;this.end=a;this.exclusive=b},_each:function(a){var b=this.start;while(this.include(b)){a(b);b=b.succ()}},include:function(a){if(a<this.start){return false}if(this.exclusive){return a<this.end}return a<=this.end}});var $R=function(c,a,b){return new ObjectRange(c,a,b)};var Ajax={getTransport:function(){return Try.these(function(){return new XMLHttpRequest()},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Microsoft.XMLHTTP")})||false},activeRequestCount:0};Ajax.Responders={responders:[],_each:function(a){this.responders._each(a)},register:function(a){if(!this.include(a)){this.responders.push(a)}},unregister:function(a){this.responders=this.responders.without(a)},dispatch:function(d,b,c,a){this.each(function(f){if(Object.isFunction(f[d])){try{f[d].apply(f,[b,c,a])}catch(g){}}})}};Object.extend(Ajax.Responders,Enumerable);Ajax.Responders.register({onCreate:function(){Ajax.activeRequestCount++},onComplete:function(){Ajax.activeRequestCount--}});Ajax.Base=Class.create({initialize:function(a){this.options={method:"post",asynchronous:true,contentType:"application/x-www-form-urlencoded",encoding:"UTF-8",parameters:"",evalJSON:true,evalJS:true};Object.extend(this.options,a||{});this.options.method=this.options.method.toLowerCase();if(Object.isString(this.options.parameters)){this.options.parameters=this.options.parameters.toQueryParams()}else{if(Object.isHash(this.options.parameters)){this.options.parameters=this.options.parameters.toObject()}}}});Ajax.Request=Class.create(Ajax.Base,{_complete:false,initialize:function($super,b,a){$super(a);this.transport=Ajax.getTransport();this.request(b)},request:function(b){this.url=b;this.method=this.options.method;var d=Object.clone(this.options.parameters);if(!["get","post"].include(this.method)){d._method=this.method;this.method="post"}this.parameters=d;if(d=Object.toQueryString(d)){if(this.method=="get"){this.url+=(this.url.include("?")?"&":"?")+d}else{if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)){d+="&_="}}}try{var a=new Ajax.Response(this);if(this.options.onCreate){this.options.onCreate(a)}Ajax.Responders.dispatch("onCreate",this,a);this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);if(this.options.asynchronous){this.respondToReadyState.bind(this).defer(1)}this.transport.onreadystatechange=this.onStateChange.bind(this);this.setRequestHeaders();this.body=this.method=="post"?(this.options.postBody||d):null;this.transport.send(this.body);if(!this.options.asynchronous&&this.transport.overrideMimeType){this.onStateChange()}}catch(c){this.dispatchException(c)}},onStateChange:function(){var a=this.transport.readyState;if(a>1&&!((a==4)&&this._complete)){this.respondToReadyState(this.transport.readyState)}},setRequestHeaders:function(){var e={"X-Requested-With":"XMLHttpRequest","X-Prototype-Version":Prototype.Version,Accept:"text/javascript, text/html, application/xml, text/xml, */*"};if(this.method=="post"){e["Content-type"]=this.options.contentType+(this.options.encoding?"; charset="+this.options.encoding:"");if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){e.Connection="close"}}if(typeof this.options.requestHeaders=="object"){var c=this.options.requestHeaders;if(Object.isFunction(c.push)){for(var b=0,d=c.length;b<d;b+=2){e[c[b]]=c[b+1]}}else{$H(c).each(function(f){e[f.key]=f.value})}}for(var a in e){this.transport.setRequestHeader(a,e[a])}},success:function(){var a=this.getStatus();return!a||(a>=200&&a<300)},getStatus:function(){try{return this.transport.status||0}catch(a){return 0}},respondToReadyState:function(a){var c=Ajax.Request.Events[a],b=new Ajax.Response(this);if(c=="Complete"){try{this._complete=true;(this.options["on"+b.status]||this.options["on"+(this.success()?"Success":"Failure")]||Prototype.emptyFunction)(b,b.headerJSON)}catch(d){this.dispatchException(d)}var f=b.getHeader("Content-type");if(this.options.evalJS=="force"||(this.options.evalJS&&this.isSameOrigin()&&f&&f.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))){this.evalResponse()}}try{(this.options["on"+c]||Prototype.emptyFunction)(b,b.headerJSON);Ajax.Responders.dispatch("on"+c,this,b,b.headerJSON)}catch(d){this.dispatchException(d)}if(c=="Complete"){this.transport.onreadystatechange=Prototype.emptyFunction}},isSameOrigin:function(){var a=this.url.match(/^\s*https?:\/\/[^\/]*/);return!a||(a[0]=="#{protocol}//#{domain}#{port}".interpolate({protocol:location.protocol,domain:document.domain,port:location.port?":"+location.port:""}))},getHeader:function(a){try{return this.transport.getResponseHeader(a)||null}catch(b){return null}},evalResponse:function(){try{return eval((this.transport.responseText||"").unfilterJSON())}catch(e){this.dispatchException(e)}},dispatchException:function(a){(this.options.onException||Prototype.emptyFunction)(this,a);Ajax.Responders.dispatch("onException",this,a)}});Ajax.Request.Events=["Uninitialized","Loading","Loaded","Interactive","Complete"];Ajax.Response=Class.create({initialize:function(c){this.request=c;var d=this.transport=c.transport,a=this.readyState=d.readyState;if((a>2&&!Prototype.Browser.IE)||a==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=String.interpret(d.responseText);this.headerJSON=this._getHeaderJSON()}if(a==4){var b=d.responseXML;this.responseXML=Object.isUndefined(b)?null:b;this.responseJSON=this._getResponseJSON()}},status:0,statusText:"",getStatus:Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||""}catch(a){return""}},getHeader:Ajax.Request.prototype.getHeader,getAllHeaders:function(){try{return this.getAllResponseHeaders()}catch(a){return null}},getResponseHeader:function(a){return this.transport.getResponseHeader(a)},getAllResponseHeaders:function(){return this.transport.getAllResponseHeaders()},_getHeaderJSON:function(){var a=this.getHeader("X-JSON");if(!a){return null}a=decodeURIComponent(escape(a));try{return a.evalJSON(this.request.options.sanitizeJSON||!this.request.isSameOrigin())}catch(b){this.request.dispatchException(b)}},_getResponseJSON:function(){var a=this.request.options;if(!a.evalJSON||(a.evalJSON!="force"&&!(this.getHeader("Content-type")||"").include("application/json"))||this.responseText.blank()){return null}try{return this.responseText.evalJSON(a.sanitizeJSON||!this.request.isSameOrigin())}catch(b){this.request.dispatchException(b)}}});Ajax.Updater=Class.create(Ajax.Request,{initialize:function($super,a,c,b){this.container={success:(a.success||a),failure:(a.failure||(a.success?null:a))};b=Object.clone(b);var d=b.onComplete;b.onComplete=(function(e,f){this.updateContent(e.responseText);if(Object.isFunction(d)){d(e,f)}}).bind(this);$super(c,b)},updateContent:function(d){var c=this.container[this.success()?"success":"failure"],a=this.options;if(!a.evalScripts){d=d.stripScripts()}if(c=$(c)){if(a.insertion){if(Object.isString(a.insertion)){var b={};b[a.insertion]=d;c.insert(b)}else{a.insertion(c,d)}}else{c.update(d)}}}});Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{initialize:function($super,a,c,b){$super(b);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=a;this.url=c;this.start()},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent()},stop:function(){this.updater.options.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments)},updateComplete:function(a){if(this.options.decay){this.decay=(a.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=a.responseText}this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency)},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options)}});function $(b){if(arguments.length>1){for(var a=0,d=[],c=arguments.length;a<c;a++){d.push($(arguments[a]))}return d}if(Object.isString(b)){b=document.getElementById(b)}return Element.extend(b)}if(Prototype.BrowserFeatures.XPath){document._getElementsByXPath=function(f,a){var c=[];var e=document.evaluate(f,$(a)||document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);for(var b=0,d=e.snapshotLength;b<d;b++){c.push(Element.extend(e.snapshotItem(b)))}return c}}if(!window.Node){var Node={}}if(!Node.ELEMENT_NODE){Object.extend(Node,{ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12})}(function(){var a=this.Element;this.Element=function(d,c){c=c||{};d=d.toLowerCase();var b=Element.cache;if(Prototype.Browser.IE&&c.name){d="<"+d+' name="'+c.name+'">';delete c.name;return Element.writeAttribute(document.createElement(d),c)}if(!b[d]){b[d]=Element.extend(document.createElement(d))}return Element.writeAttribute(b[d].cloneNode(false),c)};Object.extend(this.Element,a||{});if(a){this.Element.prototype=a.prototype}}).call(window);Element.cache={};Element.Methods={visible:function(a){return $(a).style.display!="none"},toggle:function(a){a=$(a);Element[Element.visible(a)?"hide":"show"](a);return a},hide:function(a){a=$(a);a.style.display="none";return a},show:function(a){a=$(a);a.style.display="";return a},remove:function(a){a=$(a);a.parentNode.removeChild(a);return a},update:function(a,b){a=$(a);if(b&&b.toElement){b=b.toElement()}if(Object.isElement(b)){return a.update().insert(b)}b=Object.toHTML(b);a.innerHTML=b.stripScripts();b.evalScripts.bind(b).defer();return a},replace:function(b,c){b=$(b);if(c&&c.toElement){c=c.toElement()}else{if(!Object.isElement(c)){c=Object.toHTML(c);var a=b.ownerDocument.createRange();a.selectNode(b);c.evalScripts.bind(c).defer();c=a.createContextualFragment(c.stripScripts())}}b.parentNode.replaceChild(c,b);return b},insert:function(c,e){c=$(c);if(Object.isString(e)||Object.isNumber(e)||Object.isElement(e)||(e&&(e.toElement||e.toHTML))){e={bottom:e}}var d,f,b,g;for(var a in e){d=e[a];a=a.toLowerCase();f=Element._insertionTranslations[a];if(d&&d.toElement){d=d.toElement()}if(Object.isElement(d)){f(c,d);continue}d=Object.toHTML(d);b=((a=="before"||a=="after")?c.parentNode:c).tagName.toUpperCase();g=Element._getContentFromAnonymousElement(b,d.stripScripts());if(a=="top"||a=="after"){g.reverse()}g.each(f.curry(c));d.evalScripts.bind(d).defer()}return c},wrap:function(b,c,a){b=$(b);if(Object.isElement(c)){$(c).writeAttribute(a||{})}else{if(Object.isString(c)){c=new Element(c,a)}else{c=new Element("div",c)}}if(b.parentNode){b.parentNode.replaceChild(c,b)}c.appendChild(b);return c},inspect:function(b){b=$(b);var a="<"+b.tagName.toLowerCase();$H({id:"id",className:"class"}).each(function(f){var e=f.first(),c=f.last();var d=(b[e]||"").toString();if(d){a+=" "+c+"="+d.inspect(true)}});return a+">"},recursivelyCollect:function(a,c){a=$(a);var b=[];while(a=a[c]){if(a.nodeType==1){b.push(Element.extend(a))}}return b},ancestors:function(a){return $(a).recursivelyCollect("parentNode")},descendants:function(a){return $(a).select("*")},firstDescendant:function(a){a=$(a).firstChild;while(a&&a.nodeType!=1){a=a.nextSibling}return $(a)},immediateDescendants:function(a){if(!(a=$(a).firstChild)){return[]}while(a&&a.nodeType!=1){a=a.nextSibling}if(a){return[a].concat($(a).nextSiblings())}return[]},previousSiblings:function(a){return $(a).recursivelyCollect("previousSibling")},nextSiblings:function(a){return $(a).recursivelyCollect("nextSibling")},siblings:function(a){a=$(a);return a.previousSiblings().reverse().concat(a.nextSiblings())},match:function(b,a){if(Object.isString(a)){a=new Selector(a)}return a.match($(b))},up:function(b,d,a){b=$(b);if(arguments.length==1){return $(b.parentNode)}var c=b.ancestors();return Object.isNumber(d)?c[d]:Selector.findElement(c,d,a)},down:function(b,c,a){b=$(b);if(arguments.length==1){return b.firstDescendant()}return Object.isNumber(c)?b.descendants()[c]:Element.select(b,c)[a||0]},previous:function(b,d,a){b=$(b);if(arguments.length==1){return $(Selector.handlers.previousElementSibling(b))}var c=b.previousSiblings();return Object.isNumber(d)?c[d]:Selector.findElement(c,d,a)},next:function(c,d,b){c=$(c);if(arguments.length==1){return $(Selector.handlers.nextElementSibling(c))}var a=c.nextSiblings();return Object.isNumber(d)?a[d]:Selector.findElement(a,d,b)},select:function(){var a=$A(arguments),b=$(a.shift());return Selector.findChildElements(b,a)},adjacent:function(){var a=$A(arguments),b=$(a.shift());return Selector.findChildElements(b.parentNode,a).without(b)},identify:function(b){b=$(b);var c=b.readAttribute("id"),a=arguments.callee;if(c){return c}do{c="anonymous_element_"+a.counter++}while($(c));b.writeAttribute("id",c);return c},readAttribute:function(c,a){c=$(c);if(Prototype.Browser.IE){var b=Element._attributeTranslations.read;if(b.values[a]){return b.values[a](c,a)}if(b.names[a]){a=b.names[a]}if(a.include(":")){return(!c.attributes||!c.attributes[a])?null:c.attributes[a].value}}return c.getAttribute(a)},writeAttribute:function(e,c,f){e=$(e);var b={},d=Element._attributeTranslations.write;if(typeof c=="object"){b=c}else{b[c]=Object.isUndefined(f)?true:f}for(var a in b){c=d.names[a]||a;f=b[a];if(d.values[a]){c=d.values[a](e,f)}if(f===false||f===null){e.removeAttribute(c)}else{if(f===true){e.setAttribute(c,c)}else{e.setAttribute(c,f)}}}return e},getHeight:function(a){return $(a).getDimensions().height},getWidth:function(a){return $(a).getDimensions().width},classNames:function(a){return new Element.ClassNames(a)},hasClassName:function(a,b){if(!(a=$(a))){return}var c=a.className;return(c.length>0&&(c==b||new RegExp("(^|\\s)"+b+"(\\s|$)").test(c)))},addClassName:function(a,b){if(!(a=$(a))){return}if(!a.hasClassName(b)){a.className+=(a.className?" ":"")+b}return a},removeClassName:function(a,b){if(!(a=$(a))){return}a.className=a.className.replace(new RegExp("(^|\\s+)"+b+"(\\s+|$)")," ").strip();return a},toggleClassName:function(a,b){if(!(a=$(a))){return}return a[a.hasClassName(b)?"removeClassName":"addClassName"](b)},cleanWhitespace:function(b){b=$(b);var c=b.firstChild;while(c){var a=c.nextSibling;if(c.nodeType==3&&!/\S/.test(c.nodeValue)){b.removeChild(c)}c=a}return b},empty:function(a){return $(a).innerHTML.blank()},descendantOf:function(b,a){b=$(b),a=$(a);if(b.compareDocumentPosition){return(b.compareDocumentPosition(a)&8)===8}if(a.contains){return a.contains(b)&&a!==b}while(b=b.parentNode){if(b==a){return true}}return false},scrollTo:function(a){a=$(a);var b=a.cumulativeOffset();window.scrollTo(b[0],b[1]);return a},getStyle:function(b,c){b=$(b);c=c=="float"?"cssFloat":c.camelize();var d=b.style[c];if(!d||d=="auto"){var a=document.defaultView.getComputedStyle(b,null);d=a?a[c]:null}if(c=="opacity"){return d?parseFloat(d):1}return d=="auto"?null:d},getOpacity:function(a){return $(a).getStyle("opacity")},setStyle:function(b,c){b=$(b);var e=b.style,a;if(Object.isString(c)){b.style.cssText+=";"+c;return c.include("opacity")?b.setOpacity(c.match(/opacity:\s*(\d?\.?\d*)/)[1]):b}for(var d in c){if(d=="opacity"){b.setOpacity(c[d])}else{e[(d=="float"||d=="cssFloat")?(Object.isUndefined(e.styleFloat)?"cssFloat":"styleFloat"):d]=c[d]}}return b},setOpacity:function(a,b){a=$(a);a.style.opacity=(b==1||b==="")?"":(b<0.00001)?0:b;return a},getDimensions:function(c){c=$(c);var g=c.getStyle("display");if(g!="none"&&g!=null){return{width:c.offsetWidth,height:c.offsetHeight}}var b=c.style;var f=b.visibility;var d=b.position;var a=b.display;b.visibility="hidden";b.position="absolute";b.display="block";var h=c.clientWidth;var e=c.clientHeight;b.display=a;b.position=d;b.visibility=f;return{width:h,height:e}},makePositioned:function(a){a=$(a);var b=Element.getStyle(a,"position");if(b=="static"||!b){a._madePositioned=true;a.style.position="relative";if(Prototype.Browser.Opera){a.style.top=0;a.style.left=0}}return a},undoPositioned:function(a){a=$(a);if(a._madePositioned){a._madePositioned=undefined;a.style.position=a.style.top=a.style.left=a.style.bottom=a.style.right=""}return a},makeClipping:function(a){a=$(a);if(a._overflow){return a}a._overflow=Element.getStyle(a,"overflow")||"auto";if(a._overflow!=="hidden"){a.style.overflow="hidden"}return a},undoClipping:function(a){a=$(a);if(!a._overflow){return a}a.style.overflow=a._overflow=="auto"?"":a._overflow;a._overflow=null;return a},cumulativeOffset:function(b){var a=0,c=0;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;b=b.offsetParent}while(b);return Element._returnOffset(c,a)},positionedOffset:function(b){var a=0,d=0;do{a+=b.offsetTop||0;d+=b.offsetLeft||0;b=b.offsetParent;if(b){if(b.tagName.toUpperCase()=="BODY"){break}var c=Element.getStyle(b,"position");if(c!=="static"){break}}}while(b);return Element._returnOffset(d,a)},absolutize:function(b){b=$(b);if(b.getStyle("position")=="absolute"){return b}var d=b.positionedOffset();var f=d[1];var e=d[0];var c=b.clientWidth;var a=b.clientHeight;b._originalLeft=e-parseFloat(b.style.left||0);b._originalTop=f-parseFloat(b.style.top||0);b._originalWidth=b.style.width;b._originalHeight=b.style.height;b.style.position="absolute";b.style.top=f+"px";b.style.left=e+"px";b.style.width=c+"px";b.style.height=a+"px";return b},relativize:function(a){a=$(a);if(a.getStyle("position")=="relative"){return a}a.style.position="relative";var c=parseFloat(a.style.top||0)-(a._originalTop||0);var b=parseFloat(a.style.left||0)-(a._originalLeft||0);a.style.top=c+"px";a.style.left=b+"px";a.style.height=a._originalHeight;a.style.width=a._originalWidth;return a},cumulativeScrollOffset:function(b){var a=0,c=0;do{a+=b.scrollTop||0;c+=b.scrollLeft||0;b=b.parentNode}while(b);return Element._returnOffset(c,a)},getOffsetParent:function(b){b=$(b);var d=b.offsetParent,a=document.body,c=document.documentElement;if(d&&d!==c){return $(d)}if(d===c||b===c||b===a){return $(a)}while((b=b.parentNode)&&b!==a){if(Element.getStyle(b,"position")!="static"){return $(b)}}return $(a)},viewportOffset:function(d){d=$(d);var b=d,a=0,c=0;do{a+=b.offsetTop||0;c+=b.offsetLeft||0}while((b=b.getOffsetParent())!=document.body);b=d;do{if(!Prototype.Browser.Opera||(b.tagName&&(b.tagName.toUpperCase()=="BODY"))){a-=b.scrollTop||0;c-=b.scrollLeft||0}}while(b=b.parentNode);return Element._returnOffset(c,a)},clonePosition:function(b,d){var a=Object.extend({setLeft:true,setTop:true,setWidth:true,setHeight:true,offsetTop:0,offsetLeft:0},arguments[2]||{});d=$(d);var e=d.viewportOffset();b=$(b);var f=[0,0];var c=null;if(Element.getStyle(b,"position")=="absolute"){c=b.getOffsetParent();f=c.viewportOffset()}if(c==document.body){f[0]-=document.body.offsetLeft;f[1]-=document.body.offsetTop}if(a.setLeft){b.style.left=(e[0]-f[0]+a.offsetLeft)+"px"}if(a.setTop){b.style.top=(e[1]-f[1]+a.offsetTop)+"px"}if(a.setWidth){b.style.width=d.offsetWidth+"px"}if(a.setHeight){b.style.height=d.offsetHeight+"px"}return b}};Element.Methods.identify.counter=1;Object.extend(Element.Methods,{getElementsBySelector:Element.Methods.select,childElements:Element.Methods.immediateDescendants});Element._attributeTranslations={write:{names:{className:"class",htmlFor:"for"},values:{}}};if(Prototype.Browser.Opera){Element.Methods.getStyle=Element.Methods.getStyle.wrap(function(d,b,c){switch(c){case"left":case"top":case"right":case"bottom":if(d(b,"position")==="static"){return null}case"height":case"width":if(!Element.visible(b)){return null}var e=parseInt(d(b,c),10);if(e!==b["offset"+c.capitalize()]){return e+"px"}var a;if(c==="height"){a=["border-top-width","padding-top","padding-bottom","border-bottom-width"]}else{a=["border-left-width","padding-left","padding-right","border-right-width"]}return a.inject(e,function(f,g){var h=d(b,g);return h===null?f:f-parseInt(h,10)})+"px";default:return d(b,c)}});Element.Methods.readAttribute=Element.Methods.readAttribute.wrap(function(c,a,b){if(b==="title"){return a.title}return c(a,b)})}else{if(Prototype.Browser.IE){Element.Methods.getOffsetParent=Element.Methods.getOffsetParent.wrap(function(c,b){b=$(b);try{b.offsetParent}catch(f){return $(document.body)}var a=b.getStyle("position");if(a!=="static"){return c(b)}b.setStyle({position:"relative"});var d=c(b);b.setStyle({position:a});return d});$w("positionedOffset viewportOffset").each(function(a){Element.Methods[a]=Element.Methods[a].wrap(function(f,c){c=$(c);try{c.offsetParent}catch(h){return Element._returnOffset(0,0)}var b=c.getStyle("position");if(b!=="static"){return f(c)}var d=c.getOffsetParent();if(d&&d.getStyle("position")==="fixed"){d.setStyle({zoom:1})}c.setStyle({position:"relative"});var g=f(c);c.setStyle({position:b});return g})});Element.Methods.cumulativeOffset=Element.Methods.cumulativeOffset.wrap(function(b,a){try{a.offsetParent}catch(c){return Element._returnOffset(0,0)}return b(a)});Element.Methods.getStyle=function(a,b){a=$(a);b=(b=="float"||b=="cssFloat")?"styleFloat":b.camelize();var c=a.style[b];if(!c&&a.currentStyle){c=a.currentStyle[b]}if(b=="opacity"){if(c=(a.getStyle("filter")||"").match(/alpha\(opacity=(.*)\)/)){if(c[1]){return parseFloat(c[1])/100}}return 1}if(c=="auto"){if((b=="width"||b=="height")&&(a.getStyle("display")!="none")){return a["offset"+b.capitalize()]+"px"}return null}return c};Element.Methods.setOpacity=function(b,e){function f(g){return g.replace(/alpha\([^\)]*\)/gi,"")}b=$(b);var a=b.currentStyle;if((a&&!a.hasLayout)||(!a&&b.style.zoom=="normal")){b.style.zoom=1}var d=b.getStyle("filter"),c=b.style;if(e==1||e===""){(d=f(d))?c.filter=d:c.removeAttribute("filter");return b}else{if(e<0.00001){e=0}}c.filter=f(d)+"alpha(opacity="+(e*100)+")";return b};Element._attributeTranslations={read:{names:{"class":"className","for":"htmlFor"},values:{_getAttr:function(a,b){return a.getAttribute(b,2)},_getAttrNode:function(a,c){var b=a.getAttributeNode(c);return b?b.value:""},_getEv:function(a,b){b=a.getAttribute(b);return b?b.toString().slice(23,-2):null},_flag:function(a,b){return $(a).hasAttribute(b)?b:null},style:function(a){return a.style.cssText.toLowerCase()},title:function(a){return a.title}}}};Element._attributeTranslations.write={names:Object.extend({cellpadding:"cellPadding",cellspacing:"cellSpacing"},Element._attributeTranslations.read.names),values:{checked:function(a,b){a.checked=!!b},style:function(a,b){a.style.cssText=b?b:""}}};Element._attributeTranslations.has={};$w("colSpan rowSpan vAlign dateTime accessKey tabIndex encType maxLength readOnly longDesc frameBorder").each(function(a){Element._attributeTranslations.write.names[a.toLowerCase()]=a;Element._attributeTranslations.has[a.toLowerCase()]=a});(function(a){Object.extend(a,{href:a._getAttr,src:a._getAttr,type:a._getAttr,action:a._getAttrNode,disabled:a._flag,checked:a._flag,readonly:a._flag,multiple:a._flag,onload:a._getEv,onunload:a._getEv,onclick:a._getEv,ondblclick:a._getEv,onmousedown:a._getEv,onmouseup:a._getEv,onmouseover:a._getEv,onmousemove:a._getEv,onmouseout:a._getEv,onfocus:a._getEv,onblur:a._getEv,onkeypress:a._getEv,onkeydown:a._getEv,onkeyup:a._getEv,onsubmit:a._getEv,onreset:a._getEv,onselect:a._getEv,onchange:a._getEv})})(Element._attributeTranslations.read.values)}else{if(Prototype.Browser.Gecko&&/rv:1\.8\.0/.test(navigator.userAgent)){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1)?0.999999:(b==="")?"":(b<0.00001)?0:b;return a}}else{if(Prototype.Browser.WebKit){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1||b==="")?"":(b<0.00001)?0:b;if(b==1){if(a.tagName.toUpperCase()=="IMG"&&a.width){a.width++;a.width--}else{try{var d=document.createTextNode(" ");a.appendChild(d);a.removeChild(d)}catch(c){}}}return a};Element.Methods.cumulativeOffset=function(b){var a=0,c=0;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;if(b.offsetParent==document.body){if(Element.getStyle(b,"position")=="absolute"){break}}b=b.offsetParent}while(b);return Element._returnOffset(c,a)}}}}}if(Prototype.Browser.IE||Prototype.Browser.Opera){Element.Methods.update=function(b,c){b=$(b);if(c&&c.toElement){c=c.toElement()}if(Object.isElement(c)){return b.update().insert(c)}c=Object.toHTML(c);var a=b.tagName.toUpperCase();if(a in Element._insertionTranslations.tags){$A(b.childNodes).each(function(d){b.removeChild(d)});Element._getContentFromAnonymousElement(a,c.stripScripts()).each(function(d){b.appendChild(d)})}else{b.innerHTML=c.stripScripts()}c.evalScripts.bind(c).defer();return b}}if("outerHTML"in document.createElement("div")){Element.Methods.replace=function(c,e){c=$(c);if(e&&e.toElement){e=e.toElement()}if(Object.isElement(e)){c.parentNode.replaceChild(e,c);return c}e=Object.toHTML(e);var d=c.parentNode,b=d.tagName.toUpperCase();if(Element._insertionTranslations.tags[b]){var f=c.next();var a=Element._getContentFromAnonymousElement(b,e.stripScripts());d.removeChild(c);if(f){a.each(function(g){d.insertBefore(g,f)})}else{a.each(function(g){d.appendChild(g)})}}else{c.outerHTML=e.stripScripts()}e.evalScripts.bind(e).defer();return c}}Element._returnOffset=function(b,c){var a=[b,c];a.left=b;a.top=c;return a};Element._getContentFromAnonymousElement=function(c,b){var d=new Element("div"),a=Element._insertionTranslations.tags[c];if(a){d.innerHTML=a[0]+b+a[1];a[2].times(function(){d=d.firstChild})}else{d.innerHTML=b}return $A(d.childNodes)};Element._insertionTranslations={before:function(a,b){a.parentNode.insertBefore(b,a)},top:function(a,b){a.insertBefore(b,a.firstChild)},bottom:function(a,b){a.appendChild(b)},after:function(a,b){a.parentNode.insertBefore(b,a.nextSibling)},tags:{TABLE:["<table>","</table>",1],TBODY:["<table><tbody>","</tbody></table>",2],TR:["<table><tbody><tr>","</tr></tbody></table>",3],TD:["<table><tbody><tr><td>","</td></tr></tbody></table>",4],SELECT:["<select>","</select>",1]}};(function(){Object.extend(this.tags,{THEAD:this.tags.TBODY,TFOOT:this.tags.TBODY,TH:this.tags.TD})}).call(Element._insertionTranslations);Element.Methods.Simulated={hasAttribute:function(a,c){c=Element._attributeTranslations.has[c]||c;var b=$(a).getAttributeNode(c);return!!(b&&b.specified)}};Element.Methods.ByTag={};Object.extend(Element,Element.Methods);if(!Prototype.BrowserFeatures.ElementExtensions&&document.createElement("div")["__proto__"]){window.HTMLElement={};window.HTMLElement.prototype=document.createElement("div")["__proto__"];Prototype.BrowserFeatures.ElementExtensions=true}Element.extend=(function(){if(Prototype.BrowserFeatures.SpecificElementExtensions){return Prototype.K}var a={},b=Element.Methods.ByTag;var c=Object.extend(function(f){if(!f||f._extendedByPrototype||f.nodeType!=1||f==window){return f}var d=Object.clone(a),e=f.tagName.toUpperCase(),h,g;if(b[e]){Object.extend(d,b[e])}for(h in d){g=d[h];if(Object.isFunction(g)&&!(h in f)){f[h]=g.methodize()}}f._extendedByPrototype=Prototype.emptyFunction;return f},{refresh:function(){if(!Prototype.BrowserFeatures.ElementExtensions){Object.extend(a,Element.Methods);Object.extend(a,Element.Methods.Simulated)}}});c.refresh();return c})();Element.hasAttribute=function(a,b){if(a.hasAttribute){return a.hasAttribute(b)}return Element.Methods.Simulated.hasAttribute(a,b)};Element.addMethods=function(c){var h=Prototype.BrowserFeatures,d=Element.Methods.ByTag;if(!c){Object.extend(Form,Form.Methods);Object.extend(Form.Element,Form.Element.Methods);Object.extend(Element.Methods.ByTag,{FORM:Object.clone(Form.Methods),INPUT:Object.clone(Form.Element.Methods),SELECT:Object.clone(Form.Element.Methods),TEXTAREA:Object.clone(Form.Element.Methods)})}if(arguments.length==2){var b=c;c=arguments[1]}if(!b){Object.extend(Element.Methods,c||{})}else{if(Object.isArray(b)){b.each(g)}else{g(b)}}function g(j){j=j.toUpperCase();if(!Element.Methods.ByTag[j]){Element.Methods.ByTag[j]={}}Object.extend(Element.Methods.ByTag[j],c)}function a(l,k,j){j=j||false;for(var n in l){var m=l[n];if(!Object.isFunction(m)){continue}if(!j||!(n in k)){k[n]=m.methodize()}}}function e(l){var j;var k={OPTGROUP:"OptGroup",TEXTAREA:"TextArea",P:"Paragraph",FIELDSET:"FieldSet",UL:"UList",OL:"OList",DL:"DList",DIR:"Directory",H1:"Heading",H2:"Heading",H3:"Heading",H4:"Heading",H5:"Heading",H6:"Heading",Q:"Quote",INS:"Mod",DEL:"Mod",A:"Anchor",IMG:"Image",CAPTION:"TableCaption",COL:"TableCol",COLGROUP:"TableCol",THEAD:"TableSection",TFOOT:"TableSection",TBODY:"TableSection",TR:"TableRow",TH:"TableCell",TD:"TableCell",FRAMESET:"FrameSet",IFRAME:"IFrame"};if(k[l]){j="HTML"+k[l]+"Element"}if(window[j]){return window[j]}j="HTML"+l+"Element";if(window[j]){return window[j]}j="HTML"+l.capitalize()+"Element";if(window[j]){return window[j]}window[j]={};window[j].prototype=document.createElement(l)["__proto__"];return window[j]}if(h.ElementExtensions){a(Element.Methods,HTMLElement.prototype);a(Element.Methods.Simulated,HTMLElement.prototype,true)}if(h.SpecificElementExtensions){for(var i in Element.Methods.ByTag){var f=e(i);if(Object.isUndefined(f)){continue}a(d[i],f.prototype)}}Object.extend(Element,Element.Methods);delete Element.ByTag;if(Element.extend.refresh){Element.extend.refresh()}Element.cache={}};document.viewport={getDimensions:function(){var a={},b=Prototype.Browser;$w("width height").each(function(e){var c=e.capitalize();if(b.WebKit&&!document.evaluate){a[e]=self["inner"+c]}else{if(b.Opera&&parseFloat(window.opera.version())<9.5){a[e]=document.body["client"+c]}else{a[e]=document.documentElement["client"+c]}}});return a},getWidth:function(){return this.getDimensions().width},getHeight:function(){return this.getDimensions().height},getScrollOffsets:function(){return Element._returnOffset(window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop)}};var Selector=Class.create({initialize:function(a){this.expression=a.strip();if(this.shouldUseSelectorsAPI()){this.mode="selectorsAPI"}else{if(this.shouldUseXPath()){this.mode="xpath";this.compileXPathMatcher()}else{this.mode="normal";this.compileMatcher()}}},shouldUseXPath:function(){if(!Prototype.BrowserFeatures.XPath){return false}var a=this.expression;if(Prototype.Browser.WebKit&&(a.include("-of-type")||a.include(":empty"))){return false}if((/(\[[\w-]*?:|:checked)/).test(a)){return false}return true},shouldUseSelectorsAPI:function(){if(!Prototype.BrowserFeatures.SelectorsAPI){return false}if(!Selector._div){Selector._div=new Element("div")}try{Selector._div.querySelector(this.expression)}catch(a){return false}return true},compileMatcher:function(){var e=this.expression,ps=Selector.patterns,h=Selector.handlers,c=Selector.criteria,le,p,m;if(Selector._cache[e]){this.matcher=Selector._cache[e];return}this.matcher=["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i in ps){p=ps[i];if(m=e.match(p)){this.matcher.push(Object.isFunction(c[i])?c[i](m):new Template(c[i]).evaluate(m));e=e.replace(m[0],"");break}}}this.matcher.push("return h.unique(n);\n}");eval(this.matcher.join("\n"));Selector._cache[this.expression]=this.matcher},compileXPathMatcher:function(){var f=this.expression,g=Selector.patterns,b=Selector.xpath,d,a;if(Selector._cache[f]){this.xpath=Selector._cache[f];return}this.matcher=[".//*"];while(f&&d!=f&&(/\S/).test(f)){d=f;for(var c in g){if(a=f.match(g[c])){this.matcher.push(Object.isFunction(b[c])?b[c](a):new Template(b[c]).evaluate(a));f=f.replace(a[0],"");break}}}this.xpath=this.matcher.join("");Selector._cache[this.expression]=this.xpath},findElements:function(a){a=a||document;var c=this.expression,b;switch(this.mode){case"selectorsAPI":if(a!==document){var d=a.id,f=$(a).identify();c="#"+f+" "+c}b=$A(a.querySelectorAll(c)).map(Element.extend);a.id=d;return b;case"xpath":return document._getElementsByXPath(this.xpath,a);default:return this.matcher(a)}},match:function(j){this.tokens=[];var o=this.expression,a=Selector.patterns,f=Selector.assertions;var b,d,g;while(o&&b!==o&&(/\S/).test(o)){b=o;for(var k in a){d=a[k];if(g=o.match(d)){if(f[k]){this.tokens.push([k,Object.clone(g)]);o=o.replace(g[0],"")}else{return this.findElements(document).include(j)}}}}var n=true,c,l;for(var k=0,h;h=this.tokens[k];k++){c=h[0],l=h[1];if(!Selector.assertions[c](j,l)){n=false;break}}return n},toString:function(){return this.expression},inspect:function(){return"#<Selector:"+this.expression.inspect()+">"}});Object.extend(Selector,{_cache:{},xpath:{descendant:"//*",child:"/*",adjacent:"/following-sibling::*[1]",laterSibling:"/following-sibling::*",tagName:function(a){if(a[1]=="*"){return""}return"[local-name()='"+a[1].toLowerCase()+"' or local-name()='"+a[1].toUpperCase()+"']"},className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",id:"[@id='#{1}']",attrPresence:function(a){a[1]=a[1].toLowerCase();return new Template("[@#{1}]").evaluate(a)},attr:function(a){a[1]=a[1].toLowerCase();a[3]=a[5]||a[6];return new Template(Selector.xpath.operators[a[2]]).evaluate(a)},pseudo:function(a){var b=Selector.xpath.pseudos[a[1]];if(!b){return""}if(Object.isFunction(b)){return b(a)}return new Template(Selector.xpath.pseudos[a[1]]).evaluate(a)},operators:{"=":"[@#{1}='#{3}']","!=":"[@#{1}!='#{3}']","^=":"[starts-with(@#{1}, '#{3}')]","$=":"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']","*=":"[contains(@#{1}, '#{3}')]","~=":"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]","|=":"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"},pseudos:{"first-child":"[not(preceding-sibling::*)]","last-child":"[not(following-sibling::*)]","only-child":"[not(preceding-sibling::* or following-sibling::*)]",empty:"[count(*) = 0 and (count(text()) = 0)]",checked:"[@checked]",disabled:"[(@disabled) and (@type!='hidden')]",enabled:"[not(@disabled) and (@type!='hidden')]",not:function(b){var j=b[6],h=Selector.patterns,a=Selector.xpath,f,c;var g=[];while(j&&f!=j&&(/\S/).test(j)){f=j;for(var d in h){if(b=j.match(h[d])){c=Object.isFunction(a[d])?a[d](b):new Template(a[d]).evaluate(b);g.push("("+c.substring(1,c.length-1)+")");j=j.replace(b[0],"");break}}}return"[not("+g.join(" and ")+")]"},"nth-child":function(a){return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",a)},"nth-last-child":function(a){return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",a)},"nth-of-type":function(a){return Selector.xpath.pseudos.nth("position() ",a)},"nth-last-of-type":function(a){return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",a)},"first-of-type":function(a){a[6]="1";return Selector.xpath.pseudos["nth-of-type"](a)},"last-of-type":function(a){a[6]="1";return Selector.xpath.pseudos["nth-last-of-type"](a)},"only-of-type":function(a){var b=Selector.xpath.pseudos;return b["first-of-type"](a)+b["last-of-type"](a)},nth:function(g,e){var h,i=e[6],d;if(i=="even"){i="2n+0"}if(i=="odd"){i="2n+1"}if(h=i.match(/^(\d+)$/)){return"["+g+"= "+h[1]+"]"}if(h=i.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(h[1]=="-"){h[1]=-1}var f=h[1]?Number(h[1]):1;var c=h[2]?Number(h[2]):0;d="[((#{fragment} - #{b}) mod #{a} = 0) and ((#{fragment} - #{b}) div #{a} >= 0)]";return new Template(d).evaluate({fragment:g,a:f,b:c})}}}},criteria:{tagName:'n = h.tagName(n, r, "#{1}", c);      c = false;',className:'n = h.className(n, r, "#{1}", c);    c = false;',id:'n = h.id(n, r, "#{1}", c);           c = false;',attrPresence:'n = h.attrPresence(n, r, "#{1}", c); c = false;',attr:function(a){a[3]=(a[5]||a[6]);return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(a)},pseudo:function(a){if(a[6]){a[6]=a[6].replace(/"/g,'\\"')}return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(a)},descendant:'c = "descendant";',child:'c = "child";',adjacent:'c = "adjacent";',laterSibling:'c = "laterSibling";'},patterns:{laterSibling:/^\s*~\s*/,child:/^\s*>\s*/,adjacent:/^\s*\+\s*/,descendant:/^\s/,tagName:/^\s*(\*|[\w\-]+)(\b|$)?/,id:/^#([\w\-\*]+)(\b|$)/,className:/^\.([\w\-\*]+)(\b|$)/,pseudo:/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,attrPresence:/^\[((?:[\w]+:)?[\w]+)\]/,attr:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/},assertions:{tagName:function(a,b){return b[1].toUpperCase()==a.tagName.toUpperCase()},className:function(a,b){return Element.hasClassName(a,b[1])},id:function(a,b){return a.id===b[1]},attrPresence:function(a,b){return Element.hasAttribute(a,b[1])},attr:function(b,c){var a=Element.readAttribute(b,c[1]);return a&&Selector.operators[c[2]](a,c[5]||c[6])}},handlers:{concat:function(d,c){for(var e=0,f;f=c[e];e++){d.push(f)}return d},mark:function(a){var d=Prototype.emptyFunction;for(var b=0,c;c=a[b];b++){c._countedByPrototype=d}return a},unmark:function(a){for(var b=0,c;c=a[b];b++){c._countedByPrototype=undefined}return a},index:function(a,d,g){a._countedByPrototype=Prototype.emptyFunction;if(d){for(var b=a.childNodes,e=b.length-1,c=1;e>=0;e--){var f=b[e];if(f.nodeType==1&&(!g||f._countedByPrototype)){f.nodeIndex=c++}}}else{for(var e=0,c=1,b=a.childNodes;f=b[e];e++){if(f.nodeType==1&&(!g||f._countedByPrototype)){f.nodeIndex=c++}}}},unique:function(b){if(b.length==0){return b}var d=[],e;for(var c=0,a=b.length;c<a;c++){if(!(e=b[c])._countedByPrototype){e._countedByPrototype=Prototype.emptyFunction;d.push(Element.extend(e))}}return Selector.handlers.unmark(d)},descendant:function(a){var d=Selector.handlers;for(var c=0,b=[],e;e=a[c];c++){d.concat(b,e.getElementsByTagName("*"))}return b},child:function(a){var e=Selector.handlers;for(var d=0,c=[],f;f=a[d];d++){for(var b=0,g;g=f.childNodes[b];b++){if(g.nodeType==1&&g.tagName!="!"){c.push(g)}}}return c},adjacent:function(a){for(var c=0,b=[],e;e=a[c];c++){var d=this.nextElementSibling(e);if(d){b.push(d)}}return b},laterSibling:function(a){var d=Selector.handlers;for(var c=0,b=[],e;e=a[c];c++){d.concat(b,Element.nextSiblings(e))}return b},nextElementSibling:function(a){while(a=a.nextSibling){if(a.nodeType==1){return a}}return null},previousElementSibling:function(a){while(a=a.previousSibling){if(a.nodeType==1){return a}}return null},tagName:function(a,j,c,b){var k=c.toUpperCase();var e=[],g=Selector.handlers;if(a){if(b){if(b=="descendant"){for(var f=0,d;d=a[f];f++){g.concat(e,d.getElementsByTagName(c))}return e}else{a=this[b](a)}if(c=="*"){return a}}for(var f=0,d;d=a[f];f++){if(d.tagName.toUpperCase()===k){e.push(d)}}return e}else{return j.getElementsByTagName(c)}},id:function(b,a,j,f){var g=$(j),d=Selector.handlers;if(!g){return[]}if(!b&&a==document){return[g]}if(b){if(f){if(f=="child"){for(var c=0,e;e=b[c];c++){if(g.parentNode==e){return[g]}}}else{if(f=="descendant"){for(var c=0,e;e=b[c];c++){if(Element.descendantOf(g,e)){return[g]}}}else{if(f=="adjacent"){for(var c=0,e;e=b[c];c++){if(Selector.handlers.previousElementSibling(g)==e){return[g]}}}else{b=d[f](b)}}}}for(var c=0,e;e=b[c];c++){if(e==g){return[g]}}return[]}return(g&&Element.descendantOf(g,a))?[g]:[]},className:function(b,a,c,d){if(b&&d){b=this[d](b)}return Selector.handlers.byClassName(b,a,c)},byClassName:function(c,b,f){if(!c){c=Selector.handlers.descendant([b])}var h=" "+f+" ";for(var e=0,d=[],g,a;g=c[e];e++){a=g.className;if(a.length==0){continue}if(a==f||(" "+a+" ").include(h)){d.push(g)}}return d},attrPresence:function(c,b,a,g){if(!c){c=b.getElementsByTagName("*")}if(c&&g){c=this[g](c)}var e=[];for(var d=0,f;f=c[d];d++){if(Element.hasAttribute(f,a)){e.push(f)}}return e},attr:function(a,j,h,k,c,b){if(!a){a=j.getElementsByTagName("*")}if(a&&b){a=this[b](a)}var l=Selector.operators[c],f=[];for(var e=0,d;d=a[e];e++){var g=Element.readAttribute(d,h);if(g===null){continue}if(l(g,k)){f.push(d)}}return f},pseudo:function(b,c,e,a,d){if(b&&d){b=this[d](b)}if(!b){b=a.getElementsByTagName("*")}return Selector.pseudos[c](b,e,a)}},pseudos:{"first-child":function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(Selector.handlers.previousElementSibling(e)){continue}c.push(e)}return c},"last-child":function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(Selector.handlers.nextElementSibling(e)){continue}c.push(e)}return c},"only-child":function(b,g,a){var e=Selector.handlers;for(var d=0,c=[],f;f=b[d];d++){if(!e.previousElementSibling(f)&&!e.nextElementSibling(f)){c.push(f)}}return c},"nth-child":function(b,c,a){return Selector.pseudos.nth(b,c,a)},"nth-last-child":function(b,c,a){return Selector.pseudos.nth(b,c,a,true)},"nth-of-type":function(b,c,a){return Selector.pseudos.nth(b,c,a,false,true)},"nth-last-of-type":function(b,c,a){return Selector.pseudos.nth(b,c,a,true,true)},"first-of-type":function(b,c,a){return Selector.pseudos.nth(b,"1",a,false,true)},"last-of-type":function(b,c,a){return Selector.pseudos.nth(b,"1",a,true,true)},"only-of-type":function(b,d,a){var c=Selector.pseudos;return c["last-of-type"](c["first-of-type"](b,d,a),d,a)},getIndices:function(d,c,e){if(d==0){return c>0?[c]:[]}return $R(1,e).inject([],function(a,b){if(0==(b-c)%d&&(b-c)/d>=0){a.push(b)}return a})},nth:function(c,s,u,r,e){if(c.length==0){return[]}if(s=="even"){s="2n+0"}if(s=="odd"){s="2n+1"}var q=Selector.handlers,p=[],d=[],g;q.mark(c);for(var o=0,f;f=c[o];o++){if(!f.parentNode._countedByPrototype){q.index(f.parentNode,r,e);d.push(f.parentNode)}}if(s.match(/^\d+$/)){s=Number(s);for(var o=0,f;f=c[o];o++){if(f.nodeIndex==s){p.push(f)}}}else{if(g=s.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(g[1]=="-"){g[1]=-1}var v=g[1]?Number(g[1]):1;var t=g[2]?Number(g[2]):0;var w=Selector.pseudos.getIndices(v,t,c.length);for(var o=0,f,k=w.length;f=c[o];o++){for(var n=0;n<k;n++){if(f.nodeIndex==w[n]){p.push(f)}}}}}q.unmark(c);q.unmark(d);return p},empty:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(e.tagName=="!"||e.firstChild){continue}c.push(e)}return c},not:function(a,d,k){var g=Selector.handlers,l,c;var j=new Selector(d).findElements(k);g.mark(j);for(var f=0,e=[],b;b=a[f];f++){if(!b._countedByPrototype){e.push(b)}}g.unmark(j);return e},enabled:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(!e.disabled&&(!e.type||e.type!=="hidden")){c.push(e)}}return c},disabled:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(e.disabled){c.push(e)}}return c},checked:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(e.checked){c.push(e)}}return c}},operators:{"=":function(b,a){return b==a},"!=":function(b,a){return b!=a},"^=":function(b,a){return b==a||b&&b.startsWith(a)},"$=":function(b,a){return b==a||b&&b.endsWith(a)},"*=":function(b,a){return b==a||b&&b.include(a)},"$=":function(b,a){return b.endsWith(a)},"*=":function(b,a){return b.include(a)},"~=":function(b,a){return(" "+b+" ").include(" "+a+" ")},"|=":function(b,a){return("-"+(b||"").toUpperCase()+"-").include("-"+(a||"").toUpperCase()+"-")}},split:function(b){var a=[];b.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(c){a.push(c[1].strip())});return a},matchElements:function(f,g){var e=$$(g),d=Selector.handlers;d.mark(e);for(var c=0,b=[],a;a=f[c];c++){if(a._countedByPrototype){b.push(a)}}d.unmark(e);return b},findElement:function(b,c,a){if(Object.isNumber(c)){a=c;c=false}return Selector.matchElements(b,c||"*")[a||0]},findChildElements:function(e,g){g=Selector.split(g.join(","));var d=[],f=Selector.handlers;for(var c=0,b=g.length,a;c<b;c++){a=new Selector(g[c].strip());f.concat(d,a.findElements(e))}return(b>1)?f.unique(d):d}});if(Prototype.Browser.IE){Object.extend(Selector.handlers,{concat:function(d,c){for(var e=0,f;f=c[e];e++){if(f.tagName!=="!"){d.push(f)}}return d},unmark:function(a){for(var b=0,c;c=a[b];b++){c.removeAttribute("_countedByPrototype")}return a}})}function $$(){return Selector.findChildElements(document,$A(arguments))}var Form={reset:function(a){$(a).reset();return a},serializeElements:function(g,b){if(typeof b!="object"){b={hash:!!b}}else{if(Object.isUndefined(b.hash)){b.hash=true}}var c,f,a=false,e=b.submit;var d=g.inject({},function(h,i){if(!i.disabled&&i.name){c=i.name;f=$(i).getValue();if(f!=null&&i.type!="file"&&(i.type!="submit"||(!a&&e!==false&&(!e||c==e)&&(a=true)))){if(c in h){if(!Object.isArray(h[c])){h[c]=[h[c]]}h[c].push(f)}else{h[c]=f}}}return h});return b.hash?d:Object.toQueryString(d)}};Form.Methods={serialize:function(b,a){return Form.serializeElements(Form.getElements(b),a)},getElements:function(a){return $A($(a).getElementsByTagName("*")).inject([],function(b,c){if(Form.Element.Serializers[c.tagName.toLowerCase()]){b.push(Element.extend(c))}return b})},getInputs:function(g,c,d){g=$(g);var a=g.getElementsByTagName("input");if(!c&&!d){return $A(a).map(Element.extend)}for(var e=0,h=[],f=a.length;e<f;e++){var b=a[e];if((c&&b.type!=c)||(d&&b.name!=d)){continue}h.push(Element.extend(b))}return h},disable:function(a){a=$(a);Form.getElements(a).invoke("disable");return a},enable:function(a){a=$(a);Form.getElements(a).invoke("enable");return a},findFirstElement:function(b){var c=$(b).getElements().findAll(function(d){return"hidden"!=d.type&&!d.disabled});var a=c.findAll(function(d){return d.hasAttribute("tabIndex")&&d.tabIndex>=0}).sortBy(function(d){return d.tabIndex}).first();return a?a:c.find(function(d){return["input","select","textarea"].include(d.tagName.toLowerCase())})},focusFirstElement:function(a){a=$(a);a.findFirstElement().activate();return a},request:function(b,a){b=$(b),a=Object.clone(a||{});var d=a.parameters,c=b.readAttribute("action")||"";if(c.blank()){c=window.location.href}a.parameters=b.serialize(true);if(d){if(Object.isString(d)){d=d.toQueryParams()}Object.extend(a.parameters,d)}if(b.hasAttribute("method")&&!a.method){a.method=b.method}return new Ajax.Request(c,a)}};Form.Element={focus:function(a){$(a).focus();return a},select:function(a){$(a).select();return a}};Form.Element.Methods={serialize:function(a){a=$(a);if(!a.disabled&&a.name){var b=a.getValue();if(b!=undefined){var c={};c[a.name]=b;return Object.toQueryString(c)}}return""},getValue:function(a){a=$(a);var b=a.tagName.toLowerCase();return Form.Element.Serializers[b](a)},setValue:function(a,b){a=$(a);var c=a.tagName.toLowerCase();Form.Element.Serializers[c](a,b);return a},clear:function(a){$(a).value="";return a},present:function(a){return $(a).value!=""},activate:function(a){a=$(a);try{a.focus();if(a.select&&(a.tagName.toLowerCase()!="input"||!["button","reset","submit"].include(a.type))){a.select()}}catch(b){}return a},disable:function(a){a=$(a);a.disabled=true;return a},enable:function(a){a=$(a);a.disabled=false;return a}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers={input:function(a,b){switch(a.type.toLowerCase()){case"checkbox":case"radio":return Form.Element.Serializers.inputSelector(a,b);default:return Form.Element.Serializers.textarea(a,b)}},inputSelector:function(a,b){if(Object.isUndefined(b)){return a.checked?a.value:null}else{a.checked=!!b}},textarea:function(a,b){if(Object.isUndefined(b)){return a.value}else{a.value=b}},select:function(c,f){if(Object.isUndefined(f)){return this[c.type=="select-one"?"selectOne":"selectMany"](c)}else{var b,d,g=!Object.isArray(f);for(var a=0,e=c.length;a<e;a++){b=c.options[a];d=this.optionValue(b);if(g){if(d==f){b.selected=true;return}}else{b.selected=f.include(d)}}}},selectOne:function(b){var a=b.selectedIndex;return a>=0?this.optionValue(b.options[a]):null},selectMany:function(d){var a,e=d.length;if(!e){return null}for(var c=0,a=[];c<e;c++){var b=d.options[c];if(b.selected){a.push(this.optionValue(b))}}return a},optionValue:function(a){return Element.extend(a).hasAttribute("value")?a.value:a.text}};Abstract.TimedObserver=Class.create(PeriodicalExecuter,{initialize:function($super,a,b,c){$super(c,b);this.element=$(a);this.lastValue=this.getValue()},execute:function(){var a=this.getValue();if(Object.isString(this.lastValue)&&Object.isString(a)?this.lastValue!=a:String(this.lastValue)!=String(a)){this.callback(this.element,a);this.lastValue=a}}});Form.Element.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.serialize(this.element)}});Abstract.EventObserver=Class.create({initialize:function(a,b){this.element=$(a);this.callback=b;this.lastValue=this.getValue();if(this.element.tagName.toLowerCase()=="form"){this.registerFormCallbacks()}else{this.registerCallback(this.element)}},onElementEvent:function(){var a=this.getValue();if(this.lastValue!=a){this.callback(this.element,a);this.lastValue=a}},registerFormCallbacks:function(){Form.getElements(this.element).each(this.registerCallback,this)},registerCallback:function(a){if(a.type){switch(a.type.toLowerCase()){case"checkbox":case"radio":Event.observe(a,"click",this.onElementEvent.bind(this));break;default:Event.observe(a,"change",this.onElementEvent.bind(this));break}}}});Form.Element.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.serialize(this.element)}});if(!window.Event){var Event={}}Object.extend(Event,{KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,KEY_INSERT:45,cache:{},relatedTarget:function(b){var a;switch(b.type){case"mouseover":a=b.fromElement;break;case"mouseout":a=b.toElement;break;default:return null}return Element.extend(a)}});Event.Methods=(function(){var a;if(Prototype.Browser.IE){var b={0:1,1:4,2:2};a=function(d,c){return d.button==b[c]}}else{if(Prototype.Browser.WebKit){a=function(d,c){switch(c){case 0:return d.which==1&&!d.metaKey;case 1:return d.which==1&&d.metaKey;default:return false}}}else{a=function(d,c){return d.which?(d.which===c+1):(d.button===c)}}}return{isLeftClick:function(c){return a(c,0)},isMiddleClick:function(c){return a(c,1)},isRightClick:function(c){return a(c,2)},element:function(e){e=Event.extend(e);var d=e.target,c=e.type,f=e.currentTarget;if(f&&f.tagName){if(c==="load"||c==="error"||(c==="click"&&f.tagName.toLowerCase()==="input"&&f.type==="radio")){d=f}}if(d.nodeType==Node.TEXT_NODE){d=d.parentNode}return Element.extend(d)},findElement:function(d,f){var c=Event.element(d);if(!f){return c}var e=[c].concat(c.ancestors());return Selector.findElement(e,f,0)},pointer:function(e){var d=document.documentElement,c=document.body||{scrollLeft:0,scrollTop:0};return{x:e.pageX||(e.clientX+(d.scrollLeft||c.scrollLeft)-(d.clientLeft||0)),y:e.pageY||(e.clientY+(d.scrollTop||c.scrollTop)-(d.clientTop||0))}},pointerX:function(c){return Event.pointer(c).x},pointerY:function(c){return Event.pointer(c).y},stop:function(c){Event.extend(c);c.preventDefault();c.stopPropagation();c.stopped=true}}})();Event.extend=(function(){var a=Object.keys(Event.Methods).inject({},function(b,c){b[c]=Event.Methods[c].methodize();return b});if(Prototype.Browser.IE){Object.extend(a,{stopPropagation:function(){this.cancelBubble=true},preventDefault:function(){this.returnValue=false},inspect:function(){return"[object Event]"}});return function(b){if(!b){return false}if(b._extendedByPrototype){return b}b._extendedByPrototype=Prototype.emptyFunction;var c=Event.pointer(b);Object.extend(b,{target:b.srcElement,relatedTarget:Event.relatedTarget(b),pageX:c.x,pageY:c.y});return Object.extend(b,a)}}else{Event.prototype=Event.prototype||document.createEvent("HTMLEvents")["__proto__"];Object.extend(Event.prototype,a);return Prototype.K}})();Object.extend(Event,(function(){var b=Event.cache;function c(j){if(j._prototypeEventID){return j._prototypeEventID[0]}arguments.callee.id=arguments.callee.id||1;return j._prototypeEventID=[++arguments.callee.id]}function g(j){if(j&&j.include(":")){return"dataavailable"}return j}function a(j){return b[j]=b[j]||{}}function f(l,j){var k=a(l);return k[j]=k[j]||[]}function h(k,j,l){var o=c(k);var n=f(o,j);if(n.pluck("handler").include(l)){return false}var m=function(p){if(!Event||!Event.extend||(p.eventName&&p.eventName!=j)){return false}Event.extend(p);l.call(k,p)};m.handler=l;n.push(m);return m}function i(m,j,k){var l=f(m,j);return l.find(function(n){return n.handler==k})}function d(m,j,k){var l=a(m);if(!l[j]){return false}l[j]=l[j].without(i(m,j,k))}function e(){for(var k in b){for(var j in b[k]){b[k][j]=null}}}if(window.attachEvent){window.attachEvent("onunload",e)}if(Prototype.Browser.WebKit){window.addEventListener("unload",Prototype.emptyFunction,false)}return{observe:function(l,j,m){l=$(l);var k=g(j);var n=h(l,j,m);if(!n){return l}if(l.addEventListener){l.addEventListener(k,n,false)}else{l.attachEvent("on"+k,n)}return l},stopObserving:function(l,j,m){l=$(l);var o=c(l),k=g(j);if(!m&&j){f(o,j).each(function(p){l.stopObserving(j,p.handler)});return l}else{if(!j){Object.keys(a(o)).each(function(p){l.stopObserving(p)});return l}}var n=i(o,j,m);if(!n){return l}if(l.removeEventListener){l.removeEventListener(k,n,false)}else{l.detachEvent("on"+k,n)}d(o,j,m);return l},fire:function(l,k,j){l=$(l);if(l==document&&document.createEvent&&!l.dispatchEvent){l=document.documentElement}var m;if(document.createEvent){m=document.createEvent("HTMLEvents");m.initEvent("dataavailable",true,true)}else{m=document.createEventObject();m.eventType="ondataavailable"}m.eventName=k;m.memo=j||{};if(document.createEvent){l.dispatchEvent(m)}else{l.fireEvent(m.eventType,m)}return Event.extend(m)}}})());Object.extend(Event,Event.Methods);Element.addMethods({fire:Event.fire,observe:Event.observe,stopObserving:Event.stopObserving});Object.extend(document,{fire:Element.Methods.fire.methodize(),observe:Element.Methods.observe.methodize(),stopObserving:Element.Methods.stopObserving.methodize(),loaded:false});(function(){var b;function a(){if(document.loaded){return}if(b){window.clearInterval(b)}document.fire("dom:loaded");document.loaded=true}if(document.addEventListener){if(Prototype.Browser.WebKit){b=window.setInterval(function(){if(/loaded|complete/.test(document.readyState)){a()}},0);Event.observe(window,"load",a)}else{document.addEventListener("DOMContentLoaded",a,false)}}else{document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");$("__onDOMContentLoaded").onreadystatechange=function(){if(this.readyState=="complete"){this.onreadystatechange=null;a()}}}})();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(a,b){return Element.insert(a,{before:b})},Top:function(a,b){return Element.insert(a,{top:b})},Bottom:function(a,b){return Element.insert(a,{bottom:b})},After:function(a,b){return Element.insert(a,{after:b})}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},within:function(b,a,c){if(this.includeScrollOffsets){return this.withinIncludingScrolloffsets(b,a,c)}this.xcomp=a;this.ycomp=c;this.offset=Element.cumulativeOffset(b);return(c>=this.offset[1]&&c<this.offset[1]+b.offsetHeight&&a>=this.offset[0]&&a<this.offset[0]+b.offsetWidth)},withinIncludingScrolloffsets:function(b,a,d){var c=Element.cumulativeScrollOffset(b);this.xcomp=a+c[0]-this.deltaX;this.ycomp=d+c[1]-this.deltaY;this.offset=Element.cumulativeOffset(b);return(this.ycomp>=this.offset[1]&&this.ycomp<this.offset[1]+b.offsetHeight&&this.xcomp>=this.offset[0]&&this.xcomp<this.offset[0]+b.offsetWidth)},overlap:function(b,a){if(!b){return 0}if(b=="vertical"){return((this.offset[1]+a.offsetHeight)-this.ycomp)/a.offsetHeight}if(b=="horizontal"){return((this.offset[0]+a.offsetWidth)-this.xcomp)/a.offsetWidth}},cumulativeOffset:Element.Methods.cumulativeOffset,positionedOffset:Element.Methods.positionedOffset,absolutize:function(a){Position.prepare();return Element.absolutize(a)},relativize:function(a){Position.prepare();return Element.relativize(a)},realOffset:Element.Methods.cumulativeScrollOffset,offsetParent:Element.Methods.getOffsetParent,page:Element.Methods.viewportOffset,clone:function(b,c,a){a=a||{};return Element.clonePosition(c,b,a)}};if(!document.getElementsByClassName){document.getElementsByClassName=function(b){function a(c){return c.blank()?null:"[contains(concat(' ', @class, ' '), ' "+c+" ')]"}b.getElementsByClassName=Prototype.BrowserFeatures.XPath?function(c,e){e=e.toString().strip();var d=/\s/.test(e)?$w(e).map(a).join(""):a(e);return d?document._getElementsByXPath(".//*"+d,c):[]}:function(e,f){f=f.toString().strip();var g=[],h=(/\s/.test(f)?$w(f):null);if(!h&&!f){return g}var c=$(e).getElementsByTagName("*");f=" "+f+" ";for(var d=0,k,j;k=c[d];d++){if(k.className&&(j=" "+k.className+" ")&&(j.include(f)||(h&&h.all(function(i){return!i.toString().blank()&&j.include(" "+i+" ")})))){g.push(Element.extend(k))}}return g};return function(d,c){return $(c||document.body).getElementsByClassName(d)}}(Element.Methods)}Element.ClassNames=Class.create();Element.ClassNames.prototype={initialize:function(a){this.element=$(a)},_each:function(a){this.element.className.split(/\s+/).select(function(b){return b.length>0})._each(a)},set:function(a){this.element.className=a},add:function(a){if(this.include(a)){return}this.set($A(this).concat(a).join(" "))},remove:function(a){if(!this.include(a)){return}this.set($A(this).without(a).join(" "))},toString:function(){return $A(this).join(" ")}};Object.extend(Element.ClassNames.prototype,Enumerable);Element.addMethods();
\ No newline at end of file
+var Prototype={Version:"1.6.1",Browser:(function(){var b=navigator.userAgent;var a=Object.prototype.toString.call(window.opera)=="[object Opera]";return{IE:!!window.attachEvent&&!a,Opera:a,WebKit:b.indexOf("AppleWebKit/")>-1,Gecko:b.indexOf("Gecko")>-1&&b.indexOf("KHTML")===-1,MobileSafari:/Apple.*Mobile.*Safari/.test(b)}})(),BrowserFeatures:{XPath:!!document.evaluate,SelectorsAPI:!!document.querySelector,ElementExtensions:(function(){var a=window.Element||window.HTMLElement;return!!(a&&a.prototype)})(),SpecificElementExtensions:(function(){if(typeof window.HTMLDivElement!=="undefined"){return true}var c=document.createElement("div");var b=document.createElement("form");var a=false;if(c.__proto__&&(c.__proto__!==b.__proto__)){a=true}c=b=null;return a})()},ScriptFragment:"<script[^>]*>([\\S\\s]*?)<\/script>",JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,emptyFunction:function(){},K:function(a){return a}};if(Prototype.Browser.MobileSafari){Prototype.BrowserFeatures.SpecificElementExtensions=false}var Abstract={};var Try={these:function(){var c;for(var b=0,d=arguments.length;b<d;b++){var a=arguments[b];try{c=a();break}catch(f){}}return c}};var Class=(function(){function a(){}function b(){var g=null,f=$A(arguments);if(Object.isFunction(f[0])){g=f.shift()}function d(){this.initialize.apply(this,arguments)}Object.extend(d,Class.Methods);d.superclass=g;d.subclasses=[];if(g){a.prototype=g.prototype;d.prototype=new a;g.subclasses.push(d)}for(var e=0;e<f.length;e++){d.addMethods(f[e])}if(!d.prototype.initialize){d.prototype.initialize=Prototype.emptyFunction}d.prototype.constructor=d;return d}function c(k){var f=this.superclass&&this.superclass.prototype;var e=Object.keys(k);if(!Object.keys({toString:true}).length){if(k.toString!=Object.prototype.toString){e.push("toString")}if(k.valueOf!=Object.prototype.valueOf){e.push("valueOf")}}for(var d=0,g=e.length;d<g;d++){var j=e[d],h=k[j];if(f&&Object.isFunction(h)&&h.argumentNames().first()=="$super"){var l=h;h=(function(i){return function(){return f[i].apply(this,arguments)}})(j).wrap(l);h.valueOf=l.valueOf.bind(l);h.toString=l.toString.bind(l)}this.prototype[j]=h}return this}return{create:b,Methods:{addMethods:c}}})();(function(){var d=Object.prototype.toString;function i(q,s){for(var r in s){q[r]=s[r]}return q}function l(q){try{if(e(q)){return"undefined"}if(q===null){return"null"}return q.inspect?q.inspect():String(q)}catch(r){if(r instanceof RangeError){return"..."}throw r}}function k(q){var s=typeof q;switch(s){case"undefined":case"function":case"unknown":return;case"boolean":return q.toString()}if(q===null){return"null"}if(q.toJSON){return q.toJSON()}if(h(q)){return}var r=[];for(var u in q){var t=k(q[u]);if(!e(t)){r.push(u.toJSON()+": "+t)}}return"{"+r.join(", ")+"}"}function c(q){return $H(q).toQueryString()}function f(q){return q&&q.toHTML?q.toHTML():String.interpret(q)}function o(q){var r=[];for(var s in q){r.push(s)}return r}function m(q){var r=[];for(var s in q){r.push(q[s])}return r}function j(q){return i({},q)}function h(q){return!!(q&&q.nodeType==1)}function g(q){return d.call(q)=="[object Array]"}function p(q){return q instanceof Hash}function b(q){return typeof q==="function"}function a(q){return d.call(q)=="[object String]"}function n(q){return d.call(q)=="[object Number]"}function e(q){return typeof q==="undefined"}i(Object,{extend:i,inspect:l,toJSON:k,toQueryString:c,toHTML:f,keys:o,values:m,clone:j,isElement:h,isArray:g,isHash:p,isFunction:b,isString:a,isNumber:n,isUndefined:e})})();Object.extend(Function.prototype,(function(){var k=Array.prototype.slice;function d(o,l){var n=o.length,m=l.length;while(m--){o[n+m]=l[m]}return o}function i(m,l){m=k.call(m,0);return d(m,l)}function g(){var l=this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g,"").replace(/\s+/g,"").split(",");return l.length==1&&!l[0]?[]:l}function h(n){if(arguments.length<2&&Object.isUndefined(arguments[0])){return this}var l=this,m=k.call(arguments,1);return function(){var o=i(m,arguments);return l.apply(n,o)}}function f(n){var l=this,m=k.call(arguments,1);return function(p){var o=d([p||window.event],m);return l.apply(n,o)}}function j(){if(!arguments.length){return this}var l=this,m=k.call(arguments,0);return function(){var n=i(m,arguments);return l.apply(this,n)}}function e(n){var l=this,m=k.call(arguments,1);n=n*1000;return window.setTimeout(function(){return l.apply(l,m)},n)}function a(){var l=d([0.01],arguments);return this.delay.apply(this,l)}function c(m){var l=this;return function(){var n=d([l.bind(this)],arguments);return m.apply(this,n)}}function b(){if(this._methodized){return this._methodized}var l=this;return this._methodized=function(){var m=d([this],arguments);return l.apply(null,m)}}return{argumentNames:g,bind:h,bindAsEventListener:f,curry:j,delay:e,defer:a,wrap:c,methodize:b}})());Date.prototype.toJSON=function(){return'"'+this.getUTCFullYear()+"-"+(this.getUTCMonth()+1).toPaddedString(2)+"-"+this.getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString(2)+":"+this.getUTCMinutes().toPaddedString(2)+":"+this.getUTCSeconds().toPaddedString(2)+'Z"'};RegExp.prototype.match=RegExp.prototype.test;RegExp.escape=function(a){return String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")};var PeriodicalExecuter=Class.create({initialize:function(b,a){this.callback=b;this.frequency=a;this.currentlyExecuting=false;this.registerCallback()},registerCallback:function(){this.timer=setInterval(this.onTimerEvent.bind(this),this.frequency*1000)},execute:function(){this.callback(this)},stop:function(){if(!this.timer){return}clearInterval(this.timer);this.timer=null},onTimerEvent:function(){if(!this.currentlyExecuting){try{this.currentlyExecuting=true;this.execute();this.currentlyExecuting=false}catch(a){this.currentlyExecuting=false;throw a}}}});Object.extend(String,{interpret:function(a){return a==null?"":String(a)},specialChar:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r","\\":"\\\\"}});Object.extend(String.prototype,(function(){function prepareReplacement(replacement){if(Object.isFunction(replacement)){return replacement}var template=new Template(replacement);return function(match){return template.evaluate(match)}}function gsub(pattern,replacement){var result="",source=this,match;replacement=prepareReplacement(replacement);if(Object.isString(pattern)){pattern=RegExp.escape(pattern)}if(!(pattern.length||pattern.source)){replacement=replacement("");return replacement+source.split("").join(replacement)+replacement}while(source.length>0){if(match=source.match(pattern)){result+=source.slice(0,match.index);result+=String.interpret(replacement(match));source=source.slice(match.index+match[0].length)}else{result+=source,source=""}}return result}function sub(pattern,replacement,count){replacement=prepareReplacement(replacement);count=Object.isUndefined(count)?1:count;return this.gsub(pattern,function(match){if(--count<0){return match[0]}return replacement(match)})}function scan(pattern,iterator){this.gsub(pattern,iterator);return String(this)}function truncate(length,truncation){length=length||30;truncation=Object.isUndefined(truncation)?"...":truncation;return this.length>length?this.slice(0,length-truncation.length)+truncation:String(this)}function strip(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}function stripTags(){return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi,"")}function stripScripts(){return this.replace(new RegExp(Prototype.ScriptFragment,"img"),"")}function extractScripts(){var matchAll=new RegExp(Prototype.ScriptFragment,"img");var matchOne=new RegExp(Prototype.ScriptFragment,"im");return(this.match(matchAll)||[]).map(function(scriptTag){return(scriptTag.match(matchOne)||["",""])[1]})}function evalScripts(){return this.extractScripts().map(function(script){return eval(script)})}function escapeHTML(){return this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function unescapeHTML(){return this.stripTags().replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&")}function toQueryParams(separator){var match=this.strip().match(/([^?#]*)(#.*)?$/);if(!match){return{}}return match[1].split(separator||"&").inject({},function(hash,pair){if((pair=pair.split("="))[0]){var key=decodeURIComponent(pair.shift());var value=pair.length>1?pair.join("="):pair[0];if(value!=undefined){value=decodeURIComponent(value)}if(key in hash){if(!Object.isArray(hash[key])){hash[key]=[hash[key]]}hash[key].push(value)}else{hash[key]=value}}return hash})}function toArray(){return this.split("")}function succ(){return this.slice(0,this.length-1)+String.fromCharCode(this.charCodeAt(this.length-1)+1)}function times(count){return count<1?"":new Array(count+1).join(this)}function camelize(){var parts=this.split("-"),len=parts.length;if(len==1){return parts[0]}var camelized=this.charAt(0)=="-"?parts[0].charAt(0).toUpperCase()+parts[0].substring(1):parts[0];for(var i=1;i<len;i++){camelized+=parts[i].charAt(0).toUpperCase()+parts[i].substring(1)}return camelized}function capitalize(){return this.charAt(0).toUpperCase()+this.substring(1).toLowerCase()}function underscore(){return this.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/-/g,"_").toLowerCase()}function dasherize(){return this.replace(/_/g,"-")}function inspect(useDoubleQuotes){var escapedString=this.replace(/[\x00-\x1f\\]/g,function(character){if(character in String.specialChar){return String.specialChar[character]}return"\\u00"+character.charCodeAt().toPaddedString(2,16)});if(useDoubleQuotes){return'"'+escapedString.replace(/"/g,'\\"')+'"'}return"'"+escapedString.replace(/'/g,"\\'")+"'"}function toJSON(){return this.inspect(true)}function unfilterJSON(filter){return this.replace(filter||Prototype.JSONFilter,"$1")}function isJSON(){var str=this;if(str.blank()){return false}str=this.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,"");return(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str)}function evalJSON(sanitize){var json=this.unfilterJSON();try{if(!sanitize||json.isJSON()){return eval("("+json+")")}}catch(e){}throw new SyntaxError("Badly formed JSON string: "+this.inspect())}function include(pattern){return this.indexOf(pattern)>-1}function startsWith(pattern){return this.indexOf(pattern)===0}function endsWith(pattern){var d=this.length-pattern.length;return d>=0&&this.lastIndexOf(pattern)===d}function empty(){return this==""}function blank(){return/^\s*$/.test(this)}function interpolate(object,pattern){return new Template(this,pattern).evaluate(object)}return{gsub:gsub,sub:sub,scan:scan,truncate:truncate,strip:String.prototype.trim?String.prototype.trim:strip,stripTags:stripTags,stripScripts:stripScripts,extractScripts:extractScripts,evalScripts:evalScripts,escapeHTML:escapeHTML,unescapeHTML:unescapeHTML,toQueryParams:toQueryParams,parseQuery:toQueryParams,toArray:toArray,succ:succ,times:times,camelize:camelize,capitalize:capitalize,underscore:underscore,dasherize:dasherize,inspect:inspect,toJSON:toJSON,unfilterJSON:unfilterJSON,isJSON:isJSON,evalJSON:evalJSON,include:include,startsWith:startsWith,endsWith:endsWith,empty:empty,blank:blank,interpolate:interpolate}})());var Template=Class.create({initialize:function(a,b){this.template=a.toString();this.pattern=b||Template.Pattern},evaluate:function(a){if(a&&Object.isFunction(a.toTemplateReplacements)){a=a.toTemplateReplacements()}return this.template.gsub(this.pattern,function(d){if(a==null){return(d[1]+"")}var f=d[1]||"";if(f=="\\"){return d[2]}var b=a,g=d[3];var e=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;d=e.exec(g);if(d==null){return f}while(d!=null){var c=d[1].startsWith("[")?d[2].replace(/\\\\]/g,"]"):d[1];b=b[c];if(null==b||""==d[3]){break}g=g.substring("["==d[3]?d[1].length:d[0].length);d=e.exec(g)}return f+String.interpret(b)})}});Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;var $break={};var Enumerable=(function(){function c(y,x){var w=0;try{this._each(function(A){y.call(x,A,w++)})}catch(z){if(z!=$break){throw z}}return this}function r(z,y,x){var w=-z,A=[],B=this.toArray();if(z<1){return B}while((w+=z)<B.length){A.push(B.slice(w,w+z))}return A.collect(y,x)}function b(y,x){y=y||Prototype.K;var w=true;this.each(function(A,z){w=w&&!!y.call(x,A,z);if(!w){throw $break}});return w}function i(y,x){y=y||Prototype.K;var w=false;this.each(function(A,z){if(w=!!y.call(x,A,z)){throw $break}});return w}function j(y,x){y=y||Prototype.K;var w=[];this.each(function(A,z){w.push(y.call(x,A,z))});return w}function t(y,x){var w;this.each(function(A,z){if(y.call(x,A,z)){w=A;throw $break}});return w}function h(y,x){var w=[];this.each(function(A,z){if(y.call(x,A,z)){w.push(A)}});return w}function g(z,y,x){y=y||Prototype.K;var w=[];if(Object.isString(z)){z=new RegExp(RegExp.escape(z))}this.each(function(B,A){if(z.match(B)){w.push(y.call(x,B,A))}});return w}function a(w){if(Object.isFunction(this.indexOf)){if(this.indexOf(w)!=-1){return true}}var x=false;this.each(function(y){if(y==w){x=true;throw $break}});return x}function q(x,w){w=Object.isUndefined(w)?null:w;return this.eachSlice(x,function(y){while(y.length<x){y.push(w)}return y})}function l(w,y,x){this.each(function(A,z){w=y.call(x,w,A,z)});return w}function v(x){var w=$A(arguments).slice(1);return this.map(function(y){return y[x].apply(y,w)})}function p(y,x){y=y||Prototype.K;var w;this.each(function(A,z){A=y.call(x,A,z);if(w==null||A>=w){w=A}});return w}function n(y,x){y=y||Prototype.K;var w;this.each(function(A,z){A=y.call(x,A,z);if(w==null||A<w){w=A}});return w}function e(z,x){z=z||Prototype.K;var y=[],w=[];this.each(function(B,A){(z.call(x,B,A)?y:w).push(B)});return[y,w]}function f(x){var w=[];this.each(function(y){w.push(y[x])});return w}function d(y,x){var w=[];this.each(function(A,z){if(!y.call(x,A,z)){w.push(A)}});return w}function m(x,w){return this.map(function(z,y){return{value:z,criteria:x.call(w,z,y)}}).sort(function(B,A){var z=B.criteria,y=A.criteria;return z<y?-1:z>y?1:0}).pluck("value")}function o(){return this.map()}function s(){var x=Prototype.K,w=$A(arguments);if(Object.isFunction(w.last())){x=w.pop()}var y=[this].concat(w).map($A);return this.map(function(A,z){return x(y.pluck(z))})}function k(){return this.toArray().length}function u(){return"#<Enumerable:"+this.toArray().inspect()+">"}return{each:c,eachSlice:r,all:b,every:b,any:i,some:i,collect:j,map:j,detect:t,findAll:h,select:h,filter:h,grep:g,include:a,member:a,inGroupsOf:q,inject:l,invoke:v,max:p,min:n,partition:e,pluck:f,reject:d,sortBy:m,toArray:o,entries:o,zip:s,size:k,inspect:u,find:t}})();function $A(c){if(!c){return[]}if("toArray"in Object(c)){return c.toArray()}var b=c.length||0,a=new Array(b);while(b--){a[b]=c[b]}return a}function $w(a){if(!Object.isString(a)){return[]}a=a.strip();return a?a.split(/\s+/):[]}Array.from=$A;(function(){var s=Array.prototype,m=s.slice,o=s.forEach;function b(w){for(var v=0,x=this.length;v<x;v++){w(this[v])}}if(!o){o=b}function l(){this.length=0;return this}function d(){return this[0]}function g(){return this[this.length-1]}function i(){return this.select(function(v){return v!=null})}function u(){return this.inject([],function(w,v){if(Object.isArray(v)){return w.concat(v.flatten())}w.push(v);return w})}function h(){var v=m.call(arguments,0);return this.select(function(w){return!v.include(w)})}function f(v){return(v!==false?this:this.toArray())._reverse()}function k(v){return this.inject([],function(y,x,w){if(0==w||(v?y.last()!=x:!y.include(x))){y.push(x)}return y})}function p(v){return this.uniq().findAll(function(w){return v.detect(function(x){return w===x})})}function q(){return m.call(this,0)}function j(){return this.length}function t(){return"["+this.map(Object.inspect).join(", ")+"]"}function r(){var v=[];this.each(function(w){var x=Object.toJSON(w);if(!Object.isUndefined(x)){v.push(x)}});return"["+v.join(", ")+"]"}function a(x,v){v||(v=0);var w=this.length;if(v<0){v=w+v}for(;v<w;v++){if(this[v]===x){return v}}return-1}function n(w,v){v=isNaN(v)?this.length:(v<0?this.length+v:v)+1;var x=this.slice(0,v).reverse().indexOf(w);return(x<0)?x:v-x-1}function c(){var A=m.call(this,0),y;for(var w=0,x=arguments.length;w<x;w++){y=arguments[w];if(Object.isArray(y)&&!("callee"in y)){for(var v=0,z=y.length;v<z;v++){A.push(y[v])}}else{A.push(y)}}return A}Object.extend(s,Enumerable);if(!s._reverse){s._reverse=s.reverse}Object.extend(s,{_each:o,clear:l,first:d,last:g,compact:i,flatten:u,without:h,reverse:f,uniq:k,intersect:p,clone:q,toArray:q,size:j,inspect:t,toJSON:r});var e=(function(){return[].concat(arguments)[0][0]!==1})(1,2);if(e){s.concat=c}if(!s.indexOf){s.indexOf=a}if(!s.lastIndexOf){s.lastIndexOf=n}})();function $H(a){return new Hash(a)}var Hash=Class.create(Enumerable,(function(){function e(q){this._object=Object.isHash(q)?q.toObject():Object.clone(q)}function f(r){for(var q in this._object){var s=this._object[q],t=[q,s];t.key=q;t.value=s;r(t)}}function k(q,r){return this._object[q]=r}function c(q){if(this._object[q]!==Object.prototype[q]){return this._object[q]}}function n(q){var r=this._object[q];delete this._object[q];return r}function p(){return Object.clone(this._object)}function o(){return this.pluck("key")}function m(){return this.pluck("value")}function g(r){var q=this.detect(function(s){return s.value===r});return q&&q.key}function i(q){return this.clone().update(q)}function d(q){return new Hash(q).inject(this,function(r,s){r.set(s.key,s.value);return r})}function b(q,r){if(Object.isUndefined(r)){return q}return q+"="+encodeURIComponent(String.interpret(r))}function a(){return this.inject([],function(s,t){var r=encodeURIComponent(t.key),q=t.value;if(q&&typeof q=="object"){if(Object.isArray(q)){return s.concat(q.map(b.curry(r)))}}else{s.push(b(r,q))}return s}).join("&")}function l(){return"#<Hash:{"+this.map(function(q){return q.map(Object.inspect).join(": ")}).join(", ")+"}>"}function j(){return Object.toJSON(this.toObject())}function h(){return new Hash(this)}return{initialize:e,_each:f,set:k,get:c,unset:n,toObject:p,toTemplateReplacements:p,keys:o,values:m,index:g,merge:i,update:d,toQueryString:a,inspect:l,toJSON:j,clone:h}})());Hash.from=$H;Object.extend(Number.prototype,(function(){function d(){return this.toPaddedString(2,16)}function e(){return this+1}function a(k,j){$R(0,this,true).each(k,j);return this}function b(l,k){var j=this.toString(k||10);return"0".times(l-j.length)+j}function f(){return isFinite(this)?this.toString():"null"}function i(){return Math.abs(this)}function h(){return Math.round(this)}function g(){return Math.ceil(this)}function c(){return Math.floor(this)}return{toColorPart:d,succ:e,times:a,toPaddedString:b,toJSON:f,abs:i,round:h,ceil:g,floor:c}})());function $R(c,a,b){return new ObjectRange(c,a,b)}var ObjectRange=Class.create(Enumerable,(function(){function b(f,d,e){this.start=f;this.end=d;this.exclusive=e}function c(d){var e=this.start;while(this.include(e)){d(e);e=e.succ()}}function a(d){if(d<this.start){return false}if(this.exclusive){return d<this.end}return d<=this.end}return{initialize:b,_each:c,include:a}})());var Ajax={getTransport:function(){return Try.these(function(){return new XMLHttpRequest()},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Microsoft.XMLHTTP")})||false},activeRequestCount:0};Ajax.Responders={responders:[],_each:function(a){this.responders._each(a)},register:function(a){if(!this.include(a)){this.responders.push(a)}},unregister:function(a){this.responders=this.responders.without(a)},dispatch:function(d,b,c,a){this.each(function(f){if(Object.isFunction(f[d])){try{f[d].apply(f,[b,c,a])}catch(g){}}})}};Object.extend(Ajax.Responders,Enumerable);Ajax.Responders.register({onCreate:function(){Ajax.activeRequestCount++},onComplete:function(){Ajax.activeRequestCount--}});Ajax.Base=Class.create({initialize:function(a){this.options={method:"post",asynchronous:true,contentType:"application/x-www-form-urlencoded",encoding:"UTF-8",parameters:"",evalJSON:true,evalJS:true};Object.extend(this.options,a||{});this.options.method=this.options.method.toLowerCase();if(Object.isString(this.options.parameters)){this.options.parameters=this.options.parameters.toQueryParams()}else{if(Object.isHash(this.options.parameters)){this.options.parameters=this.options.parameters.toObject()}}}});Ajax.Request=Class.create(Ajax.Base,{_complete:false,initialize:function($super,b,a){$super(a);this.transport=Ajax.getTransport();this.request(b)},request:function(b){this.url=b;this.method=this.options.method;var d=Object.clone(this.options.parameters);if(!["get","post"].include(this.method)){d._method=this.method;this.method="post"}this.parameters=d;if(d=Object.toQueryString(d)){if(this.method=="get"){this.url+=(this.url.include("?")?"&":"?")+d}else{if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)){d+="&_="}}}try{var a=new Ajax.Response(this);if(this.options.onCreate){this.options.onCreate(a)}Ajax.Responders.dispatch("onCreate",this,a);this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);if(this.options.asynchronous){this.respondToReadyState.bind(this).defer(1)}this.transport.onreadystatechange=this.onStateChange.bind(this);this.setRequestHeaders();this.body=this.method=="post"?(this.options.postBody||d):null;this.transport.send(this.body);if(!this.options.asynchronous&&this.transport.overrideMimeType){this.onStateChange()}}catch(c){this.dispatchException(c)}},onStateChange:function(){var a=this.transport.readyState;if(a>1&&!((a==4)&&this._complete)){this.respondToReadyState(this.transport.readyState)}},setRequestHeaders:function(){var e={"X-Requested-With":"XMLHttpRequest","X-Prototype-Version":Prototype.Version,Accept:"text/javascript, text/html, application/xml, text/xml, */*"};if(this.method=="post"){e["Content-type"]=this.options.contentType+(this.options.encoding?"; charset="+this.options.encoding:"");if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){e.Connection="close"}}if(typeof this.options.requestHeaders=="object"){var c=this.options.requestHeaders;if(Object.isFunction(c.push)){for(var b=0,d=c.length;b<d;b+=2){e[c[b]]=c[b+1]}}else{$H(c).each(function(f){e[f.key]=f.value})}}for(var a in e){this.transport.setRequestHeader(a,e[a])}},success:function(){var a=this.getStatus();return!a||(a>=200&&a<300)},getStatus:function(){try{return this.transport.status||0}catch(a){return 0}},respondToReadyState:function(a){var c=Ajax.Request.Events[a],b=new Ajax.Response(this);if(c=="Complete"){try{this._complete=true;(this.options["on"+b.status]||this.options["on"+(this.success()?"Success":"Failure")]||Prototype.emptyFunction)(b,b.headerJSON)}catch(d){this.dispatchException(d)}var f=b.getHeader("Content-type");if(this.options.evalJS=="force"||(this.options.evalJS&&this.isSameOrigin()&&f&&f.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))){this.evalResponse()}}try{(this.options["on"+c]||Prototype.emptyFunction)(b,b.headerJSON);Ajax.Responders.dispatch("on"+c,this,b,b.headerJSON)}catch(d){this.dispatchException(d)}if(c=="Complete"){this.transport.onreadystatechange=Prototype.emptyFunction}},isSameOrigin:function(){var a=this.url.match(/^\s*https?:\/\/[^\/]*/);return!a||(a[0]=="#{protocol}//#{domain}#{port}".interpolate({protocol:location.protocol,domain:document.domain,port:location.port?":"+location.port:""}))},getHeader:function(a){try{return this.transport.getResponseHeader(a)||null}catch(b){return null}},evalResponse:function(){try{return eval((this.transport.responseText||"").unfilterJSON())}catch(e){this.dispatchException(e)}},dispatchException:function(a){(this.options.onException||Prototype.emptyFunction)(this,a);Ajax.Responders.dispatch("onException",this,a)}});Ajax.Request.Events=["Uninitialized","Loading","Loaded","Interactive","Complete"];Ajax.Response=Class.create({initialize:function(c){this.request=c;var d=this.transport=c.transport,a=this.readyState=d.readyState;if((a>2&&!Prototype.Browser.IE)||a==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=String.interpret(d.responseText);this.headerJSON=this._getHeaderJSON()}if(a==4){var b=d.responseXML;this.responseXML=Object.isUndefined(b)?null:b;this.responseJSON=this._getResponseJSON()}},status:0,statusText:"",getStatus:Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||""}catch(a){return""}},getHeader:Ajax.Request.prototype.getHeader,getAllHeaders:function(){try{return this.getAllResponseHeaders()}catch(a){return null}},getResponseHeader:function(a){return this.transport.getResponseHeader(a)},getAllResponseHeaders:function(){return this.transport.getAllResponseHeaders()},_getHeaderJSON:function(){var a=this.getHeader("X-JSON");if(!a){return null}a=decodeURIComponent(escape(a));try{return a.evalJSON(this.request.options.sanitizeJSON||!this.request.isSameOrigin())}catch(b){this.request.dispatchException(b)}},_getResponseJSON:function(){var a=this.request.options;if(!a.evalJSON||(a.evalJSON!="force"&&!(this.getHeader("Content-type")||"").include("application/json"))||this.responseText.blank()){return null}try{return this.responseText.evalJSON(a.sanitizeJSON||!this.request.isSameOrigin())}catch(b){this.request.dispatchException(b)}}});Ajax.Updater=Class.create(Ajax.Request,{initialize:function($super,a,c,b){this.container={success:(a.success||a),failure:(a.failure||(a.success?null:a))};b=Object.clone(b);var d=b.onComplete;b.onComplete=(function(e,f){this.updateContent(e.responseText);if(Object.isFunction(d)){d(e,f)}}).bind(this);$super(c,b)},updateContent:function(d){var c=this.container[this.success()?"success":"failure"],a=this.options;if(!a.evalScripts){d=d.stripScripts()}if(c=$(c)){if(a.insertion){if(Object.isString(a.insertion)){var b={};b[a.insertion]=d;c.insert(b)}else{a.insertion(c,d)}}else{c.update(d)}}}});Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{initialize:function($super,a,c,b){$super(b);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=a;this.url=c;this.start()},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent()},stop:function(){this.updater.options.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments)},updateComplete:function(a){if(this.options.decay){this.decay=(a.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=a.responseText}this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency)},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options)}});function $(b){if(arguments.length>1){for(var a=0,d=[],c=arguments.length;a<c;a++){d.push($(arguments[a]))}return d}if(Object.isString(b)){b=document.getElementById(b)}return Element.extend(b)}if(Prototype.BrowserFeatures.XPath){document._getElementsByXPath=function(f,a){var c=[];var e=document.evaluate(f,$(a)||document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);for(var b=0,d=e.snapshotLength;b<d;b++){c.push(Element.extend(e.snapshotItem(b)))}return c}}if(!window.Node){var Node={}}if(!Node.ELEMENT_NODE){Object.extend(Node,{ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12})}(function(c){var b=(function(){var f=document.createElement("form");var e=document.createElement("input");var d=document.documentElement;e.setAttribute("name","test");f.appendChild(e);d.appendChild(f);var g=f.elements?(typeof f.elements.test=="undefined"):null;d.removeChild(f);f=e=null;return g})();var a=c.Element;c.Element=function(f,e){e=e||{};f=f.toLowerCase();var d=Element.cache;if(b&&e.name){f="<"+f+' name="'+e.name+'">';delete e.name;return Element.writeAttribute(document.createElement(f),e)}if(!d[f]){d[f]=Element.extend(document.createElement(f))}return Element.writeAttribute(d[f].cloneNode(false),e)};Object.extend(c.Element,a||{});if(a){c.Element.prototype=a.prototype}})(this);Element.cache={};Element.idCounter=1;Element.Methods={visible:function(a){return $(a).style.display!="none"},toggle:function(a){a=$(a);Element[Element.visible(a)?"hide":"show"](a);return a},hide:function(a){a=$(a);a.style.display="none";return a},show:function(a){a=$(a);a.style.display="";return a},remove:function(a){a=$(a);a.parentNode.removeChild(a);return a},update:(function(){var b=(function(){var e=document.createElement("select"),f=true;e.innerHTML='<option value="test">test</option>';if(e.options&&e.options[0]){f=e.options[0].nodeName.toUpperCase()!=="OPTION"}e=null;return f})();var a=(function(){try{var f=document.createElement("table");if(f&&f.tBodies){f.innerHTML="<tbody><tr><td>test</td></tr></tbody>";var h=typeof f.tBodies[0]=="undefined";f=null;return h}}catch(g){return true}})();var d=(function(){var f=document.createElement("script"),h=false;try{f.appendChild(document.createTextNode(""));h=!f.firstChild||f.firstChild&&f.firstChild.nodeType!==3}catch(g){h=true}f=null;return h})();function c(f,g){f=$(f);if(g&&g.toElement){g=g.toElement()}if(Object.isElement(g)){return f.update().insert(g)}g=Object.toHTML(g);var e=f.tagName.toUpperCase();if(e==="SCRIPT"&&d){f.text=g;return f}if(b||a){if(e in Element._insertionTranslations.tags){while(f.firstChild){f.removeChild(f.firstChild)}Element._getContentFromAnonymousElement(e,g.stripScripts()).each(function(h){f.appendChild(h)})}else{f.innerHTML=g.stripScripts()}}else{f.innerHTML=g.stripScripts()}g.evalScripts.bind(g).defer();return f}return c})(),replace:function(b,c){b=$(b);if(c&&c.toElement){c=c.toElement()}else{if(!Object.isElement(c)){c=Object.toHTML(c);var a=b.ownerDocument.createRange();a.selectNode(b);c.evalScripts.bind(c).defer();c=a.createContextualFragment(c.stripScripts())}}b.parentNode.replaceChild(c,b);return b},insert:function(c,e){c=$(c);if(Object.isString(e)||Object.isNumber(e)||Object.isElement(e)||(e&&(e.toElement||e.toHTML))){e={bottom:e}}var d,f,b,g;for(var a in e){d=e[a];a=a.toLowerCase();f=Element._insertionTranslations[a];if(d&&d.toElement){d=d.toElement()}if(Object.isElement(d)){f(c,d);continue}d=Object.toHTML(d);b=((a=="before"||a=="after")?c.parentNode:c).tagName.toUpperCase();g=Element._getContentFromAnonymousElement(b,d.stripScripts());if(a=="top"||a=="after"){g.reverse()}g.each(f.curry(c));d.evalScripts.bind(d).defer()}return c},wrap:function(b,c,a){b=$(b);if(Object.isElement(c)){$(c).writeAttribute(a||{})}else{if(Object.isString(c)){c=new Element(c,a)}else{c=new Element("div",c)}}if(b.parentNode){b.parentNode.replaceChild(c,b)}c.appendChild(b);return c},inspect:function(b){b=$(b);var a="<"+b.tagName.toLowerCase();$H({id:"id",className:"class"}).each(function(f){var e=f.first(),c=f.last();var d=(b[e]||"").toString();if(d){a+=" "+c+"="+d.inspect(true)}});return a+">"},recursivelyCollect:function(a,c){a=$(a);var b=[];while(a=a[c]){if(a.nodeType==1){b.push(Element.extend(a))}}return b},ancestors:function(a){return Element.recursivelyCollect(a,"parentNode")},descendants:function(a){return Element.select(a,"*")},firstDescendant:function(a){a=$(a).firstChild;while(a&&a.nodeType!=1){a=a.nextSibling}return $(a)},immediateDescendants:function(a){if(!(a=$(a).firstChild)){return[]}while(a&&a.nodeType!=1){a=a.nextSibling}if(a){return[a].concat($(a).nextSiblings())}return[]},previousSiblings:function(a){return Element.recursivelyCollect(a,"previousSibling")},nextSiblings:function(a){return Element.recursivelyCollect(a,"nextSibling")},siblings:function(a){a=$(a);return Element.previousSiblings(a).reverse().concat(Element.nextSiblings(a))},match:function(b,a){if(Object.isString(a)){a=new Selector(a)}return a.match($(b))},up:function(b,d,a){b=$(b);if(arguments.length==1){return $(b.parentNode)}var c=Element.ancestors(b);return Object.isNumber(d)?c[d]:Selector.findElement(c,d,a)},down:function(b,c,a){b=$(b);if(arguments.length==1){return Element.firstDescendant(b)}return Object.isNumber(c)?Element.descendants(b)[c]:Element.select(b,c)[a||0]},previous:function(b,d,a){b=$(b);if(arguments.length==1){return $(Selector.handlers.previousElementSibling(b))}var c=Element.previousSiblings(b);return Object.isNumber(d)?c[d]:Selector.findElement(c,d,a)},next:function(c,d,b){c=$(c);if(arguments.length==1){return $(Selector.handlers.nextElementSibling(c))}var a=Element.nextSiblings(c);return Object.isNumber(d)?a[d]:Selector.findElement(a,d,b)},select:function(b){var a=Array.prototype.slice.call(arguments,1);return Selector.findChildElements(b,a)},adjacent:function(b){var a=Array.prototype.slice.call(arguments,1);return Selector.findChildElements(b.parentNode,a).without(b)},identify:function(a){a=$(a);var b=Element.readAttribute(a,"id");if(b){return b}do{b="anonymous_element_"+Element.idCounter++}while($(b));Element.writeAttribute(a,"id",b);return b},readAttribute:function(c,a){c=$(c);if(Prototype.Browser.IE){var b=Element._attributeTranslations.read;if(b.values[a]){return b.values[a](c,a)}if(b.names[a]){a=b.names[a]}if(a.include(":")){return(!c.attributes||!c.attributes[a])?null:c.attributes[a].value}}return c.getAttribute(a)},writeAttribute:function(e,c,f){e=$(e);var b={},d=Element._attributeTranslations.write;if(typeof c=="object"){b=c}else{b[c]=Object.isUndefined(f)?true:f}for(var a in b){c=d.names[a]||a;f=b[a];if(d.values[a]){c=d.values[a](e,f)}if(f===false||f===null){e.removeAttribute(c)}else{if(f===true){e.setAttribute(c,c)}else{e.setAttribute(c,f)}}}return e},getHeight:function(a){return Element.getDimensions(a).height},getWidth:function(a){return Element.getDimensions(a).width},classNames:function(a){return new Element.ClassNames(a)},hasClassName:function(a,b){if(!(a=$(a))){return}var c=a.className;return(c.length>0&&(c==b||new RegExp("(^|\\s)"+b+"(\\s|$)").test(c)))},addClassName:function(a,b){if(!(a=$(a))){return}if(!Element.hasClassName(a,b)){a.className+=(a.className?" ":"")+b}return a},removeClassName:function(a,b){if(!(a=$(a))){return}a.className=a.className.replace(new RegExp("(^|\\s+)"+b+"(\\s+|$)")," ").strip();return a},toggleClassName:function(a,b){if(!(a=$(a))){return}return Element[Element.hasClassName(a,b)?"removeClassName":"addClassName"](a,b)},cleanWhitespace:function(b){b=$(b);var c=b.firstChild;while(c){var a=c.nextSibling;if(c.nodeType==3&&!/\S/.test(c.nodeValue)){b.removeChild(c)}c=a}return b},empty:function(a){return $(a).innerHTML.blank()},descendantOf:function(b,a){b=$(b),a=$(a);if(b.compareDocumentPosition){return(b.compareDocumentPosition(a)&8)===8}if(a.contains){return a.contains(b)&&a!==b}while(b=b.parentNode){if(b==a){return true}}return false},scrollTo:function(a){a=$(a);var b=Element.cumulativeOffset(a);window.scrollTo(b[0],b[1]);return a},getStyle:function(b,c){b=$(b);c=c=="float"?"cssFloat":c.camelize();var d=b.style[c];if(!d||d=="auto"){var a=document.defaultView.getComputedStyle(b,null);d=a?a[c]:null}if(c=="opacity"){return d?parseFloat(d):1}return d=="auto"?null:d},getOpacity:function(a){return $(a).getStyle("opacity")},setStyle:function(b,c){b=$(b);var e=b.style,a;if(Object.isString(c)){b.style.cssText+=";"+c;return c.include("opacity")?b.setOpacity(c.match(/opacity:\s*(\d?\.?\d*)/)[1]):b}for(var d in c){if(d=="opacity"){b.setOpacity(c[d])}else{e[(d=="float"||d=="cssFloat")?(Object.isUndefined(e.styleFloat)?"cssFloat":"styleFloat"):d]=c[d]}}return b},setOpacity:function(a,b){a=$(a);a.style.opacity=(b==1||b==="")?"":(b<0.00001)?0:b;return a},getDimensions:function(c){c=$(c);var g=Element.getStyle(c,"display");if(g!="none"&&g!=null){return{width:c.offsetWidth,height:c.offsetHeight}}var b=c.style;var f=b.visibility;var d=b.position;var a=b.display;b.visibility="hidden";if(d!="fixed"){b.position="absolute"}b.display="block";var h=c.clientWidth;var e=c.clientHeight;b.display=a;b.position=d;b.visibility=f;return{width:h,height:e}},makePositioned:function(a){a=$(a);var b=Element.getStyle(a,"position");if(b=="static"||!b){a._madePositioned=true;a.style.position="relative";if(Prototype.Browser.Opera){a.style.top=0;a.style.left=0}}return a},undoPositioned:function(a){a=$(a);if(a._madePositioned){a._madePositioned=undefined;a.style.position=a.style.top=a.style.left=a.style.bottom=a.style.right=""}return a},makeClipping:function(a){a=$(a);if(a._overflow){return a}a._overflow=Element.getStyle(a,"overflow")||"auto";if(a._overflow!=="hidden"){a.style.overflow="hidden"}return a},undoClipping:function(a){a=$(a);if(!a._overflow){return a}a.style.overflow=a._overflow=="auto"?"":a._overflow;a._overflow=null;return a},cumulativeOffset:function(b){var a=0,c=0;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;b=b.offsetParent}while(b);return Element._returnOffset(c,a)},positionedOffset:function(b){var a=0,d=0;do{a+=b.offsetTop||0;d+=b.offsetLeft||0;b=b.offsetParent;if(b){if(b.tagName.toUpperCase()=="BODY"){break}var c=Element.getStyle(b,"position");if(c!=="static"){break}}}while(b);return Element._returnOffset(d,a)},absolutize:function(b){b=$(b);if(Element.getStyle(b,"position")=="absolute"){return b}var d=Element.positionedOffset(b);var f=d[1];var e=d[0];var c=b.clientWidth;var a=b.clientHeight;b._originalLeft=e-parseFloat(b.style.left||0);b._originalTop=f-parseFloat(b.style.top||0);b._originalWidth=b.style.width;b._originalHeight=b.style.height;b.style.position="absolute";b.style.top=f+"px";b.style.left=e+"px";b.style.width=c+"px";b.style.height=a+"px";return b},relativize:function(a){a=$(a);if(Element.getStyle(a,"position")=="relative"){return a}a.style.position="relative";var c=parseFloat(a.style.top||0)-(a._originalTop||0);var b=parseFloat(a.style.left||0)-(a._originalLeft||0);a.style.top=c+"px";a.style.left=b+"px";a.style.height=a._originalHeight;a.style.width=a._originalWidth;return a},cumulativeScrollOffset:function(b){var a=0,c=0;do{a+=b.scrollTop||0;c+=b.scrollLeft||0;b=b.parentNode}while(b);return Element._returnOffset(c,a)},getOffsetParent:function(a){if(a.offsetParent){return $(a.offsetParent)}if(a==document.body){return $(a)}while((a=a.parentNode)&&a!=document.body){if(Element.getStyle(a,"position")!="static"){return $(a)}}return $(document.body)},viewportOffset:function(d){var a=0,c=0;var b=d;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;if(b.offsetParent==document.body&&Element.getStyle(b,"position")=="absolute"){break}}while(b=b.offsetParent);b=d;do{if(!Prototype.Browser.Opera||(b.tagName&&(b.tagName.toUpperCase()=="BODY"))){a-=b.scrollTop||0;c-=b.scrollLeft||0}}while(b=b.parentNode);return Element._returnOffset(c,a)},clonePosition:function(b,d){var a=Object.extend({setLeft:true,setTop:true,setWidth:true,setHeight:true,offsetTop:0,offsetLeft:0},arguments[2]||{});d=$(d);var e=Element.viewportOffset(d);b=$(b);var f=[0,0];var c=null;if(Element.getStyle(b,"position")=="absolute"){c=Element.getOffsetParent(b);f=Element.viewportOffset(c)}if(c==document.body){f[0]-=document.body.offsetLeft;f[1]-=document.body.offsetTop}if(a.setLeft){b.style.left=(e[0]-f[0]+a.offsetLeft)+"px"}if(a.setTop){b.style.top=(e[1]-f[1]+a.offsetTop)+"px"}if(a.setWidth){b.style.width=d.offsetWidth+"px"}if(a.setHeight){b.style.height=d.offsetHeight+"px"}return b}};Object.extend(Element.Methods,{getElementsBySelector:Element.Methods.select,childElements:Element.Methods.immediateDescendants});Element._attributeTranslations={write:{names:{className:"class",htmlFor:"for"},values:{}}};if(Prototype.Browser.Opera){Element.Methods.getStyle=Element.Methods.getStyle.wrap(function(d,b,c){switch(c){case"left":case"top":case"right":case"bottom":if(d(b,"position")==="static"){return null}case"height":case"width":if(!Element.visible(b)){return null}var e=parseInt(d(b,c),10);if(e!==b["offset"+c.capitalize()]){return e+"px"}var a;if(c==="height"){a=["border-top-width","padding-top","padding-bottom","border-bottom-width"]}else{a=["border-left-width","padding-left","padding-right","border-right-width"]}return a.inject(e,function(f,g){var h=d(b,g);return h===null?f:f-parseInt(h,10)})+"px";default:return d(b,c)}});Element.Methods.readAttribute=Element.Methods.readAttribute.wrap(function(c,a,b){if(b==="title"){return a.title}return c(a,b)})}else{if(Prototype.Browser.IE){Element.Methods.getOffsetParent=Element.Methods.getOffsetParent.wrap(function(c,b){b=$(b);try{b.offsetParent}catch(f){return $(document.body)}var a=b.getStyle("position");if(a!=="static"){return c(b)}b.setStyle({position:"relative"});var d=c(b);b.setStyle({position:a});return d});$w("positionedOffset viewportOffset").each(function(a){Element.Methods[a]=Element.Methods[a].wrap(function(f,c){c=$(c);try{c.offsetParent}catch(h){return Element._returnOffset(0,0)}var b=c.getStyle("position");if(b!=="static"){return f(c)}var d=c.getOffsetParent();if(d&&d.getStyle("position")==="fixed"){d.setStyle({zoom:1})}c.setStyle({position:"relative"});var g=f(c);c.setStyle({position:b});return g})});Element.Methods.cumulativeOffset=Element.Methods.cumulativeOffset.wrap(function(b,a){try{a.offsetParent}catch(c){return Element._returnOffset(0,0)}return b(a)});Element.Methods.getStyle=function(a,b){a=$(a);b=(b=="float"||b=="cssFloat")?"styleFloat":b.camelize();var c=a.style[b];if(!c&&a.currentStyle){c=a.currentStyle[b]}if(b=="opacity"){if(c=(a.getStyle("filter")||"").match(/alpha\(opacity=(.*)\)/)){if(c[1]){return parseFloat(c[1])/100}}return 1}if(c=="auto"){if((b=="width"||b=="height")&&(a.getStyle("display")!="none")){return a["offset"+b.capitalize()]+"px"}return null}return c};Element.Methods.setOpacity=function(b,e){function f(g){return g.replace(/alpha\([^\)]*\)/gi,"")}b=$(b);var a=b.currentStyle;if((a&&!a.hasLayout)||(!a&&b.style.zoom=="normal")){b.style.zoom=1}var d=b.getStyle("filter"),c=b.style;if(e==1||e===""){(d=f(d))?c.filter=d:c.removeAttribute("filter");return b}else{if(e<0.00001){e=0}}c.filter=f(d)+"alpha(opacity="+(e*100)+")";return b};Element._attributeTranslations=(function(){var b="className";var a="for";var c=document.createElement("div");c.setAttribute(b,"x");if(c.className!=="x"){c.setAttribute("class","x");if(c.className==="x"){b="class"}}c=null;c=document.createElement("label");c.setAttribute(a,"x");if(c.htmlFor!=="x"){c.setAttribute("htmlFor","x");if(c.htmlFor==="x"){a="htmlFor"}}c=null;return{read:{names:{"class":b,className:b,"for":a,htmlFor:a},values:{_getAttr:function(d,e){return d.getAttribute(e)},_getAttr2:function(d,e){return d.getAttribute(e,2)},_getAttrNode:function(d,f){var e=d.getAttributeNode(f);return e?e.value:""},_getEv:(function(){var d=document.createElement("div");d.onclick=Prototype.emptyFunction;var g=d.getAttribute("onclick");var e;if(String(g).indexOf("{")>-1){e=function(f,h){h=f.getAttribute(h);if(!h){return null}h=h.toString();h=h.split("{")[1];h=h.split("}")[0];return h.strip()}}else{if(g===""){e=function(f,h){h=f.getAttribute(h);if(!h){return null}return h.strip()}}}d=null;return e})(),_flag:function(d,e){return $(d).hasAttribute(e)?e:null},style:function(d){return d.style.cssText.toLowerCase()},title:function(d){return d.title}}}}})();Element._attributeTranslations.write={names:Object.extend({cellpadding:"cellPadding",cellspacing:"cellSpacing"},Element._attributeTranslations.read.names),values:{checked:function(a,b){a.checked=!!b},style:function(a,b){a.style.cssText=b?b:""}}};Element._attributeTranslations.has={};$w("colSpan rowSpan vAlign dateTime accessKey tabIndex encType maxLength readOnly longDesc frameBorder").each(function(a){Element._attributeTranslations.write.names[a.toLowerCase()]=a;Element._attributeTranslations.has[a.toLowerCase()]=a});(function(a){Object.extend(a,{href:a._getAttr2,src:a._getAttr2,type:a._getAttr,action:a._getAttrNode,disabled:a._flag,checked:a._flag,readonly:a._flag,multiple:a._flag,onload:a._getEv,onunload:a._getEv,onclick:a._getEv,ondblclick:a._getEv,onmousedown:a._getEv,onmouseup:a._getEv,onmouseover:a._getEv,onmousemove:a._getEv,onmouseout:a._getEv,onfocus:a._getEv,onblur:a._getEv,onkeypress:a._getEv,onkeydown:a._getEv,onkeyup:a._getEv,onsubmit:a._getEv,onreset:a._getEv,onselect:a._getEv,onchange:a._getEv})})(Element._attributeTranslations.read.values);if(Prototype.BrowserFeatures.ElementExtensions){(function(){function a(e){var b=e.getElementsByTagName("*"),d=[];for(var c=0,f;f=b[c];c++){if(f.tagName!=="!"){d.push(f)}}return d}Element.Methods.down=function(c,d,b){c=$(c);if(arguments.length==1){return c.firstDescendant()}return Object.isNumber(d)?a(c)[d]:Element.select(c,d)[b||0]}})()}}else{if(Prototype.Browser.Gecko&&/rv:1\.8\.0/.test(navigator.userAgent)){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1)?0.999999:(b==="")?"":(b<0.00001)?0:b;return a}}else{if(Prototype.Browser.WebKit){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1||b==="")?"":(b<0.00001)?0:b;if(b==1){if(a.tagName.toUpperCase()=="IMG"&&a.width){a.width++;a.width--}else{try{var d=document.createTextNode(" ");a.appendChild(d);a.removeChild(d)}catch(c){}}}return a};Element.Methods.cumulativeOffset=function(b){var a=0,c=0;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;if(b.offsetParent==document.body){if(Element.getStyle(b,"position")=="absolute"){break}}b=b.offsetParent}while(b);return Element._returnOffset(c,a)}}}}}if("outerHTML"in document.documentElement){Element.Methods.replace=function(c,e){c=$(c);if(e&&e.toElement){e=e.toElement()}if(Object.isElement(e)){c.parentNode.replaceChild(e,c);return c}e=Object.toHTML(e);var d=c.parentNode,b=d.tagName.toUpperCase();if(Element._insertionTranslations.tags[b]){var f=c.next();var a=Element._getContentFromAnonymousElement(b,e.stripScripts());d.removeChild(c);if(f){a.each(function(g){d.insertBefore(g,f)})}else{a.each(function(g){d.appendChild(g)})}}else{c.outerHTML=e.stripScripts()}e.evalScripts.bind(e).defer();return c}}Element._returnOffset=function(b,c){var a=[b,c];a.left=b;a.top=c;return a};Element._getContentFromAnonymousElement=function(c,b){var d=new Element("div"),a=Element._insertionTranslations.tags[c];if(a){d.innerHTML=a[0]+b+a[1];a[2].times(function(){d=d.firstChild})}else{d.innerHTML=b}return $A(d.childNodes)};Element._insertionTranslations={before:function(a,b){a.parentNode.insertBefore(b,a)},top:function(a,b){a.insertBefore(b,a.firstChild)},bottom:function(a,b){a.appendChild(b)},after:function(a,b){a.parentNode.insertBefore(b,a.nextSibling)},tags:{TABLE:["<table>","</table>",1],TBODY:["<table><tbody>","</tbody></table>",2],TR:["<table><tbody><tr>","</tr></tbody></table>",3],TD:["<table><tbody><tr><td>","</td></tr></tbody></table>",4],SELECT:["<select>","</select>",1]}};(function(){var a=Element._insertionTranslations.tags;Object.extend(a,{THEAD:a.TBODY,TFOOT:a.TBODY,TH:a.TD})})();Element.Methods.Simulated={hasAttribute:function(a,c){c=Element._attributeTranslations.has[c]||c;var b=$(a).getAttributeNode(c);return!!(b&&b.specified)}};Element.Methods.ByTag={};Object.extend(Element,Element.Methods);(function(a){if(!Prototype.BrowserFeatures.ElementExtensions&&a.__proto__){window.HTMLElement={};window.HTMLElement.prototype=a.__proto__;Prototype.BrowserFeatures.ElementExtensions=true}a=null})(document.createElement("div"));Element.extend=(function(){function c(g){if(typeof window.Element!="undefined"){var i=window.Element.prototype;if(i){var k="_"+(Math.random()+"").slice(2);var h=document.createElement(g);i[k]="x";var j=(h[k]!=="x");delete i[k];h=null;return j}}return false}function b(h,g){for(var j in g){var i=g[j];if(Object.isFunction(i)&&!(j in h)){h[j]=i.methodize()}}}var d=c("object");if(Prototype.BrowserFeatures.SpecificElementExtensions){if(d){return function(h){if(h&&typeof h._extendedByPrototype=="undefined"){var g=h.tagName;if(g&&(/^(?:object|applet|embed)$/i.test(g))){b(h,Element.Methods);b(h,Element.Methods.Simulated);b(h,Element.Methods.ByTag[g.toUpperCase()])}}return h}}return Prototype.K}var a={},e=Element.Methods.ByTag;var f=Object.extend(function(i){if(!i||typeof i._extendedByPrototype!="undefined"||i.nodeType!=1||i==window){return i}var g=Object.clone(a),h=i.tagName.toUpperCase();if(e[h]){Object.extend(g,e[h])}b(i,g);i._extendedByPrototype=Prototype.emptyFunction;return i},{refresh:function(){if(!Prototype.BrowserFeatures.ElementExtensions){Object.extend(a,Element.Methods);Object.extend(a,Element.Methods.Simulated)}}});f.refresh();return f})();Element.hasAttribute=function(a,b){if(a.hasAttribute){return a.hasAttribute(b)}return Element.Methods.Simulated.hasAttribute(a,b)};Element.addMethods=function(c){var i=Prototype.BrowserFeatures,d=Element.Methods.ByTag;if(!c){Object.extend(Form,Form.Methods);Object.extend(Form.Element,Form.Element.Methods);Object.extend(Element.Methods.ByTag,{FORM:Object.clone(Form.Methods),INPUT:Object.clone(Form.Element.Methods),SELECT:Object.clone(Form.Element.Methods),TEXTAREA:Object.clone(Form.Element.Methods)})}if(arguments.length==2){var b=c;c=arguments[1]}if(!b){Object.extend(Element.Methods,c||{})}else{if(Object.isArray(b)){b.each(g)}else{g(b)}}function g(k){k=k.toUpperCase();if(!Element.Methods.ByTag[k]){Element.Methods.ByTag[k]={}}Object.extend(Element.Methods.ByTag[k],c)}function a(m,l,k){k=k||false;for(var o in m){var n=m[o];if(!Object.isFunction(n)){continue}if(!k||!(o in l)){l[o]=n.methodize()}}}function e(n){var k;var m={OPTGROUP:"OptGroup",TEXTAREA:"TextArea",P:"Paragraph",FIELDSET:"FieldSet",UL:"UList",OL:"OList",DL:"DList",DIR:"Directory",H1:"Heading",H2:"Heading",H3:"Heading",H4:"Heading",H5:"Heading",H6:"Heading",Q:"Quote",INS:"Mod",DEL:"Mod",A:"Anchor",IMG:"Image",CAPTION:"TableCaption",COL:"TableCol",COLGROUP:"TableCol",THEAD:"TableSection",TFOOT:"TableSection",TBODY:"TableSection",TR:"TableRow",TH:"TableCell",TD:"TableCell",FRAMESET:"FrameSet",IFRAME:"IFrame"};if(m[n]){k="HTML"+m[n]+"Element"}if(window[k]){return window[k]}k="HTML"+n+"Element";if(window[k]){return window[k]}k="HTML"+n.capitalize()+"Element";if(window[k]){return window[k]}var l=document.createElement(n);var o=l.__proto__||l.constructor.prototype;l=null;return o}var h=window.HTMLElement?HTMLElement.prototype:Element.prototype;if(i.ElementExtensions){a(Element.Methods,h);a(Element.Methods.Simulated,h,true)}if(i.SpecificElementExtensions){for(var j in Element.Methods.ByTag){var f=e(j);if(Object.isUndefined(f)){continue}a(d[j],f.prototype)}}Object.extend(Element,Element.Methods);delete Element.ByTag;if(Element.extend.refresh){Element.extend.refresh()}Element.cache={}};document.viewport={getDimensions:function(){return{width:this.getWidth(),height:this.getHeight()}},getScrollOffsets:function(){return Element._returnOffset(window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop)}};(function(b){var g=Prototype.Browser,e=document,c,d={};function a(){if(g.WebKit&&!e.evaluate){return document}if(g.Opera&&window.parseFloat(window.opera.version())<9.5){return document.body}return document.documentElement}function f(h){if(!c){c=a()}d[h]="client"+h;b["get"+h]=function(){return c[d[h]]};return b["get"+h]()}b.getWidth=f.curry("Width");b.getHeight=f.curry("Height")})(document.viewport);Element.Storage={UID:1};Element.addMethods({getStorage:function(b){if(!(b=$(b))){return}var a;if(b===window){a=0}else{if(typeof b._prototypeUID==="undefined"){b._prototypeUID=[Element.Storage.UID++]}a=b._prototypeUID[0]}if(!Element.Storage[a]){Element.Storage[a]=$H()}return Element.Storage[a]},store:function(b,a,c){if(!(b=$(b))){return}if(arguments.length===2){Element.getStorage(b).update(a)}else{Element.getStorage(b).set(a,c)}return b},retrieve:function(c,b,a){if(!(c=$(c))){return}var e=Element.getStorage(c),d=e.get(b);if(Object.isUndefined(d)){e.set(b,a);d=a}return d},clone:function(c,a){if(!(c=$(c))){return}var e=c.cloneNode(a);e._prototypeUID=void 0;if(a){var d=Element.select(e,"*"),b=d.length;while(b--){d[b]._prototypeUID=void 0}}return Element.extend(e)}});var Selector=Class.create({initialize:function(a){this.expression=a.strip();if(this.shouldUseSelectorsAPI()){this.mode="selectorsAPI"}else{if(this.shouldUseXPath()){this.mode="xpath";this.compileXPathMatcher()}else{this.mode="normal";this.compileMatcher()}}},shouldUseXPath:(function(){var a=(function(){var e=false;if(document.evaluate&&window.XPathResult){var d=document.createElement("div");d.innerHTML="<ul><li></li></ul><div><ul><li></li></ul></div>";var c=".//*[local-name()='ul' or local-name()='UL']//*[local-name()='li' or local-name()='LI']";var b=document.evaluate(c,d,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);e=(b.snapshotLength!==2);d=null}return e})();return function(){if(!Prototype.BrowserFeatures.XPath){return false}var b=this.expression;if(Prototype.Browser.WebKit&&(b.include("-of-type")||b.include(":empty"))){return false}if((/(\[[\w-]*?:|:checked)/).test(b)){return false}if(a){return false}return true}})(),shouldUseSelectorsAPI:function(){if(!Prototype.BrowserFeatures.SelectorsAPI){return false}if(Selector.CASE_INSENSITIVE_CLASS_NAMES){return false}if(!Selector._div){Selector._div=new Element("div")}try{Selector._div.querySelector(this.expression)}catch(a){return false}return true},compileMatcher:function(){var e=this.expression,ps=Selector.patterns,h=Selector.handlers,c=Selector.criteria,le,p,m,len=ps.length,name;if(Selector._cache[e]){this.matcher=Selector._cache[e];return}this.matcher=["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i=0;i<len;i++){p=ps[i].re;name=ps[i].name;if(m=e.match(p)){this.matcher.push(Object.isFunction(c[name])?c[name](m):new Template(c[name]).evaluate(m));e=e.replace(m[0],"");break}}}this.matcher.push("return h.unique(n);\n}");eval(this.matcher.join("\n"));Selector._cache[this.expression]=this.matcher},compileXPathMatcher:function(){var h=this.expression,j=Selector.patterns,c=Selector.xpath,g,b,a=j.length,d;if(Selector._cache[h]){this.xpath=Selector._cache[h];return}this.matcher=[".//*"];while(h&&g!=h&&(/\S/).test(h)){g=h;for(var f=0;f<a;f++){d=j[f].name;if(b=h.match(j[f].re)){this.matcher.push(Object.isFunction(c[d])?c[d](b):new Template(c[d]).evaluate(b));h=h.replace(b[0],"");break}}}this.xpath=this.matcher.join("");Selector._cache[this.expression]=this.xpath},findElements:function(a){a=a||document;var c=this.expression,b;switch(this.mode){case"selectorsAPI":if(a!==document){var d=a.id,f=$(a).identify();f=f.replace(/([\.:])/g,"\\$1");c="#"+f+" "+c}b=$A(a.querySelectorAll(c)).map(Element.extend);a.id=d;return b;case"xpath":return document._getElementsByXPath(this.xpath,a);default:return this.matcher(a)}},match:function(k){this.tokens=[];var q=this.expression,a=Selector.patterns,f=Selector.assertions;var b,d,g,o=a.length,c;while(q&&b!==q&&(/\S/).test(q)){b=q;for(var j=0;j<o;j++){d=a[j].re;c=a[j].name;if(g=q.match(d)){if(f[c]){this.tokens.push([c,Object.clone(g)]);q=q.replace(g[0],"")}else{return this.findElements(document).include(k)}}}}var n=true,c,l;for(var j=0,h;h=this.tokens[j];j++){c=h[0],l=h[1];if(!Selector.assertions[c](k,l)){n=false;break}}return n},toString:function(){return this.expression},inspect:function(){return"#<Selector:"+this.expression.inspect()+">"}});if(Prototype.BrowserFeatures.SelectorsAPI&&document.compatMode==="BackCompat"){Selector.CASE_INSENSITIVE_CLASS_NAMES=(function(){var c=document.createElement("div"),a=document.createElement("span");c.id="prototype_test_id";a.className="Test";c.appendChild(a);var b=(c.querySelector("#prototype_test_id .test")!==null);c=a=null;return b})()}Object.extend(Selector,{_cache:{},xpath:{descendant:"//*",child:"/*",adjacent:"/following-sibling::*[1]",laterSibling:"/following-sibling::*",tagName:function(a){if(a[1]=="*"){return""}return"[local-name()='"+a[1].toLowerCase()+"' or local-name()='"+a[1].toUpperCase()+"']"},className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",id:"[@id='#{1}']",attrPresence:function(a){a[1]=a[1].toLowerCase();return new Template("[@#{1}]").evaluate(a)},attr:function(a){a[1]=a[1].toLowerCase();a[3]=a[5]||a[6];return new Template(Selector.xpath.operators[a[2]]).evaluate(a)},pseudo:function(a){var b=Selector.xpath.pseudos[a[1]];if(!b){return""}if(Object.isFunction(b)){return b(a)}return new Template(Selector.xpath.pseudos[a[1]]).evaluate(a)},operators:{"=":"[@#{1}='#{3}']","!=":"[@#{1}!='#{3}']","^=":"[starts-with(@#{1}, '#{3}')]","$=":"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']","*=":"[contains(@#{1}, '#{3}')]","~=":"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]","|=":"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"},pseudos:{"first-child":"[not(preceding-sibling::*)]","last-child":"[not(following-sibling::*)]","only-child":"[not(preceding-sibling::* or following-sibling::*)]",empty:"[count(*) = 0 and (count(text()) = 0)]",checked:"[@checked]",disabled:"[(@disabled) and (@type!='hidden')]",enabled:"[not(@disabled) and (@type!='hidden')]",not:function(f){var j=f[6],c=Selector.patterns,k=Selector.xpath,a,l,h=c.length,b;var d=[];while(j&&a!=j&&(/\S/).test(j)){a=j;for(var g=0;g<h;g++){b=c[g].name;if(f=j.match(c[g].re)){l=Object.isFunction(k[b])?k[b](f):new Template(k[b]).evaluate(f);d.push("("+l.substring(1,l.length-1)+")");j=j.replace(f[0],"");break}}}return"[not("+d.join(" and ")+")]"},"nth-child":function(a){return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",a)},"nth-last-child":function(a){return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",a)},"nth-of-type":function(a){return Selector.xpath.pseudos.nth("position() ",a)},"nth-last-of-type":function(a){return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",a)},"first-of-type":function(a){a[6]="1";return Selector.xpath.pseudos["nth-of-type"](a)},"last-of-type":function(a){a[6]="1";return Selector.xpath.pseudos["nth-last-of-type"](a)},"only-of-type":function(a){var b=Selector.xpath.pseudos;return b["first-of-type"](a)+b["last-of-type"](a)},nth:function(g,e){var h,i=e[6],d;if(i=="even"){i="2n+0"}if(i=="odd"){i="2n+1"}if(h=i.match(/^(\d+)$/)){return"["+g+"= "+h[1]+"]"}if(h=i.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(h[1]=="-"){h[1]=-1}var f=h[1]?Number(h[1]):1;var c=h[2]?Number(h[2]):0;d="[((#{fragment} - #{b}) mod #{a} = 0) and ((#{fragment} - #{b}) div #{a} >= 0)]";return new Template(d).evaluate({fragment:g,a:f,b:c})}}}},criteria:{tagName:'n = h.tagName(n, r, "#{1}", c);      c = false;',className:'n = h.className(n, r, "#{1}", c);    c = false;',id:'n = h.id(n, r, "#{1}", c);           c = false;',attrPresence:'n = h.attrPresence(n, r, "#{1}", c); c = false;',attr:function(a){a[3]=(a[5]||a[6]);return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(a)},pseudo:function(a){if(a[6]){a[6]=a[6].replace(/"/g,'\\"')}return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(a)},descendant:'c = "descendant";',child:'c = "child";',adjacent:'c = "adjacent";',laterSibling:'c = "laterSibling";'},patterns:[{name:"laterSibling",re:/^\s*~\s*/},{name:"child",re:/^\s*>\s*/},{name:"adjacent",re:/^\s*\+\s*/},{name:"descendant",re:/^\s/},{name:"tagName",re:/^\s*(\*|[\w\-]+)(\b|$)?/},{name:"id",re:/^#([\w\-\*]+)(\b|$)/},{name:"className",re:/^\.([\w\-\*]+)(\b|$)/},{name:"pseudo",re:/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/},{name:"attrPresence",re:/^\[((?:[\w-]+:)?[\w-]+)\]/},{name:"attr",re:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/}],assertions:{tagName:function(a,b){return b[1].toUpperCase()==a.tagName.toUpperCase()},className:function(a,b){return Element.hasClassName(a,b[1])},id:function(a,b){return a.id===b[1]},attrPresence:function(a,b){return Element.hasAttribute(a,b[1])},attr:function(b,c){var a=Element.readAttribute(b,c[1]);return a&&Selector.operators[c[2]](a,c[5]||c[6])}},handlers:{concat:function(d,c){for(var e=0,f;f=c[e];e++){d.push(f)}return d},mark:function(a){var d=Prototype.emptyFunction;for(var b=0,c;c=a[b];b++){c._countedByPrototype=d}return a},unmark:(function(){var a=(function(){var b=document.createElement("div"),e=false,d="_countedByPrototype",c="x";b[d]=c;e=(b.getAttribute(d)===c);b=null;return e})();return a?function(b){for(var c=0,d;d=b[c];c++){d.removeAttribute("_countedByPrototype")}return b}:function(b){for(var c=0,d;d=b[c];c++){d._countedByPrototype=void 0}return b}})(),index:function(a,d,g){a._countedByPrototype=Prototype.emptyFunction;if(d){for(var b=a.childNodes,e=b.length-1,c=1;e>=0;e--){var f=b[e];if(f.nodeType==1&&(!g||f._countedByPrototype)){f.nodeIndex=c++}}}else{for(var e=0,c=1,b=a.childNodes;f=b[e];e++){if(f.nodeType==1&&(!g||f._countedByPrototype)){f.nodeIndex=c++}}}},unique:function(b){if(b.length==0){return b}var d=[],e;for(var c=0,a=b.length;c<a;c++){if(typeof(e=b[c])._countedByPrototype=="undefined"){e._countedByPrototype=Prototype.emptyFunction;d.push(Element.extend(e))}}return Selector.handlers.unmark(d)},descendant:function(a){var d=Selector.handlers;for(var c=0,b=[],e;e=a[c];c++){d.concat(b,e.getElementsByTagName("*"))}return b},child:function(a){var e=Selector.handlers;for(var d=0,c=[],f;f=a[d];d++){for(var b=0,g;g=f.childNodes[b];b++){if(g.nodeType==1&&g.tagName!="!"){c.push(g)}}}return c},adjacent:function(a){for(var c=0,b=[],e;e=a[c];c++){var d=this.nextElementSibling(e);if(d){b.push(d)}}return b},laterSibling:function(a){var d=Selector.handlers;for(var c=0,b=[],e;e=a[c];c++){d.concat(b,Element.nextSiblings(e))}return b},nextElementSibling:function(a){while(a=a.nextSibling){if(a.nodeType==1){return a}}return null},previousElementSibling:function(a){while(a=a.previousSibling){if(a.nodeType==1){return a}}return null},tagName:function(a,j,c,b){var k=c.toUpperCase();var e=[],g=Selector.handlers;if(a){if(b){if(b=="descendant"){for(var f=0,d;d=a[f];f++){g.concat(e,d.getElementsByTagName(c))}return e}else{a=this[b](a)}if(c=="*"){return a}}for(var f=0,d;d=a[f];f++){if(d.tagName.toUpperCase()===k){e.push(d)}}return e}else{return j.getElementsByTagName(c)}},id:function(a,l,b,c){var k=$(b),g=Selector.handlers;if(l==document){if(!k){return[]}if(!a){return[k]}}else{if(!l.sourceIndex||l.sourceIndex<1){var a=l.getElementsByTagName("*");for(var e=0,d;d=a[e];e++){if(d.id===b){return[d]}}}}if(a){if(c){if(c=="child"){for(var f=0,d;d=a[f];f++){if(k.parentNode==d){return[k]}}}else{if(c=="descendant"){for(var f=0,d;d=a[f];f++){if(Element.descendantOf(k,d)){return[k]}}}else{if(c=="adjacent"){for(var f=0,d;d=a[f];f++){if(Selector.handlers.previousElementSibling(k)==d){return[k]}}}else{a=g[c](a)}}}}for(var f=0,d;d=a[f];f++){if(d==k){return[k]}}return[]}return(k&&Element.descendantOf(k,l))?[k]:[]},className:function(b,a,c,d){if(b&&d){b=this[d](b)}return Selector.handlers.byClassName(b,a,c)},byClassName:function(c,b,f){if(!c){c=Selector.handlers.descendant([b])}var h=" "+f+" ";for(var e=0,d=[],g,a;g=c[e];e++){a=g.className;if(a.length==0){continue}if(a==f||(" "+a+" ").include(h)){d.push(g)}}return d},attrPresence:function(c,b,a,g){if(!c){c=b.getElementsByTagName("*")}if(c&&g){c=this[g](c)}var e=[];for(var d=0,f;f=c[d];d++){if(Element.hasAttribute(f,a)){e.push(f)}}return e},attr:function(a,j,h,k,c,b){if(!a){a=j.getElementsByTagName("*")}if(a&&b){a=this[b](a)}var l=Selector.operators[c],f=[];for(var e=0,d;d=a[e];e++){var g=Element.readAttribute(d,h);if(g===null){continue}if(l(g,k)){f.push(d)}}return f},pseudo:function(b,c,e,a,d){if(b&&d){b=this[d](b)}if(!b){b=a.getElementsByTagName("*")}return Selector.pseudos[c](b,e,a)}},pseudos:{"first-child":function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(Selector.handlers.previousElementSibling(e)){continue}c.push(e)}return c},"last-child":function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(Selector.handlers.nextElementSibling(e)){continue}c.push(e)}return c},"only-child":function(b,g,a){var e=Selector.handlers;for(var d=0,c=[],f;f=b[d];d++){if(!e.previousElementSibling(f)&&!e.nextElementSibling(f)){c.push(f)}}return c},"nth-child":function(b,c,a){return Selector.pseudos.nth(b,c,a)},"nth-last-child":function(b,c,a){return Selector.pseudos.nth(b,c,a,true)},"nth-of-type":function(b,c,a){return Selector.pseudos.nth(b,c,a,false,true)},"nth-last-of-type":function(b,c,a){return Selector.pseudos.nth(b,c,a,true,true)},"first-of-type":function(b,c,a){return Selector.pseudos.nth(b,"1",a,false,true)},"last-of-type":function(b,c,a){return Selector.pseudos.nth(b,"1",a,true,true)},"only-of-type":function(b,d,a){var c=Selector.pseudos;return c["last-of-type"](c["first-of-type"](b,d,a),d,a)},getIndices:function(d,c,e){if(d==0){return c>0?[c]:[]}return $R(1,e).inject([],function(a,b){if(0==(b-c)%d&&(b-c)/d>=0){a.push(b)}return a})},nth:function(c,s,u,r,e){if(c.length==0){return[]}if(s=="even"){s="2n+0"}if(s=="odd"){s="2n+1"}var q=Selector.handlers,p=[],d=[],g;q.mark(c);for(var o=0,f;f=c[o];o++){if(!f.parentNode._countedByPrototype){q.index(f.parentNode,r,e);d.push(f.parentNode)}}if(s.match(/^\d+$/)){s=Number(s);for(var o=0,f;f=c[o];o++){if(f.nodeIndex==s){p.push(f)}}}else{if(g=s.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(g[1]=="-"){g[1]=-1}var v=g[1]?Number(g[1]):1;var t=g[2]?Number(g[2]):0;var w=Selector.pseudos.getIndices(v,t,c.length);for(var o=0,f,k=w.length;f=c[o];o++){for(var n=0;n<k;n++){if(f.nodeIndex==w[n]){p.push(f)}}}}}q.unmark(c);q.unmark(d);return p},empty:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(e.tagName=="!"||e.firstChild){continue}c.push(e)}return c},not:function(a,d,k){var g=Selector.handlers,l,c;var j=new Selector(d).findElements(k);g.mark(j);for(var f=0,e=[],b;b=a[f];f++){if(!b._countedByPrototype){e.push(b)}}g.unmark(j);return e},enabled:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(!e.disabled&&(!e.type||e.type!=="hidden")){c.push(e)}}return c},disabled:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(e.disabled){c.push(e)}}return c},checked:function(b,f,a){for(var d=0,c=[],e;e=b[d];d++){if(e.checked){c.push(e)}}return c}},operators:{"=":function(b,a){return b==a},"!=":function(b,a){return b!=a},"^=":function(b,a){return b==a||b&&b.startsWith(a)},"$=":function(b,a){return b==a||b&&b.endsWith(a)},"*=":function(b,a){return b==a||b&&b.include(a)},"~=":function(b,a){return(" "+b+" ").include(" "+a+" ")},"|=":function(b,a){return("-"+(b||"").toUpperCase()+"-").include("-"+(a||"").toUpperCase()+"-")}},split:function(b){var a=[];b.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(c){a.push(c[1].strip())});return a},matchElements:function(f,g){var e=$$(g),d=Selector.handlers;d.mark(e);for(var c=0,b=[],a;a=f[c];c++){if(a._countedByPrototype){b.push(a)}}d.unmark(e);return b},findElement:function(b,c,a){if(Object.isNumber(c)){a=c;c=false}return Selector.matchElements(b,c||"*")[a||0]},findChildElements:function(e,g){g=Selector.split(g.join(","));var d=[],f=Selector.handlers;for(var c=0,b=g.length,a;c<b;c++){a=new Selector(g[c].strip());f.concat(d,a.findElements(e))}return(b>1)?f.unique(d):d}});if(Prototype.Browser.IE){Object.extend(Selector.handlers,{concat:function(d,c){for(var e=0,f;f=c[e];e++){if(f.tagName!=="!"){d.push(f)}}return d}})}function $$(){return Selector.findChildElements(document,$A(arguments))}var Form={reset:function(a){a=$(a);a.reset();return a},serializeElements:function(g,b){if(typeof b!="object"){b={hash:!!b}}else{if(Object.isUndefined(b.hash)){b.hash=true}}var c,f,a=false,e=b.submit;var d=g.inject({},function(h,i){if(!i.disabled&&i.name){c=i.name;f=$(i).getValue();if(f!=null&&i.type!="file"&&(i.type!="submit"||(!a&&e!==false&&(!e||c==e)&&(a=true)))){if(c in h){if(!Object.isArray(h[c])){h[c]=[h[c]]}h[c].push(f)}else{h[c]=f}}}return h});return b.hash?d:Object.toQueryString(d)}};Form.Methods={serialize:function(b,a){return Form.serializeElements(Form.getElements(b),a)},getElements:function(e){var f=$(e).getElementsByTagName("*"),d,a=[],c=Form.Element.Serializers;for(var b=0;d=f[b];b++){a.push(d)}return a.inject([],function(g,h){if(c[h.tagName.toLowerCase()]){g.push(Element.extend(h))}return g})},getInputs:function(g,c,d){g=$(g);var a=g.getElementsByTagName("input");if(!c&&!d){return $A(a).map(Element.extend)}for(var e=0,h=[],f=a.length;e<f;e++){var b=a[e];if((c&&b.type!=c)||(d&&b.name!=d)){continue}h.push(Element.extend(b))}return h},disable:function(a){a=$(a);Form.getElements(a).invoke("disable");return a},enable:function(a){a=$(a);Form.getElements(a).invoke("enable");return a},findFirstElement:function(b){var c=$(b).getElements().findAll(function(d){return"hidden"!=d.type&&!d.disabled});var a=c.findAll(function(d){return d.hasAttribute("tabIndex")&&d.tabIndex>=0}).sortBy(function(d){return d.tabIndex}).first();return a?a:c.find(function(d){return/^(?:input|select|textarea)$/i.test(d.tagName)})},focusFirstElement:function(a){a=$(a);a.findFirstElement().activate();return a},request:function(b,a){b=$(b),a=Object.clone(a||{});var d=a.parameters,c=b.readAttribute("action")||"";if(c.blank()){c=window.location.href}a.parameters=b.serialize(true);if(d){if(Object.isString(d)){d=d.toQueryParams()}Object.extend(a.parameters,d)}if(b.hasAttribute("method")&&!a.method){a.method=b.method}return new Ajax.Request(c,a)}};Form.Element={focus:function(a){$(a).focus();return a},select:function(a){$(a).select();return a}};Form.Element.Methods={serialize:function(a){a=$(a);if(!a.disabled&&a.name){var b=a.getValue();if(b!=undefined){var c={};c[a.name]=b;return Object.toQueryString(c)}}return""},getValue:function(a){a=$(a);var b=a.tagName.toLowerCase();return Form.Element.Serializers[b](a)},setValue:function(a,b){a=$(a);var c=a.tagName.toLowerCase();Form.Element.Serializers[c](a,b);return a},clear:function(a){$(a).value="";return a},present:function(a){return $(a).value!=""},activate:function(a){a=$(a);try{a.focus();if(a.select&&(a.tagName.toLowerCase()!="input"||!(/^(?:button|reset|submit)$/i.test(a.type)))){a.select()}}catch(b){}return a},disable:function(a){a=$(a);a.disabled=true;return a},enable:function(a){a=$(a);a.disabled=false;return a}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers={input:function(a,b){switch(a.type.toLowerCase()){case"checkbox":case"radio":return Form.Element.Serializers.inputSelector(a,b);default:return Form.Element.Serializers.textarea(a,b)}},inputSelector:function(a,b){if(Object.isUndefined(b)){return a.checked?a.value:null}else{a.checked=!!b}},textarea:function(a,b){if(Object.isUndefined(b)){return a.value}else{a.value=b}},select:function(c,f){if(Object.isUndefined(f)){return this[c.type=="select-one"?"selectOne":"selectMany"](c)}else{var b,d,g=!Object.isArray(f);for(var a=0,e=c.length;a<e;a++){b=c.options[a];d=this.optionValue(b);if(g){if(d==f){b.selected=true;return}}else{b.selected=f.include(d)}}}},selectOne:function(b){var a=b.selectedIndex;return a>=0?this.optionValue(b.options[a]):null},selectMany:function(d){var a,e=d.length;if(!e){return null}for(var c=0,a=[];c<e;c++){var b=d.options[c];if(b.selected){a.push(this.optionValue(b))}}return a},optionValue:function(a){return Element.extend(a).hasAttribute("value")?a.value:a.text}};Abstract.TimedObserver=Class.create(PeriodicalExecuter,{initialize:function($super,a,b,c){$super(c,b);this.element=$(a);this.lastValue=this.getValue()},execute:function(){var a=this.getValue();if(Object.isString(this.lastValue)&&Object.isString(a)?this.lastValue!=a:String(this.lastValue)!=String(a)){this.callback(this.element,a);this.lastValue=a}}});Form.Element.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.serialize(this.element)}});Abstract.EventObserver=Class.create({initialize:function(a,b){this.element=$(a);this.callback=b;this.lastValue=this.getValue();if(this.element.tagName.toLowerCase()=="form"){this.registerFormCallbacks()}else{this.registerCallback(this.element)}},onElementEvent:function(){var a=this.getValue();if(this.lastValue!=a){this.callback(this.element,a);this.lastValue=a}},registerFormCallbacks:function(){Form.getElements(this.element).each(this.registerCallback,this)},registerCallback:function(a){if(a.type){switch(a.type.toLowerCase()){case"checkbox":case"radio":Event.observe(a,"click",this.onElementEvent.bind(this));break;default:Event.observe(a,"change",this.onElementEvent.bind(this));break}}}});Form.Element.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.serialize(this.element)}});(function(){var v={KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,KEY_INSERT:45,cache:{}};var e=document.documentElement;var w="onmouseenter"in e&&"onmouseleave"in e;var o;if(Prototype.Browser.IE){var h={0:1,1:4,2:2};o=function(y,x){return y.button===h[x]}}else{if(Prototype.Browser.WebKit){o=function(y,x){switch(x){case 0:return y.which==1&&!y.metaKey;case 1:return y.which==1&&y.metaKey;default:return false}}}else{o=function(y,x){return y.which?(y.which===x+1):(y.button===x)}}}function r(x){return o(x,0)}function q(x){return o(x,1)}function k(x){return o(x,2)}function c(z){z=v.extend(z);var y=z.target,x=z.type,A=z.currentTarget;if(A&&A.tagName){if(x==="load"||x==="error"||(x==="click"&&A.tagName.toLowerCase()==="input"&&A.type==="radio")){y=A}}if(y.nodeType==Node.TEXT_NODE){y=y.parentNode}return Element.extend(y)}function m(y,A){var x=v.element(y);if(!A){return x}var z=[x].concat(x.ancestors());return Selector.findElement(z,A,0)}function p(x){return{x:b(x),y:a(x)}}function b(z){var y=document.documentElement,x=document.body||{scrollLeft:0};return z.pageX||(z.clientX+(y.scrollLeft||x.scrollLeft)-(y.clientLeft||0))}function a(z){var y=document.documentElement,x=document.body||{scrollTop:0};return z.pageY||(z.clientY+(y.scrollTop||x.scrollTop)-(y.clientTop||0))}function n(x){v.extend(x);x.preventDefault();x.stopPropagation();x.stopped=true}v.Methods={isLeftClick:r,isMiddleClick:q,isRightClick:k,element:c,findElement:m,pointer:p,pointerX:b,pointerY:a,stop:n};var t=Object.keys(v.Methods).inject({},function(x,y){x[y]=v.Methods[y].methodize();return x});if(Prototype.Browser.IE){function g(y){var x;switch(y.type){case"mouseover":x=y.fromElement;break;case"mouseout":x=y.toElement;break;default:return null}return Element.extend(x)}Object.extend(t,{stopPropagation:function(){this.cancelBubble=true},preventDefault:function(){this.returnValue=false},inspect:function(){return"[object Event]"}});v.extend=function(y,x){if(!y){return false}if(y._extendedByPrototype){return y}y._extendedByPrototype=Prototype.emptyFunction;var z=v.pointer(y);Object.extend(y,{target:y.srcElement||x,relatedTarget:g(y),pageX:z.x,pageY:z.y});return Object.extend(y,t)}}else{v.prototype=window.Event.prototype||document.createEvent("HTMLEvents").__proto__;Object.extend(v.prototype,t);v.extend=Prototype.K}function l(B,A,C){var z=Element.retrieve(B,"prototype_event_registry");if(Object.isUndefined(z)){d.push(B);z=Element.retrieve(B,"prototype_event_registry",$H())}var x=z.get(A);if(Object.isUndefined(x)){x=[];z.set(A,x)}if(x.pluck("handler").include(C)){return false}var y;if(A.include(":")){y=function(D){if(Object.isUndefined(D.eventName)){return false}if(D.eventName!==A){return false}v.extend(D,B);C.call(B,D)}}else{if(!w&&(A==="mouseenter"||A==="mouseleave")){if(A==="mouseenter"||A==="mouseleave"){y=function(E){v.extend(E,B);var D=E.relatedTarget;while(D&&D!==B){try{D=D.parentNode}catch(F){D=B}}if(D===B){return}C.call(B,E)}}}else{y=function(D){v.extend(D,B);C.call(B,D)}}}y.handler=C;x.push(y);return y}function f(){for(var x=0,y=d.length;x<y;x++){v.stopObserving(d[x]);d[x]=null}}var d=[];if(Prototype.Browser.IE){window.attachEvent("onunload",f)}if(Prototype.Browser.WebKit){window.addEventListener("unload",Prototype.emptyFunction,false)}var j=Prototype.K;if(!w){j=function(y){var x={mouseenter:"mouseover",mouseleave:"mouseout"};return y in x?x[y]:y}}function s(A,z,B){A=$(A);var y=l(A,z,B);if(!y){return A}if(z.include(":")){if(A.addEventListener){A.addEventListener("dataavailable",y,false)}else{A.attachEvent("ondataavailable",y);A.attachEvent("onfilterchange",y)}}else{var x=j(z);if(A.addEventListener){A.addEventListener(x,y,false)}else{A.attachEvent("on"+x,y)}}return A}function i(C,A,D){C=$(C);var z=Element.retrieve(C,"prototype_event_registry");if(Object.isUndefined(z)){return C}if(A&&!D){var B=z.get(A);if(Object.isUndefined(B)){return C}B.each(function(E){Element.stopObserving(C,A,E.handler)});return C}else{if(!A){z.each(function(G){var E=G.key,F=G.value;F.each(function(H){Element.stopObserving(C,E,H.handler)})});return C}}var B=z.get(A);if(!B){return}var y=B.find(function(E){return E.handler===D});if(!y){return C}var x=j(A);if(A.include(":")){if(C.removeEventListener){C.removeEventListener("dataavailable",y,false)}else{C.detachEvent("ondataavailable",y);C.detachEvent("onfilterchange",y)}}else{if(C.removeEventListener){C.removeEventListener(x,y,false)}else{C.detachEvent("on"+x,y)}}z.set(A,B.without(y));return C}function u(A,z,y,x){A=$(A);if(Object.isUndefined(x)){x=true}if(A==document&&document.createEvent&&!A.dispatchEvent){A=document.documentElement}var B;if(document.createEvent){B=document.createEvent("HTMLEvents");B.initEvent("dataavailable",true,true)}else{B=document.createEventObject();B.eventType=x?"ondataavailable":"onfilterchange"}B.eventName=z;B.memo=y||{};if(document.createEvent){A.dispatchEvent(B)}else{A.fireEvent(B.eventType,B)}return v.extend(B)}Object.extend(v,v.Methods);Object.extend(v,{fire:u,observe:s,stopObserving:i});Element.addMethods({fire:u,observe:s,stopObserving:i});Object.extend(document,{fire:u.methodize(),observe:s.methodize(),stopObserving:i.methodize(),loaded:false});if(window.Event){Object.extend(window.Event,v)}else{window.Event=v}})();(function(){var d;function a(){if(document.loaded){return}if(d){window.clearTimeout(d)}document.loaded=true;document.fire("dom:loaded")}function c(){if(document.readyState==="complete"){document.stopObserving("readystatechange",c);a()}}function b(){try{document.documentElement.doScroll("left")}catch(f){d=b.defer();return}a()}if(document.addEventListener){document.addEventListener("DOMContentLoaded",a,false)}else{document.observe("readystatechange",c);if(window==top){d=b.defer()}}Event.observe(window,"load",a)})();Element.addMethods();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(a,b){return Element.insert(a,{before:b})},Top:function(a,b){return Element.insert(a,{top:b})},Bottom:function(a,b){return Element.insert(a,{bottom:b})},After:function(a,b){return Element.insert(a,{after:b})}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},within:function(b,a,c){if(this.includeScrollOffsets){return this.withinIncludingScrolloffsets(b,a,c)}this.xcomp=a;this.ycomp=c;this.offset=Element.cumulativeOffset(b);return(c>=this.offset[1]&&c<this.offset[1]+b.offsetHeight&&a>=this.offset[0]&&a<this.offset[0]+b.offsetWidth)},withinIncludingScrolloffsets:function(b,a,d){var c=Element.cumulativeScrollOffset(b);this.xcomp=a+c[0]-this.deltaX;this.ycomp=d+c[1]-this.deltaY;this.offset=Element.cumulativeOffset(b);return(this.ycomp>=this.offset[1]&&this.ycomp<this.offset[1]+b.offsetHeight&&this.xcomp>=this.offset[0]&&this.xcomp<this.offset[0]+b.offsetWidth)},overlap:function(b,a){if(!b){return 0}if(b=="vertical"){return((this.offset[1]+a.offsetHeight)-this.ycomp)/a.offsetHeight}if(b=="horizontal"){return((this.offset[0]+a.offsetWidth)-this.xcomp)/a.offsetWidth}},cumulativeOffset:Element.Methods.cumulativeOffset,positionedOffset:Element.Methods.positionedOffset,absolutize:function(a){Position.prepare();return Element.absolutize(a)},relativize:function(a){Position.prepare();return Element.relativize(a)},realOffset:Element.Methods.cumulativeScrollOffset,offsetParent:Element.Methods.getOffsetParent,page:Element.Methods.viewportOffset,clone:function(b,c,a){a=a||{};return Element.clonePosition(c,b,a)}};if(!document.getElementsByClassName){document.getElementsByClassName=function(b){function a(c){return c.blank()?null:"[contains(concat(' ', @class, ' '), ' "+c+" ')]"}b.getElementsByClassName=Prototype.BrowserFeatures.XPath?function(c,e){e=e.toString().strip();var d=/\s/.test(e)?$w(e).map(a).join(""):a(e);return d?document._getElementsByXPath(".//*"+d,c):[]}:function(e,f){f=f.toString().strip();var g=[],h=(/\s/.test(f)?$w(f):null);if(!h&&!f){return g}var c=$(e).getElementsByTagName("*");f=" "+f+" ";for(var d=0,k,j;k=c[d];d++){if(k.className&&(j=" "+k.className+" ")&&(j.include(f)||(h&&h.all(function(i){return!i.toString().blank()&&j.include(" "+i+" ")})))){g.push(Element.extend(k))}}return g};return function(d,c){return $(c||document.body).getElementsByClassName(d)}}(Element.Methods)}Element.ClassNames=Class.create();Element.ClassNames.prototype={initialize:function(a){this.element=$(a)},_each:function(a){this.element.className.split(/\s+/).select(function(b){return b.length>0})._each(a)},set:function(a){this.element.className=a},add:function(a){if(this.include(a)){return}this.set($A(this).concat(a).join(" "))},remove:function(a){if(!this.include(a)){return}this.set($A(this).without(a).join(" "))},toString:function(){return $A(this).join(" ")}};Object.extend(Element.ClassNames.prototype,Enumerable);
\ No newline at end of file
diff --git a/js/src/dragdrop.js b/js/src/dragdrop.js
index 14ebc6f..d6d935a 100644
--- a/js/src/dragdrop.js
+++ b/js/src/dragdrop.js
@@ -1,6 +1,6 @@
 // script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
 
-// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Copyright 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
 //           (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi at oriontransfer.co.nz)
 // 
 // script.aculo.us is freely distributable under the terms of an MIT-style license.
diff --git a/js/src/effects.js b/js/src/effects.js
index 27c2901..5097fa0 100644
--- a/js/src/effects.js
+++ b/js/src/effects.js
@@ -1,6 +1,6 @@
 // script.aculo.us effects.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
 
-// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Copyright 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
 // Contributors:
 //  Justin Palmer (http://encytemedia.com/)
 //  Mark Pilgrim (http://diveintomark.org/)
diff --git a/js/src/prototype.js b/js/src/prototype.js
index a7fd383..9fe6e12 100644
--- a/js/src/prototype.js
+++ b/js/src/prototype.js
@@ -1,5 +1,5 @@
-/*  Prototype JavaScript framework, version 1.6.0.3
- *  (c) 2005-2008 Sam Stephenson
+/*  Prototype JavaScript framework, version 1.6.1
+ *  (c) 2005-2009 Sam Stephenson
  *
  *  Prototype is freely distributable under the terms of an MIT-style license.
  *  For details, see the Prototype web site: http://www.prototypejs.org/
@@ -7,26 +7,43 @@
  *--------------------------------------------------------------------------*/
 
 var Prototype = {
-  Version: '1.6.0.3',
-
-  Browser: {
-    IE:     !!(window.attachEvent &&
-      navigator.userAgent.indexOf('Opera') === -1),
-    Opera:  navigator.userAgent.indexOf('Opera') > -1,
-    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
-    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 &&
-      navigator.userAgent.indexOf('KHTML') === -1,
-    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
-  },
+  Version: '1.6.1',
+
+  Browser: (function(){
+    var ua = navigator.userAgent;
+    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
+    return {
+      IE:             !!window.attachEvent && !isOpera,
+      Opera:          isOpera,
+      WebKit:         ua.indexOf('AppleWebKit/') > -1,
+      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
+      MobileSafari:   /Apple.*Mobile.*Safari/.test(ua)
+    }
+  })(),
 
   BrowserFeatures: {
     XPath: !!document.evaluate,
     SelectorsAPI: !!document.querySelector,
-    ElementExtensions: !!window.HTMLElement,
-    SpecificElementExtensions:
-      document.createElement('div')['__proto__'] &&
-      document.createElement('div')['__proto__'] !==
-        document.createElement('form')['__proto__']
+    ElementExtensions: (function() {
+      var constructor = window.Element || window.HTMLElement;
+      return !!(constructor && constructor.prototype);
+    })(),
+    SpecificElementExtensions: (function() {
+      if (typeof window.HTMLDivElement !== 'undefined')
+        return true;
+
+      var div = document.createElement('div');
+      var form = document.createElement('form');
+      var isSupported = false;
+
+      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
+        isSupported = true;
+      }
+
+      div = form = null;
+
+      return isSupported;
+    })()
   },
 
   ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
@@ -40,9 +57,30 @@ if (Prototype.Browser.MobileSafari)
   Prototype.BrowserFeatures.SpecificElementExtensions = false;
 
 
+var Abstract = { };
+
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) { }
+    }
+
+    return returnValue;
+  }
+};
+
 /* Based on Alex Arnell's inheritance implementation. */
-var Class = {
-  create: function() {
+
+var Class = (function() {
+  function subclass() {};
+  function create() {
     var parent = null, properties = $A(arguments);
     if (Object.isFunction(properties[0]))
       parent = properties.shift();
@@ -56,7 +94,6 @@ var Class = {
     klass.subclasses = [];
 
     if (parent) {
-      var subclass = function() { };
       subclass.prototype = parent.prototype;
       klass.prototype = new subclass;
       parent.subclasses.push(klass);
@@ -69,18 +106,19 @@ var Class = {
       klass.prototype.initialize = Prototype.emptyFunction;
 
     klass.prototype.constructor = klass;
-
     return klass;
   }
-};
 
-Class.Methods = {
-  addMethods: function(source) {
+  function addMethods(source) {
     var ancestor   = this.superclass && this.superclass.prototype;
     var properties = Object.keys(source);
 
-    if (!Object.keys({ toString: true }).length)
-      properties.push("toString", "valueOf");
+    if (!Object.keys({ toString: true }).length) {
+      if (source.toString != Object.prototype.toString)
+        properties.push("toString");
+      if (source.valueOf != Object.prototype.valueOf)
+        properties.push("valueOf");
+    }
 
     for (var i = 0, length = properties.length; i < length; i++) {
       var property = properties[i], value = source[property];
@@ -88,7 +126,7 @@ Class.Methods = {
           value.argumentNames().first() == "$super") {
         var method = value;
         value = (function(m) {
-          return function() { return ancestor[m].apply(this, arguments) };
+          return function() { return ancestor[m].apply(this, arguments); };
         })(property).wrap(method);
 
         value.valueOf = method.valueOf.bind(method);
@@ -99,29 +137,36 @@ Class.Methods = {
 
     return this;
   }
-};
 
-var Abstract = { };
+  return {
+    create: create,
+    Methods: {
+      addMethods: addMethods
+    }
+  };
+})();
+(function() {
 
-Object.extend = function(destination, source) {
-  for (var property in source)
-    destination[property] = source[property];
-  return destination;
-};
+  var _toString = Object.prototype.toString;
 
-Object.extend(Object, {
-  inspect: function(object) {
+  function extend(destination, source) {
+    for (var property in source)
+      destination[property] = source[property];
+    return destination;
+  }
+
+  function inspect(object) {
     try {
-      if (Object.isUndefined(object)) return 'undefined';
+      if (isUndefined(object)) return 'undefined';
       if (object === null) return 'null';
       return object.inspect ? object.inspect() : String(object);
     } catch (e) {
       if (e instanceof RangeError) return '...';
       throw e;
     }
-  },
+  }
 
-  toJSON: function(object) {
+  function toJSON(object) {
     var type = typeof object;
     switch (type) {
       case 'undefined':
@@ -132,131 +177,180 @@ Object.extend(Object, {
 
     if (object === null) return 'null';
     if (object.toJSON) return object.toJSON();
-    if (Object.isElement(object)) return;
+    if (isElement(object)) return;
 
     var results = [];
     for (var property in object) {
-      var value = Object.toJSON(object[property]);
-      if (!Object.isUndefined(value))
+      var value = toJSON(object[property]);
+      if (!isUndefined(value))
         results.push(property.toJSON() + ': ' + value);
     }
 
     return '{' + results.join(', ') + '}';
-  },
+  }
 
-  toQueryString: function(object) {
+  function toQueryString(object) {
     return $H(object).toQueryString();
-  },
+  }
 
-  toHTML: function(object) {
+  function toHTML(object) {
     return object && object.toHTML ? object.toHTML() : String.interpret(object);
-  },
+  }
 
-  keys: function(object) {
-    var keys = [];
+  function keys(object) {
+    var results = [];
     for (var property in object)
-      keys.push(property);
-    return keys;
-  },
+      results.push(property);
+    return results;
+  }
 
-  values: function(object) {
-    var values = [];
+  function values(object) {
+    var results = [];
     for (var property in object)
-      values.push(object[property]);
-    return values;
-  },
+      results.push(object[property]);
+    return results;
+  }
 
-  clone: function(object) {
-    return Object.extend({ }, object);
-  },
+  function clone(object) {
+    return extend({ }, object);
+  }
 
-  isElement: function(object) {
+  function isElement(object) {
     return !!(object && object.nodeType == 1);
-  },
+  }
+
+  function isArray(object) {
+    return _toString.call(object) == "[object Array]";
+  }
 
-  isArray: function(object) {
-    return object != null && typeof object == "object" &&
-      'splice' in object && 'join' in object;
-  },
 
-  isHash: function(object) {
+  function isHash(object) {
     return object instanceof Hash;
-  },
+  }
 
-  isFunction: function(object) {
-    return typeof object == "function";
-  },
+  function isFunction(object) {
+    return typeof object === "function";
+  }
 
-  isString: function(object) {
-    return typeof object == "string";
-  },
+  function isString(object) {
+    return _toString.call(object) == "[object String]";
+  }
 
-  isNumber: function(object) {
-    return typeof object == "number";
-  },
+  function isNumber(object) {
+    return _toString.call(object) == "[object Number]";
+  }
 
-  isUndefined: function(object) {
-    return typeof object == "undefined";
+  function isUndefined(object) {
+    return typeof object === "undefined";
   }
-});
 
-Object.extend(Function.prototype, {
-  argumentNames: function() {
-    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
+  extend(Object, {
+    extend:        extend,
+    inspect:       inspect,
+    toJSON:        toJSON,
+    toQueryString: toQueryString,
+    toHTML:        toHTML,
+    keys:          keys,
+    values:        values,
+    clone:         clone,
+    isElement:     isElement,
+    isArray:       isArray,
+    isHash:        isHash,
+    isFunction:    isFunction,
+    isString:      isString,
+    isNumber:      isNumber,
+    isUndefined:   isUndefined
+  });
+})();
+Object.extend(Function.prototype, (function() {
+  var slice = Array.prototype.slice;
+
+  function update(array, args) {
+    var arrayLength = array.length, length = args.length;
+    while (length--) array[arrayLength + length] = args[length];
+    return array;
+  }
+
+  function merge(array, args) {
+    array = slice.call(array, 0);
+    return update(array, args);
+  }
+
+  function argumentNames() {
+    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
+      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
       .replace(/\s+/g, '').split(',');
     return names.length == 1 && !names[0] ? [] : names;
-  },
+  }
 
-  bind: function() {
+  function bind(context) {
     if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
-    var __method = this, args = $A(arguments), object = args.shift();
+    var __method = this, args = slice.call(arguments, 1);
     return function() {
-      return __method.apply(object, args.concat($A(arguments)));
+      var a = merge(args, arguments);
+      return __method.apply(context, a);
     }
-  },
+  }
 
-  bindAsEventListener: function() {
-    var __method = this, args = $A(arguments), object = args.shift();
+  function bindAsEventListener(context) {
+    var __method = this, args = slice.call(arguments, 1);
     return function(event) {
-      return __method.apply(object, [event || window.event].concat(args));
+      var a = update([event || window.event], args);
+      return __method.apply(context, a);
     }
-  },
+  }
 
-  curry: function() {
+  function curry() {
     if (!arguments.length) return this;
-    var __method = this, args = $A(arguments);
+    var __method = this, args = slice.call(arguments, 0);
     return function() {
-      return __method.apply(this, args.concat($A(arguments)));
+      var a = merge(args, arguments);
+      return __method.apply(this, a);
     }
-  },
+  }
 
-  delay: function() {
-    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+  function delay(timeout) {
+    var __method = this, args = slice.call(arguments, 1);
+    timeout = timeout * 1000
     return window.setTimeout(function() {
       return __method.apply(__method, args);
     }, timeout);
-  },
+  }
 
-  defer: function() {
-    var args = [0.01].concat($A(arguments));
+  function defer() {
+    var args = update([0.01], arguments);
     return this.delay.apply(this, args);
-  },
+  }
 
-  wrap: function(wrapper) {
+  function wrap(wrapper) {
     var __method = this;
     return function() {
-      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+      var a = update([__method.bind(this)], arguments);
+      return wrapper.apply(this, a);
     }
-  },
+  }
 
-  methodize: function() {
+  function methodize() {
     if (this._methodized) return this._methodized;
     var __method = this;
     return this._methodized = function() {
-      return __method.apply(null, [this].concat($A(arguments)));
+      var a = update([this], arguments);
+      return __method.apply(null, a);
     };
   }
-});
+
+  return {
+    argumentNames:       argumentNames,
+    bind:                bind,
+    bindAsEventListener: bindAsEventListener,
+    curry:               curry,
+    delay:               delay,
+    defer:               defer,
+    wrap:                wrap,
+    methodize:           methodize
+  }
+})());
+
 
 Date.prototype.toJSON = function() {
   return '"' + this.getUTCFullYear() + '-' +
@@ -267,30 +361,12 @@ Date.prototype.toJSON = function() {
     this.getUTCSeconds().toPaddedString(2) + 'Z"';
 };
 
-var Try = {
-  these: function() {
-    var returnValue;
-
-    for (var i = 0, length = arguments.length; i < length; i++) {
-      var lambda = arguments[i];
-      try {
-        returnValue = lambda();
-        break;
-      } catch (e) { }
-    }
-
-    return returnValue;
-  }
-};
 
 RegExp.prototype.match = RegExp.prototype.test;
 
 RegExp.escape = function(str) {
   return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
 };
-
-/*--------------------------------------------------------------------------*/
-
 var PeriodicalExecuter = Class.create({
   initialize: function(callback, frequency) {
     this.callback = callback;
@@ -319,8 +395,10 @@ var PeriodicalExecuter = Class.create({
       try {
         this.currentlyExecuting = true;
         this.execute();
-      } finally {
         this.currentlyExecuting = false;
+      } catch(e) {
+        this.currentlyExecuting = false;
+        throw e;
       }
     }
   }
@@ -339,10 +417,25 @@ Object.extend(String, {
   }
 });
 
-Object.extend(String.prototype, {
-  gsub: function(pattern, replacement) {
+Object.extend(String.prototype, (function() {
+
+  function prepareReplacement(replacement) {
+    if (Object.isFunction(replacement)) return replacement;
+    var template = new Template(replacement);
+    return function(match) { return template.evaluate(match) };
+  }
+
+  function gsub(pattern, replacement) {
     var result = '', source = this, match;
-    replacement = arguments.callee.prepareReplacement(replacement);
+    replacement = prepareReplacement(replacement);
+
+    if (Object.isString(pattern))
+      pattern = RegExp.escape(pattern);
+
+    if (!(pattern.length || pattern.source)) {
+      replacement = replacement('');
+      return replacement + source.split('').join(replacement) + replacement;
+    }
 
     while (source.length > 0) {
       if (match = source.match(pattern)) {
@@ -354,69 +447,64 @@ Object.extend(String.prototype, {
       }
     }
     return result;
-  },
+  }
 
-  sub: function(pattern, replacement, count) {
-    replacement = this.gsub.prepareReplacement(replacement);
+  function sub(pattern, replacement, count) {
+    replacement = prepareReplacement(replacement);
     count = Object.isUndefined(count) ? 1 : count;
 
     return this.gsub(pattern, function(match) {
       if (--count < 0) return match[0];
       return replacement(match);
     });
-  },
+  }
 
-  scan: function(pattern, iterator) {
+  function scan(pattern, iterator) {
     this.gsub(pattern, iterator);
     return String(this);
-  },
+  }
 
-  truncate: function(length, truncation) {
+  function truncate(length, truncation) {
     length = length || 30;
     truncation = Object.isUndefined(truncation) ? '...' : truncation;
     return this.length > length ?
       this.slice(0, length - truncation.length) + truncation : String(this);
-  },
+  }
 
-  strip: function() {
+  function strip() {
     return this.replace(/^\s+/, '').replace(/\s+$/, '');
-  },
+  }
 
-  stripTags: function() {
-    return this.replace(/<\/?[^>]+>/gi, '');
-  },
+  function stripTags() {
+    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
+  }
 
-  stripScripts: function() {
+  function stripScripts() {
     return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
-  },
+  }
 
-  extractScripts: function() {
+  function extractScripts() {
     var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
     var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
     return (this.match(matchAll) || []).map(function(scriptTag) {
       return (scriptTag.match(matchOne) || ['', ''])[1];
     });
-  },
+  }
 
-  evalScripts: function() {
+  function evalScripts() {
     return this.extractScripts().map(function(script) { return eval(script) });
-  },
+  }
 
-  escapeHTML: function() {
-    var self = arguments.callee;
-    self.text.data = this;
-    return self.div.innerHTML;
-  },
+  function escapeHTML() {
+    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+  }
+
+  function unescapeHTML() {
+    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
+  }
 
-  unescapeHTML: function() {
-    var div = new Element('div');
-    div.innerHTML = this.stripTags();
-    return div.childNodes[0] ? (div.childNodes.length > 1 ?
-      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
-      div.childNodes[0].nodeValue) : '';
-  },
 
-  toQueryParams: function(separator) {
+  function toQueryParams(separator) {
     var match = this.strip().match(/([^?#]*)(#.*)?$/);
     if (!match) return { };
 
@@ -434,22 +522,22 @@ Object.extend(String.prototype, {
       }
       return hash;
     });
-  },
+  }
 
-  toArray: function() {
+  function toArray() {
     return this.split('');
-  },
+  }
 
-  succ: function() {
+  function succ() {
     return this.slice(0, this.length - 1) +
       String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
-  },
+  }
 
-  times: function(count) {
+  function times(count) {
     return count < 1 ? '' : new Array(count + 1).join(this);
-  },
+  }
 
-  camelize: function() {
+  function camelize() {
     var parts = this.split('-'), len = parts.length;
     if (len == 1) return parts[0];
 
@@ -461,101 +549,117 @@ Object.extend(String.prototype, {
       camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
 
     return camelized;
-  },
+  }
 
-  capitalize: function() {
+  function capitalize() {
     return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
-  },
+  }
 
-  underscore: function() {
-    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
-  },
+  function underscore() {
+    return this.replace(/::/g, '/')
+               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
+               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+               .replace(/-/g, '_')
+               .toLowerCase();
+  }
 
-  dasherize: function() {
-    return this.gsub(/_/,'-');
-  },
+  function dasherize() {
+    return this.replace(/_/g, '-');
+  }
 
-  inspect: function(useDoubleQuotes) {
-    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
-      var character = String.specialChar[match[0]];
-      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+  function inspect(useDoubleQuotes) {
+    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
+      if (character in String.specialChar) {
+        return String.specialChar[character];
+      }
+      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
     });
     if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
     return "'" + escapedString.replace(/'/g, '\\\'') + "'";
-  },
+  }
 
-  toJSON: function() {
+  function toJSON() {
     return this.inspect(true);
-  },
+  }
 
-  unfilterJSON: function(filter) {
-    return this.sub(filter || Prototype.JSONFilter, '#{1}');
-  },
+  function unfilterJSON(filter) {
+    return this.replace(filter || Prototype.JSONFilter, '$1');
+  }
 
-  isJSON: function() {
+  function isJSON() {
     var str = this;
     if (str.blank()) return false;
     str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
     return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
-  },
+  }
 
-  evalJSON: function(sanitize) {
+  function evalJSON(sanitize) {
     var json = this.unfilterJSON();
     try {
       if (!sanitize || json.isJSON()) return eval('(' + json + ')');
     } catch (e) { }
     throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
-  },
+  }
 
-  include: function(pattern) {
+  function include(pattern) {
     return this.indexOf(pattern) > -1;
-  },
+  }
 
-  startsWith: function(pattern) {
+  function startsWith(pattern) {
     return this.indexOf(pattern) === 0;
-  },
+  }
 
-  endsWith: function(pattern) {
+  function endsWith(pattern) {
     var d = this.length - pattern.length;
     return d >= 0 && this.lastIndexOf(pattern) === d;
-  },
+  }
 
-  empty: function() {
+  function empty() {
     return this == '';
-  },
+  }
 
-  blank: function() {
+  function blank() {
     return /^\s*$/.test(this);
-  },
-
-  interpolate: function(object, pattern) {
-    return new Template(this, pattern).evaluate(object);
   }
-});
 
-if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
-  escapeHTML: function() {
-    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
-  },
-  unescapeHTML: function() {
-    return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
+  function interpolate(object, pattern) {
+    return new Template(this, pattern).evaluate(object);
   }
-});
-
-String.prototype.gsub.prepareReplacement = function(replacement) {
-  if (Object.isFunction(replacement)) return replacement;
-  var template = new Template(replacement);
-  return function(match) { return template.evaluate(match) };
-};
 
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-Object.extend(String.prototype.escapeHTML, {
-  div:  document.createElement('div'),
-  text: document.createTextNode('')
-});
-
-String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
+  return {
+    gsub:           gsub,
+    sub:            sub,
+    scan:           scan,
+    truncate:       truncate,
+    strip:          String.prototype.trim ? String.prototype.trim : strip,
+    stripTags:      stripTags,
+    stripScripts:   stripScripts,
+    extractScripts: extractScripts,
+    evalScripts:    evalScripts,
+    escapeHTML:     escapeHTML,
+    unescapeHTML:   unescapeHTML,
+    toQueryParams:  toQueryParams,
+    parseQuery:     toQueryParams,
+    toArray:        toArray,
+    succ:           succ,
+    times:          times,
+    camelize:       camelize,
+    capitalize:     capitalize,
+    underscore:     underscore,
+    dasherize:      dasherize,
+    inspect:        inspect,
+    toJSON:         toJSON,
+    unfilterJSON:   unfilterJSON,
+    isJSON:         isJSON,
+    evalJSON:       evalJSON,
+    include:        include,
+    startsWith:     startsWith,
+    endsWith:       endsWith,
+    empty:          empty,
+    blank:          blank,
+    interpolate:    interpolate
+  };
+})());
 
 var Template = Class.create({
   initialize: function(template, pattern) {
@@ -564,11 +668,11 @@ var Template = Class.create({
   },
 
   evaluate: function(object) {
-    if (Object.isFunction(object.toTemplateReplacements))
+    if (object && Object.isFunction(object.toTemplateReplacements))
       object = object.toTemplateReplacements();
 
     return this.template.gsub(this.pattern, function(match) {
-      if (object == null) return '';
+      if (object == null) return (match[1] + '');
 
       var before = match[1] || '';
       if (before == '\\') return match[2];
@@ -579,7 +683,7 @@ var Template = Class.create({
       if (match == null) return before;
 
       while (match != null) {
-        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
         ctx = ctx[comp];
         if (null == ctx || '' == match[3]) break;
         expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
@@ -594,8 +698,8 @@ Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
 
 var $break = { };
 
-var Enumerable = {
-  each: function(iterator, context) {
+var Enumerable = (function() {
+  function each(iterator, context) {
     var index = 0;
     try {
       this._each(function(value) {
@@ -605,17 +709,17 @@ var Enumerable = {
       if (e != $break) throw e;
     }
     return this;
-  },
+  }
 
-  eachSlice: function(number, iterator, context) {
+  function eachSlice(number, iterator, context) {
     var index = -number, slices = [], array = this.toArray();
     if (number < 1) return array;
     while ((index += number) < array.length)
       slices.push(array.slice(index, index+number));
     return slices.collect(iterator, context);
-  },
+  }
 
-  all: function(iterator, context) {
+  function all(iterator, context) {
     iterator = iterator || Prototype.K;
     var result = true;
     this.each(function(value, index) {
@@ -623,9 +727,9 @@ var Enumerable = {
       if (!result) throw $break;
     });
     return result;
-  },
+  }
 
-  any: function(iterator, context) {
+  function any(iterator, context) {
     iterator = iterator || Prototype.K;
     var result = false;
     this.each(function(value, index) {
@@ -633,18 +737,18 @@ var Enumerable = {
         throw $break;
     });
     return result;
-  },
+  }
 
-  collect: function(iterator, context) {
+  function collect(iterator, context) {
     iterator = iterator || Prototype.K;
     var results = [];
     this.each(function(value, index) {
       results.push(iterator.call(context, value, index));
     });
     return results;
-  },
+  }
 
-  detect: function(iterator, context) {
+  function detect(iterator, context) {
     var result;
     this.each(function(value, index) {
       if (iterator.call(context, value, index)) {
@@ -653,32 +757,32 @@ var Enumerable = {
       }
     });
     return result;
-  },
+  }
 
-  findAll: function(iterator, context) {
+  function findAll(iterator, context) {
     var results = [];
     this.each(function(value, index) {
       if (iterator.call(context, value, index))
         results.push(value);
     });
     return results;
-  },
+  }
 
-  grep: function(filter, iterator, context) {
+  function grep(filter, iterator, context) {
     iterator = iterator || Prototype.K;
     var results = [];
 
     if (Object.isString(filter))
-      filter = new RegExp(filter);
+      filter = new RegExp(RegExp.escape(filter));
 
     this.each(function(value, index) {
       if (filter.match(value))
         results.push(iterator.call(context, value, index));
     });
     return results;
-  },
+  }
 
-  include: function(object) {
+  function include(object) {
     if (Object.isFunction(this.indexOf))
       if (this.indexOf(object) != -1) return true;
 
@@ -690,31 +794,31 @@ var Enumerable = {
       }
     });
     return found;
-  },
+  }
 
-  inGroupsOf: function(number, fillWith) {
+  function inGroupsOf(number, fillWith) {
     fillWith = Object.isUndefined(fillWith) ? null : fillWith;
     return this.eachSlice(number, function(slice) {
       while(slice.length < number) slice.push(fillWith);
       return slice;
     });
-  },
+  }
 
-  inject: function(memo, iterator, context) {
+  function inject(memo, iterator, context) {
     this.each(function(value, index) {
       memo = iterator.call(context, memo, value, index);
     });
     return memo;
-  },
+  }
 
-  invoke: function(method) {
+  function invoke(method) {
     var args = $A(arguments).slice(1);
     return this.map(function(value) {
       return value[method].apply(value, args);
     });
-  },
+  }
 
-  max: function(iterator, context) {
+  function max(iterator, context) {
     iterator = iterator || Prototype.K;
     var result;
     this.each(function(value, index) {
@@ -723,9 +827,9 @@ var Enumerable = {
         result = value;
     });
     return result;
-  },
+  }
 
-  min: function(iterator, context) {
+  function min(iterator, context) {
     iterator = iterator || Prototype.K;
     var result;
     this.each(function(value, index) {
@@ -734,9 +838,9 @@ var Enumerable = {
         result = value;
     });
     return result;
-  },
+  }
 
-  partition: function(iterator, context) {
+  function partition(iterator, context) {
     iterator = iterator || Prototype.K;
     var trues = [], falses = [];
     this.each(function(value, index) {
@@ -744,26 +848,26 @@ var Enumerable = {
         trues : falses).push(value);
     });
     return [trues, falses];
-  },
+  }
 
-  pluck: function(property) {
+  function pluck(property) {
     var results = [];
     this.each(function(value) {
       results.push(value[property]);
     });
     return results;
-  },
+  }
 
-  reject: function(iterator, context) {
+  function reject(iterator, context) {
     var results = [];
     this.each(function(value, index) {
       if (!iterator.call(context, value, index))
         results.push(value);
     });
     return results;
-  },
+  }
 
-  sortBy: function(iterator, context) {
+  function sortBy(iterator, context) {
     return this.map(function(value, index) {
       return {
         value: value,
@@ -773,13 +877,13 @@ var Enumerable = {
       var a = left.criteria, b = right.criteria;
       return a < b ? -1 : a > b ? 1 : 0;
     }).pluck('value');
-  },
+  }
 
-  toArray: function() {
+  function toArray() {
     return this.map();
-  },
+  }
 
-  zip: function() {
+  function zip() {
     var iterator = Prototype.K, args = $A(arguments);
     if (Object.isFunction(args.last()))
       iterator = args.pop();
@@ -788,130 +892,152 @@ var Enumerable = {
     return this.map(function(value, index) {
       return iterator(collections.pluck(index));
     });
-  },
+  }
 
-  size: function() {
+  function size() {
     return this.toArray().length;
-  },
+  }
 
-  inspect: function() {
+  function inspect() {
     return '#<Enumerable:' + this.toArray().inspect() + '>';
   }
-};
 
-Object.extend(Enumerable, {
-  map:     Enumerable.collect,
-  find:    Enumerable.detect,
-  select:  Enumerable.findAll,
-  filter:  Enumerable.findAll,
-  member:  Enumerable.include,
-  entries: Enumerable.toArray,
-  every:   Enumerable.all,
-  some:    Enumerable.any
-});
+
+
+
+
+
+
+
+
+  return {
+    each:       each,
+    eachSlice:  eachSlice,
+    all:        all,
+    every:      all,
+    any:        any,
+    some:       any,
+    collect:    collect,
+    map:        collect,
+    detect:     detect,
+    findAll:    findAll,
+    select:     findAll,
+    filter:     findAll,
+    grep:       grep,
+    include:    include,
+    member:     include,
+    inGroupsOf: inGroupsOf,
+    inject:     inject,
+    invoke:     invoke,
+    max:        max,
+    min:        min,
+    partition:  partition,
+    pluck:      pluck,
+    reject:     reject,
+    sortBy:     sortBy,
+    toArray:    toArray,
+    entries:    toArray,
+    zip:        zip,
+    size:       size,
+    inspect:    inspect,
+    find:       detect
+  };
+})();
 function $A(iterable) {
   if (!iterable) return [];
-  if (iterable.toArray) return iterable.toArray();
+  if ('toArray' in Object(iterable)) return iterable.toArray();
   var length = iterable.length || 0, results = new Array(length);
   while (length--) results[length] = iterable[length];
   return results;
 }
 
-if (Prototype.Browser.WebKit) {
-  $A = function(iterable) {
-    if (!iterable) return [];
-    // In Safari, only use the `toArray` method if it's not a NodeList.
-    // A NodeList is a function, has an function `item` property, and a numeric
-    // `length` property. Adapted from Google Doctype.
-    if (!(typeof iterable === 'function' && typeof iterable.length ===
-        'number' && typeof iterable.item === 'function') && iterable.toArray)
-      return iterable.toArray();
-    var length = iterable.length || 0, results = new Array(length);
-    while (length--) results[length] = iterable[length];
-    return results;
-  };
+function $w(string) {
+  if (!Object.isString(string)) return [];
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
 }
 
 Array.from = $A;
 
-Object.extend(Array.prototype, Enumerable);
 
-if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+(function() {
+  var arrayProto = Array.prototype,
+      slice = arrayProto.slice,
+      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
 
-Object.extend(Array.prototype, {
-  _each: function(iterator) {
+  function each(iterator) {
     for (var i = 0, length = this.length; i < length; i++)
       iterator(this[i]);
-  },
+  }
+  if (!_each) _each = each;
 
-  clear: function() {
+  function clear() {
     this.length = 0;
     return this;
-  },
+  }
 
-  first: function() {
+  function first() {
     return this[0];
-  },
+  }
 
-  last: function() {
+  function last() {
     return this[this.length - 1];
-  },
+  }
 
-  compact: function() {
+  function compact() {
     return this.select(function(value) {
       return value != null;
     });
-  },
+  }
 
-  flatten: function() {
+  function flatten() {
     return this.inject([], function(array, value) {
-      return array.concat(Object.isArray(value) ?
-        value.flatten() : [value]);
+      if (Object.isArray(value))
+        return array.concat(value.flatten());
+      array.push(value);
+      return array;
     });
-  },
+  }
 
-  without: function() {
-    var values = $A(arguments);
+  function without() {
+    var values = slice.call(arguments, 0);
     return this.select(function(value) {
       return !values.include(value);
     });
-  },
+  }
 
-  reverse: function(inline) {
+  function reverse(inline) {
     return (inline !== false ? this : this.toArray())._reverse();
-  },
-
-  reduce: function() {
-    return this.length > 1 ? this : this[0];
-  },
+  }
 
-  uniq: function(sorted) {
+  function uniq(sorted) {
     return this.inject([], function(array, value, index) {
       if (0 == index || (sorted ? array.last() != value : !array.include(value)))
         array.push(value);
       return array;
     });
-  },
+  }
 
-  intersect: function(array) {
+  function intersect(array) {
     return this.uniq().findAll(function(item) {
       return array.detect(function(value) { return item === value });
     });
-  },
+  }
 
-  clone: function() {
-    return [].concat(this);
-  },
 
-  size: function() {
+  function clone() {
+    return slice.call(this, 0);
+  }
+
+  function size() {
     return this.length;
-  },
+  }
 
-  inspect: function() {
+  function inspect() {
     return '[' + this.map(Object.inspect).join(', ') + ']';
-  },
+  }
 
-  toJSON: function() {
+  function toJSON() {
     var results = [];
     this.each(function(object) {
       var value = Object.toJSON(object);
@@ -919,205 +1045,270 @@ Object.extend(Array.prototype, {
     });
     return '[' + results.join(', ') + ']';
   }
-});
-
-// use native browser JS 1.6 implementation if available
-if (Object.isFunction(Array.prototype.forEach))
-  Array.prototype._each = Array.prototype.forEach;
-
-if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
-  i || (i = 0);
-  var length = this.length;
-  if (i < 0) i = length + i;
-  for (; i < length; i++)
-    if (this[i] === item) return i;
-  return -1;
-};
-
-if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
-  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
-  var n = this.slice(0, i).reverse().indexOf(item);
-  return (n < 0) ? n : i - n - 1;
-};
 
-Array.prototype.toArray = Array.prototype.clone;
+  function indexOf(item, i) {
+    i || (i = 0);
+    var length = this.length;
+    if (i < 0) i = length + i;
+    for (; i < length; i++)
+      if (this[i] === item) return i;
+    return -1;
+  }
 
-function $w(string) {
-  if (!Object.isString(string)) return [];
-  string = string.strip();
-  return string ? string.split(/\s+/) : [];
-}
+  function lastIndexOf(item, i) {
+    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+    var n = this.slice(0, i).reverse().indexOf(item);
+    return (n < 0) ? n : i - n - 1;
+  }
 
-if (Prototype.Browser.Opera){
-  Array.prototype.concat = function() {
-    var array = [];
-    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+  function concat() {
+    var array = slice.call(this, 0), item;
     for (var i = 0, length = arguments.length; i < length; i++) {
-      if (Object.isArray(arguments[i])) {
-        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
-          array.push(arguments[i][j]);
+      item = arguments[i];
+      if (Object.isArray(item) && !('callee' in item)) {
+        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
+          array.push(item[j]);
       } else {
-        array.push(arguments[i]);
+        array.push(item);
       }
     }
     return array;
-  };
-}
-Object.extend(Number.prototype, {
-  toColorPart: function() {
-    return this.toPaddedString(2, 16);
-  },
-
-  succ: function() {
-    return this + 1;
-  },
+  }
 
-  times: function(iterator, context) {
-    $R(0, this, true).each(iterator, context);
-    return this;
-  },
+  Object.extend(arrayProto, Enumerable);
+
+  if (!arrayProto._reverse)
+    arrayProto._reverse = arrayProto.reverse;
+
+  Object.extend(arrayProto, {
+    _each:     _each,
+    clear:     clear,
+    first:     first,
+    last:      last,
+    compact:   compact,
+    flatten:   flatten,
+    without:   without,
+    reverse:   reverse,
+    uniq:      uniq,
+    intersect: intersect,
+    clone:     clone,
+    toArray:   clone,
+    size:      size,
+    inspect:   inspect,
+    toJSON:    toJSON
+  });
 
-  toPaddedString: function(length, radix) {
-    var string = this.toString(radix || 10);
-    return '0'.times(length - string.length) + string;
-  },
+  var CONCAT_ARGUMENTS_BUGGY = (function() {
+    return [].concat(arguments)[0][0] !== 1;
+  })(1,2)
 
-  toJSON: function() {
-    return isFinite(this) ? this.toString() : 'null';
-  }
-});
+  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
 
-$w('abs round ceil floor').each(function(method){
-  Number.prototype[method] = Math[method].methodize();
-});
+  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
+  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
+})();
 function $H(object) {
   return new Hash(object);
 };
 
 var Hash = Class.create(Enumerable, (function() {
+  function initialize(object) {
+    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+  }
+
+  function _each(iterator) {
+    for (var key in this._object) {
+      var value = this._object[key], pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  }
+
+  function set(key, value) {
+    return this._object[key] = value;
+  }
+
+  function get(key) {
+    if (this._object[key] !== Object.prototype[key])
+      return this._object[key];
+  }
+
+  function unset(key) {
+    var value = this._object[key];
+    delete this._object[key];
+    return value;
+  }
+
+  function toObject() {
+    return Object.clone(this._object);
+  }
+
+  function keys() {
+    return this.pluck('key');
+  }
+
+  function values() {
+    return this.pluck('value');
+  }
+
+  function index(value) {
+    var match = this.detect(function(pair) {
+      return pair.value === value;
+    });
+    return match && match.key;
+  }
+
+  function merge(object) {
+    return this.clone().update(object);
+  }
+
+  function update(object) {
+    return new Hash(object).inject(this, function(result, pair) {
+      result.set(pair.key, pair.value);
+      return result;
+    });
+  }
 
   function toQueryPair(key, value) {
     if (Object.isUndefined(value)) return key;
     return key + '=' + encodeURIComponent(String.interpret(value));
   }
 
-  return {
-    initialize: function(object) {
-      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
-    },
+  function toQueryString() {
+    return this.inject([], function(results, pair) {
+      var key = encodeURIComponent(pair.key), values = pair.value;
 
-    _each: function(iterator) {
-      for (var key in this._object) {
-        var value = this._object[key], pair = [key, value];
-        pair.key = key;
-        pair.value = value;
-        iterator(pair);
-      }
-    },
-
-    set: function(key, value) {
-      return this._object[key] = value;
-    },
+      if (values && typeof values == 'object') {
+        if (Object.isArray(values))
+          return results.concat(values.map(toQueryPair.curry(key)));
+      } else results.push(toQueryPair(key, values));
+      return results;
+    }).join('&');
+  }
 
-    get: function(key) {
-      // simulating poorly supported hasOwnProperty
-      if (this._object[key] !== Object.prototype[key])
-        return this._object[key];
-    },
+  function inspect() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  }
 
-    unset: function(key) {
-      var value = this._object[key];
-      delete this._object[key];
-      return value;
-    },
+  function toJSON() {
+    return Object.toJSON(this.toObject());
+  }
 
-    toObject: function() {
-      return Object.clone(this._object);
-    },
+  function clone() {
+    return new Hash(this);
+  }
 
-    keys: function() {
-      return this.pluck('key');
-    },
+  return {
+    initialize:             initialize,
+    _each:                  _each,
+    set:                    set,
+    get:                    get,
+    unset:                  unset,
+    toObject:               toObject,
+    toTemplateReplacements: toObject,
+    keys:                   keys,
+    values:                 values,
+    index:                  index,
+    merge:                  merge,
+    update:                 update,
+    toQueryString:          toQueryString,
+    inspect:                inspect,
+    toJSON:                 toJSON,
+    clone:                  clone
+  };
+})());
 
-    values: function() {
-      return this.pluck('value');
-    },
+Hash.from = $H;
+Object.extend(Number.prototype, (function() {
+  function toColorPart() {
+    return this.toPaddedString(2, 16);
+  }
 
-    index: function(value) {
-      var match = this.detect(function(pair) {
-        return pair.value === value;
-      });
-      return match && match.key;
-    },
+  function succ() {
+    return this + 1;
+  }
 
-    merge: function(object) {
-      return this.clone().update(object);
-    },
+  function times(iterator, context) {
+    $R(0, this, true).each(iterator, context);
+    return this;
+  }
 
-    update: function(object) {
-      return new Hash(object).inject(this, function(result, pair) {
-        result.set(pair.key, pair.value);
-        return result;
-      });
-    },
+  function toPaddedString(length, radix) {
+    var string = this.toString(radix || 10);
+    return '0'.times(length - string.length) + string;
+  }
 
-    toQueryString: function() {
-      return this.inject([], function(results, pair) {
-        var key = encodeURIComponent(pair.key), values = pair.value;
+  function toJSON() {
+    return isFinite(this) ? this.toString() : 'null';
+  }
 
-        if (values && typeof values == 'object') {
-          if (Object.isArray(values))
-            return results.concat(values.map(toQueryPair.curry(key)));
-        } else results.push(toQueryPair(key, values));
-        return results;
-      }).join('&');
-    },
+  function abs() {
+    return Math.abs(this);
+  }
 
-    inspect: function() {
-      return '#<Hash:{' + this.map(function(pair) {
-        return pair.map(Object.inspect).join(': ');
-      }).join(', ') + '}>';
-    },
+  function round() {
+    return Math.round(this);
+  }
 
-    toJSON: function() {
-      return Object.toJSON(this.toObject());
-    },
+  function ceil() {
+    return Math.ceil(this);
+  }
 
-    clone: function() {
-      return new Hash(this);
-    }
+  function floor() {
+    return Math.floor(this);
   }
+
+  return {
+    toColorPart:    toColorPart,
+    succ:           succ,
+    times:          times,
+    toPaddedString: toPaddedString,
+    toJSON:         toJSON,
+    abs:            abs,
+    round:          round,
+    ceil:           ceil,
+    floor:          floor
+  };
 })());
 
-Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
-Hash.from = $H;
-var ObjectRange = Class.create(Enumerable, {
-  initialize: function(start, end, exclusive) {
+function $R(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+}
+
+var ObjectRange = Class.create(Enumerable, (function() {
+  function initialize(start, end, exclusive) {
     this.start = start;
     this.end = end;
     this.exclusive = exclusive;
-  },
+  }
 
-  _each: function(iterator) {
+  function _each(iterator) {
     var value = this.start;
     while (this.include(value)) {
       iterator(value);
       value = value.succ();
     }
-  },
+  }
 
-  include: function(value) {
+  function include(value) {
     if (value < this.start)
       return false;
     if (this.exclusive)
       return value < this.end;
     return value <= this.end;
   }
-});
 
-var $R = function(start, end, exclusive) {
-  return new ObjectRange(start, end, exclusive);
-};
+  return {
+    initialize: initialize,
+    _each:      _each,
+    include:    include
+  };
+})());
+
+
 
 var Ajax = {
   getTransport: function() {
@@ -1164,7 +1355,6 @@ Ajax.Responders.register({
   onCreate:   function() { Ajax.activeRequestCount++ },
   onComplete: function() { Ajax.activeRequestCount-- }
 });
-
 Ajax.Base = Class.create({
   initialize: function(options) {
     this.options = {
@@ -1186,7 +1376,6 @@ Ajax.Base = Class.create({
       this.options.parameters = this.options.parameters.toObject();
   }
 });
-
 Ajax.Request = Class.create(Ajax.Base, {
   _complete: false,
 
@@ -1202,7 +1391,6 @@ Ajax.Request = Class.create(Ajax.Base, {
     var params = Object.clone(this.options.parameters);
 
     if (!['get', 'post'].include(this.method)) {
-      // simulate other verbs over post
       params['_method'] = this.method;
       this.method = 'post';
     }
@@ -1210,7 +1398,6 @@ Ajax.Request = Class.create(Ajax.Base, {
     this.parameters = params;
 
     if (params = Object.toQueryString(params)) {
-      // when GET, append parameters to URL
       if (this.method == 'get')
         this.url += (this.url.include('?') ? '&' : '?') + params;
       else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
@@ -1269,7 +1456,6 @@ Ajax.Request = Class.create(Ajax.Base, {
             headers['Connection'] = 'close';
     }
 
-    // user-defined headers
     if (typeof this.options.requestHeaders == 'object') {
       var extras = this.options.requestHeaders;
 
@@ -1323,7 +1509,6 @@ Ajax.Request = Class.create(Ajax.Base, {
     }
 
     if (state == 'Complete') {
-      // avoid memory leak in MSIE: clean up
       this.transport.onreadystatechange = Prototype.emptyFunction;
     }
   },
@@ -1340,7 +1525,7 @@ Ajax.Request = Class.create(Ajax.Base, {
   getHeader: function(name) {
     try {
       return this.transport.getResponseHeader(name) || null;
-    } catch (e) { return null }
+    } catch (e) { return null; }
   },
 
   evalResponse: function() {
@@ -1360,6 +1545,13 @@ Ajax.Request = Class.create(Ajax.Base, {
 Ajax.Request.Events =
   ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
 
+
+
+
+
+
+
+
 Ajax.Response = Class.create({
   initialize: function(request){
     this.request = request;
@@ -1381,6 +1573,7 @@ Ajax.Response = Class.create({
   },
 
   status:      0,
+
   statusText: '',
 
   getStatus: Ajax.Request.prototype.getStatus,
@@ -1510,6 +1703,9 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
     this.updater = new Ajax.Updater(this.container, this.url, this.options);
   }
 });
+
+
+
 function $(element) {
   if (arguments.length > 1) {
     for (var i = 0, elements = [], length = arguments.length; i < length; i++)
@@ -1537,7 +1733,6 @@ if (Prototype.BrowserFeatures.XPath) {
 if (!window.Node) var Node = { };
 
 if (!Node.ELEMENT_NODE) {
-  // DOM level 2 ECMAScript Language Binding
   Object.extend(Node, {
     ELEMENT_NODE: 1,
     ATTRIBUTE_NODE: 2,
@@ -1554,13 +1749,30 @@ if (!Node.ELEMENT_NODE) {
   });
 }
 
-(function() {
-  var element = this.Element;
-  this.Element = function(tagName, attributes) {
+
+(function(global) {
+
+  var SETATTRIBUTE_IGNORES_NAME = (function(){
+    var elForm = document.createElement("form");
+    var elInput = document.createElement("input");
+    var root = document.documentElement;
+    elInput.setAttribute("name", "test");
+    elForm.appendChild(elInput);
+    root.appendChild(elForm);
+    var isBuggy = elForm.elements
+      ? (typeof elForm.elements.test == "undefined")
+      : null;
+    root.removeChild(elForm);
+    elForm = elInput = null;
+    return isBuggy;
+  })();
+
+  var element = global.Element;
+  global.Element = function(tagName, attributes) {
     attributes = attributes || { };
     tagName = tagName.toLowerCase();
     var cache = Element.cache;
-    if (Prototype.Browser.IE && attributes.name) {
+    if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
       tagName = '<' + tagName + ' name="' + attributes.name + '">';
       delete attributes.name;
       return Element.writeAttribute(document.createElement(tagName), attributes);
@@ -1568,11 +1780,12 @@ if (!Node.ELEMENT_NODE) {
     if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
     return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
   };
-  Object.extend(this.Element, element || { });
-  if (element) this.Element.prototype = element.prototype;
-}).call(window);
+  Object.extend(global.Element, element || { });
+  if (element) global.Element.prototype = element.prototype;
+})(this);
 
 Element.cache = { };
+Element.idCounter = 1;
 
 Element.Methods = {
   visible: function(element) {
@@ -1585,6 +1798,7 @@ Element.Methods = {
     return element;
   },
 
+
   hide: function(element) {
     element = $(element);
     element.style.display = 'none';
@@ -1603,15 +1817,89 @@ Element.Methods = {
     return element;
   },
 
-  update: function(element, content) {
-    element = $(element);
-    if (content && content.toElement) content = content.toElement();
-    if (Object.isElement(content)) return element.update().insert(content);
-    content = Object.toHTML(content);
-    element.innerHTML = content.stripScripts();
-    content.evalScripts.bind(content).defer();
-    return element;
-  },
+  update: (function(){
+
+    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
+      var el = document.createElement("select"),
+          isBuggy = true;
+      el.innerHTML = "<option value=\"test\">test</option>";
+      if (el.options && el.options[0]) {
+        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
+      }
+      el = null;
+      return isBuggy;
+    })();
+
+    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
+      try {
+        var el = document.createElement("table");
+        if (el && el.tBodies) {
+          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
+          var isBuggy = typeof el.tBodies[0] == "undefined";
+          el = null;
+          return isBuggy;
+        }
+      } catch (e) {
+        return true;
+      }
+    })();
+
+    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
+      var s = document.createElement("script"),
+          isBuggy = false;
+      try {
+        s.appendChild(document.createTextNode(""));
+        isBuggy = !s.firstChild ||
+          s.firstChild && s.firstChild.nodeType !== 3;
+      } catch (e) {
+        isBuggy = true;
+      }
+      s = null;
+      return isBuggy;
+    })();
+
+    function update(element, content) {
+      element = $(element);
+
+      if (content && content.toElement)
+        content = content.toElement();
+
+      if (Object.isElement(content))
+        return element.update().insert(content);
+
+      content = Object.toHTML(content);
+
+      var tagName = element.tagName.toUpperCase();
+
+      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
+        element.text = content;
+        return element;
+      }
+
+      if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
+        if (tagName in Element._insertionTranslations.tags) {
+          while (element.firstChild) {
+            element.removeChild(element.firstChild);
+          }
+          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+            .each(function(node) {
+              element.appendChild(node)
+            });
+        }
+        else {
+          element.innerHTML = content.stripScripts();
+        }
+      }
+      else {
+        element.innerHTML = content.stripScripts();
+      }
+
+      content.evalScripts.bind(content).defer();
+      return element;
+    }
+
+    return update;
+  })(),
 
   replace: function(element, content) {
     element = $(element);
@@ -1696,11 +1984,11 @@ Element.Methods = {
   },
 
   ancestors: function(element) {
-    return $(element).recursivelyCollect('parentNode');
+    return Element.recursivelyCollect(element, 'parentNode');
   },
 
   descendants: function(element) {
-    return $(element).select("*");
+    return Element.select(element, "*");
   },
 
   firstDescendant: function(element) {
@@ -1717,16 +2005,17 @@ Element.Methods = {
   },
 
   previousSiblings: function(element) {
-    return $(element).recursivelyCollect('previousSibling');
+    return Element.recursivelyCollect(element, 'previousSibling');
   },
 
   nextSiblings: function(element) {
-    return $(element).recursivelyCollect('nextSibling');
+    return Element.recursivelyCollect(element, 'nextSibling');
   },
 
   siblings: function(element) {
     element = $(element);
-    return element.previousSiblings().reverse().concat(element.nextSiblings());
+    return Element.previousSiblings(element).reverse()
+      .concat(Element.nextSiblings(element));
   },
 
   match: function(element, selector) {
@@ -1738,22 +2027,22 @@ Element.Methods = {
   up: function(element, expression, index) {
     element = $(element);
     if (arguments.length == 1) return $(element.parentNode);
-    var ancestors = element.ancestors();
+    var ancestors = Element.ancestors(element);
     return Object.isNumber(expression) ? ancestors[expression] :
       Selector.findElement(ancestors, expression, index);
   },
 
   down: function(element, expression, index) {
     element = $(element);
-    if (arguments.length == 1) return element.firstDescendant();
-    return Object.isNumber(expression) ? element.descendants()[expression] :
+    if (arguments.length == 1) return Element.firstDescendant(element);
+    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
       Element.select(element, expression)[index || 0];
   },
 
   previous: function(element, expression, index) {
     element = $(element);
     if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
-    var previousSiblings = element.previousSiblings();
+    var previousSiblings = Element.previousSiblings(element);
     return Object.isNumber(expression) ? previousSiblings[expression] :
       Selector.findElement(previousSiblings, expression, index);
   },
@@ -1761,27 +2050,28 @@ Element.Methods = {
   next: function(element, expression, index) {
     element = $(element);
     if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
-    var nextSiblings = element.nextSiblings();
+    var nextSiblings = Element.nextSiblings(element);
     return Object.isNumber(expression) ? nextSiblings[expression] :
       Selector.findElement(nextSiblings, expression, index);
   },
 
-  select: function() {
-    var args = $A(arguments), element = $(args.shift());
+
+  select: function(element) {
+    var args = Array.prototype.slice.call(arguments, 1);
     return Selector.findChildElements(element, args);
   },
 
-  adjacent: function() {
-    var args = $A(arguments), element = $(args.shift());
+  adjacent: function(element) {
+    var args = Array.prototype.slice.call(arguments, 1);
     return Selector.findChildElements(element.parentNode, args).without(element);
   },
 
   identify: function(element) {
     element = $(element);
-    var id = element.readAttribute('id'), self = arguments.callee;
+    var id = Element.readAttribute(element, 'id');
     if (id) return id;
-    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
-    element.writeAttribute('id', id);
+    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
+    Element.writeAttribute(element, 'id', id);
     return id;
   },
 
@@ -1820,11 +2110,11 @@ Element.Methods = {
   },
 
   getHeight: function(element) {
-    return $(element).getDimensions().height;
+    return Element.getDimensions(element).height;
   },
 
   getWidth: function(element) {
-    return $(element).getDimensions().width;
+    return Element.getDimensions(element).width;
   },
 
   classNames: function(element) {
@@ -1840,7 +2130,7 @@ Element.Methods = {
 
   addClassName: function(element, className) {
     if (!(element = $(element))) return;
-    if (!element.hasClassName(className))
+    if (!Element.hasClassName(element, className))
       element.className += (element.className ? ' ' : '') + className;
     return element;
   },
@@ -1854,11 +2144,10 @@ Element.Methods = {
 
   toggleClassName: function(element, className) {
     if (!(element = $(element))) return;
-    return element[element.hasClassName(className) ?
-      'removeClassName' : 'addClassName'](className);
+    return Element[Element.hasClassName(element, className) ?
+      'removeClassName' : 'addClassName'](element, className);
   },
 
-  // removes whitespace-only text node children
   cleanWhitespace: function(element) {
     element = $(element);
     var node = element.firstChild;
@@ -1892,7 +2181,7 @@ Element.Methods = {
 
   scrollTo: function(element) {
     element = $(element);
-    var pos = element.cumulativeOffset();
+    var pos = Element.cumulativeOffset(element);
     window.scrollTo(pos[0], pos[1]);
     return element;
   },
@@ -1940,18 +2229,17 @@ Element.Methods = {
 
   getDimensions: function(element) {
     element = $(element);
-    var display = element.getStyle('display');
+    var display = Element.getStyle(element, 'display');
     if (display != 'none' && display != null) // Safari bug
       return {width: element.offsetWidth, height: element.offsetHeight};
 
-    // All *Width and *Height properties give 0 on elements with display none,
-    // so enable the element temporarily
     var els = element.style;
     var originalVisibility = els.visibility;
     var originalPosition = els.position;
     var originalDisplay = els.display;
     els.visibility = 'hidden';
-    els.position = 'absolute';
+    if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
+      els.position = 'absolute';
     els.display = 'block';
     var originalWidth = element.clientWidth;
     var originalHeight = element.clientHeight;
@@ -1967,8 +2255,6 @@ Element.Methods = {
     if (pos == 'static' || !pos) {
       element._madePositioned = true;
       element.style.position = 'relative';
-      // Opera returns the offset relative to the positioning context, when an
-      // element is position relative but top and left have not been defined
       if (Prototype.Browser.Opera) {
         element.style.top = 0;
         element.style.left = 0;
@@ -2034,10 +2320,9 @@ Element.Methods = {
 
   absolutize: function(element) {
     element = $(element);
-    if (element.getStyle('position') == 'absolute') return element;
-    // Position.prepare(); // To be done manually by Scripty when it needs it.
+    if (Element.getStyle(element, 'position') == 'absolute') return element;
 
-    var offsets = element.positionedOffset();
+    var offsets = Element.positionedOffset(element);
     var top     = offsets[1];
     var left    = offsets[0];
     var width   = element.clientWidth;
@@ -2058,8 +2343,7 @@ Element.Methods = {
 
   relativize: function(element) {
     element = $(element);
-    if (element.getStyle('position') == 'relative') return element;
-    // Position.prepare(); // To be done manually by Scripty when it needs it.
+    if (Element.getStyle(element, 'position') == 'relative') return element;
 
     element.style.position = 'relative';
     var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
@@ -2083,29 +2367,28 @@ Element.Methods = {
   },
 
   getOffsetParent: function(element) {
-    element = $(element);
-    var op = element.offsetParent, body = document.body, docEl = document.documentElement;
+    if (element.offsetParent) return $(element.offsetParent);
+    if (element == document.body) return $(element);
 
-    /* IE with strict doctype may try to return documentElement as offsetParent
-       on relatively positioned elements, we will return body instead */
-    if (op && op !== docEl) return $(op);
-    if (op === docEl || element === docEl || element === body) return $(body);
-
-    while ((element = element.parentNode) && element !== body)
+    while ((element = element.parentNode) && element != document.body)
       if (Element.getStyle(element, 'position') != 'static')
         return $(element);
 
-    return $(body);
+    return $(document.body);
   },
 
   viewportOffset: function(forElement) {
-    forElement = $(forElement);
+    var valueT = 0, valueL = 0;
 
-    var element = forElement, valueT = 0, valueL = 0;
+    var element = forElement;
     do {
       valueT += element.offsetTop  || 0;
       valueL += element.offsetLeft || 0;
-    } while ((element = element.getOffsetParent()) != document.body);
+
+      if (element.offsetParent == document.body &&
+        Element.getStyle(element, 'position') == 'absolute') break;
+
+    } while (element = element.offsetParent);
 
     element = forElement;
     do {
@@ -2128,28 +2411,22 @@ Element.Methods = {
       offsetLeft: 0
     }, arguments[2] || { });
 
-    // find page position of source
     source = $(source);
-    var p = source.viewportOffset();
+    var p = Element.viewportOffset(source);
 
-    // find coordinate system to use
     element = $(element);
     var delta = [0, 0];
     var parent = null;
-    // delta [0,0] will do fine with position: fixed elements,
-    // position:absolute needs offsetParent deltas
     if (Element.getStyle(element, 'position') == 'absolute') {
-      parent = element.getOffsetParent();
-      delta = parent.viewportOffset();
+      parent = Element.getOffsetParent(element);
+      delta = Element.viewportOffset(parent);
     }
 
-    // correct by body offsets (fixes Safari)
     if (parent == document.body) {
       delta[0] -= document.body.offsetLeft;
       delta[1] -= document.body.offsetTop;
     }
 
-    // set position
     if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
     if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
     if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
@@ -2158,10 +2435,9 @@ Element.Methods = {
   }
 };
 
-Element.Methods.identify.counter = 1;
-
 Object.extend(Element.Methods, {
   getElementsBySelector: Element.Methods.select,
+
   childElements: Element.Methods.immediateDescendants
 });
 
@@ -2182,11 +2458,8 @@ if (Prototype.Browser.Opera) {
         case 'left': case 'top': case 'right': case 'bottom':
           if (proceed(element, 'position') === 'static') return null;
         case 'height': case 'width':
-          // returns '0px' for hidden elements; we want it to return null
           if (!Element.visible(element)) return null;
 
-          // returns the border-box dimensions rather than the content-box
-          // dimensions, so we subtract padding and borders from the value
           var dim = parseInt(proceed(element, style), 10);
 
           if (dim !== element['offset' + style.capitalize()])
@@ -2219,12 +2492,9 @@ if (Prototype.Browser.Opera) {
 }
 
 else if (Prototype.Browser.IE) {
-  // IE doesn't report offsets correctly for static elements, so we change them
-  // to "relative" to get the values, then change them back.
   Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
     function(proceed, element) {
       element = $(element);
-      // IE throws an error if element is not in document
       try { element.offsetParent }
       catch(e) { return $(document.body) }
       var position = element.getStyle('position');
@@ -2244,8 +2514,6 @@ else if (Prototype.Browser.IE) {
         catch(e) { return Element._returnOffset(0,0) }
         var position = element.getStyle('position');
         if (position !== 'static') return proceed(element);
-        // Trigger hasLayout on the offset parent so that IE6 reports
-        // accurate offsetTop and offsetLeft values for position: fixed.
         var offsetParent = element.getOffsetParent();
         if (offsetParent && offsetParent.getStyle('position') === 'fixed')
           offsetParent.setStyle({ zoom: 1 });
@@ -2306,36 +2574,92 @@ else if (Prototype.Browser.IE) {
     return element;
   };
 
-  Element._attributeTranslations = {
-    read: {
-      names: {
-        'class': 'className',
-        'for':   'htmlFor'
-      },
-      values: {
-        _getAttr: function(element, attribute) {
-          return element.getAttribute(attribute, 2);
-        },
-        _getAttrNode: function(element, attribute) {
-          var node = element.getAttributeNode(attribute);
-          return node ? node.value : "";
-        },
-        _getEv: function(element, attribute) {
-          attribute = element.getAttribute(attribute);
-          return attribute ? attribute.toString().slice(23, -2) : null;
-        },
-        _flag: function(element, attribute) {
-          return $(element).hasAttribute(attribute) ? attribute : null;
-        },
-        style: function(element) {
-          return element.style.cssText.toLowerCase();
+  Element._attributeTranslations = (function(){
+
+    var classProp = 'className';
+    var forProp = 'for';
+
+    var el = document.createElement('div');
+
+    el.setAttribute(classProp, 'x');
+
+    if (el.className !== 'x') {
+      el.setAttribute('class', 'x');
+      if (el.className === 'x') {
+        classProp = 'class';
+      }
+    }
+    el = null;
+
+    el = document.createElement('label');
+    el.setAttribute(forProp, 'x');
+    if (el.htmlFor !== 'x') {
+      el.setAttribute('htmlFor', 'x');
+      if (el.htmlFor === 'x') {
+        forProp = 'htmlFor';
+      }
+    }
+    el = null;
+
+    return {
+      read: {
+        names: {
+          'class':      classProp,
+          'className':  classProp,
+          'for':        forProp,
+          'htmlFor':    forProp
         },
-        title: function(element) {
-          return element.title;
+        values: {
+          _getAttr: function(element, attribute) {
+            return element.getAttribute(attribute);
+          },
+          _getAttr2: function(element, attribute) {
+            return element.getAttribute(attribute, 2);
+          },
+          _getAttrNode: function(element, attribute) {
+            var node = element.getAttributeNode(attribute);
+            return node ? node.value : "";
+          },
+          _getEv: (function(){
+
+            var el = document.createElement('div');
+            el.onclick = Prototype.emptyFunction;
+            var value = el.getAttribute('onclick');
+            var f;
+
+            if (String(value).indexOf('{') > -1) {
+              f = function(element, attribute) {
+                attribute = element.getAttribute(attribute);
+                if (!attribute) return null;
+                attribute = attribute.toString();
+                attribute = attribute.split('{')[1];
+                attribute = attribute.split('}')[0];
+                return attribute.strip();
+              };
+            }
+            else if (value === '') {
+              f = function(element, attribute) {
+                attribute = element.getAttribute(attribute);
+                if (!attribute) return null;
+                return attribute.strip();
+              };
+            }
+            el = null;
+            return f;
+          })(),
+          _flag: function(element, attribute) {
+            return $(element).hasAttribute(attribute) ? attribute : null;
+          },
+          style: function(element) {
+            return element.style.cssText.toLowerCase();
+          },
+          title: function(element) {
+            return element.title;
+          }
         }
       }
     }
-  };
+  })();
 
   Element._attributeTranslations.write = {
     names: Object.extend({
@@ -2363,8 +2687,8 @@ else if (Prototype.Browser.IE) {
 
   (function(v) {
     Object.extend(v, {
-      href:        v._getAttr,
-      src:         v._getAttr,
+      href:        v._getAttr2,
+      src:         v._getAttr2,
       type:        v._getAttr,
       action:      v._getAttrNode,
       disabled:    v._flag,
@@ -2391,6 +2715,26 @@ else if (Prototype.Browser.IE) {
       onchange:    v._getEv
     });
   })(Element._attributeTranslations.read.values);
+
+  if (Prototype.BrowserFeatures.ElementExtensions) {
+    (function() {
+      function _descendants(element) {
+        var nodes = element.getElementsByTagName('*'), results = [];
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.tagName !== "!") // Filter out comment nodes.
+            results.push(node);
+        return results;
+      }
+
+      Element.Methods.down = function(element, expression, index) {
+        element = $(element);
+        if (arguments.length == 1) return element.firstDescendant();
+        return Object.isNumber(expression) ? _descendants(element)[expression] :
+          Element.select(element, expression)[index || 0];
+      }
+    })();
+  }
+
 }
 
 else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
@@ -2420,9 +2764,6 @@ else if (Prototype.Browser.WebKit) {
     return element;
   };
 
-  // Safari returns margins on body which is incorrect if the child is absolutely
-  // positioned.  For performance reasons, redefine Element#cumulativeOffset for
-  // KHTML/WebKit only.
   Element.Methods.cumulativeOffset = function(element) {
     var valueT = 0, valueL = 0;
     do {
@@ -2438,30 +2779,7 @@ else if (Prototype.Browser.WebKit) {
   };
 }
 
-if (Prototype.Browser.IE || Prototype.Browser.Opera) {
-  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
-  Element.Methods.update = function(element, content) {
-    element = $(element);
-
-    if (content && content.toElement) content = content.toElement();
-    if (Object.isElement(content)) return element.update().insert(content);
-
-    content = Object.toHTML(content);
-    var tagName = element.tagName.toUpperCase();
-
-    if (tagName in Element._insertionTranslations.tags) {
-      $A(element.childNodes).each(function(node) { element.removeChild(node) });
-      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
-        .each(function(node) { element.appendChild(node) });
-    }
-    else element.innerHTML = content.stripScripts();
-
-    content.evalScripts.bind(content).defer();
-    return element;
-  };
-}
-
-if ('outerHTML' in document.createElement('div')) {
+if ('outerHTML' in document.documentElement) {
   Element.Methods.replace = function(element, content) {
     element = $(element);
 
@@ -2529,12 +2847,13 @@ Element._insertionTranslations = {
 };
 
 (function() {
-  Object.extend(this.tags, {
-    THEAD: this.tags.TBODY,
-    TFOOT: this.tags.TBODY,
-    TH:    this.tags.TD
+  var tags = Element._insertionTranslations.tags;
+  Object.extend(tags, {
+    THEAD: tags.TBODY,
+    TFOOT: tags.TBODY,
+    TH:    tags.TD
   });
-}).call(Element._insertionTranslations);
+})();
 
 Element.Methods.Simulated = {
   hasAttribute: function(element, attribute) {
@@ -2548,41 +2867,81 @@ Element.Methods.ByTag = { };
 
 Object.extend(Element, Element.Methods);
 
-if (!Prototype.BrowserFeatures.ElementExtensions &&
-    document.createElement('div')['__proto__']) {
-  window.HTMLElement = { };
-  window.HTMLElement.prototype = document.createElement('div')['__proto__'];
-  Prototype.BrowserFeatures.ElementExtensions = true;
-}
+(function(div) {
+
+  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
+    window.HTMLElement = { };
+    window.HTMLElement.prototype = div['__proto__'];
+    Prototype.BrowserFeatures.ElementExtensions = true;
+  }
+
+  div = null;
+
+})(document.createElement('div'))
 
 Element.extend = (function() {
-  if (Prototype.BrowserFeatures.SpecificElementExtensions)
+
+  function checkDeficiency(tagName) {
+    if (typeof window.Element != 'undefined') {
+      var proto = window.Element.prototype;
+      if (proto) {
+        var id = '_' + (Math.random()+'').slice(2);
+        var el = document.createElement(tagName);
+        proto[id] = 'x';
+        var isBuggy = (el[id] !== 'x');
+        delete proto[id];
+        el = null;
+        return isBuggy;
+      }
+    }
+    return false;
+  }
+
+  function extendElementWith(element, methods) {
+    for (var property in methods) {
+      var value = methods[property];
+      if (Object.isFunction(value) && !(property in element))
+        element[property] = value.methodize();
+    }
+  }
+
+  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
+
+  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
+    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
+      return function(element) {
+        if (element && typeof element._extendedByPrototype == 'undefined') {
+          var t = element.tagName;
+          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
+            extendElementWith(element, Element.Methods);
+            extendElementWith(element, Element.Methods.Simulated);
+            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
+          }
+        }
+        return element;
+      }
+    }
     return Prototype.K;
+  }
 
   var Methods = { }, ByTag = Element.Methods.ByTag;
 
   var extend = Object.extend(function(element) {
-    if (!element || element._extendedByPrototype ||
+    if (!element || typeof element._extendedByPrototype != 'undefined' ||
         element.nodeType != 1 || element == window) return element;
 
     var methods = Object.clone(Methods),
-      tagName = element.tagName.toUpperCase(), property, value;
+        tagName = element.tagName.toUpperCase();
 
-    // extend methods for specific tags
     if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
 
-    for (property in methods) {
-      value = methods[property];
-      if (Object.isFunction(value) && !(property in element))
-        element[property] = value.methodize();
-    }
+    extendElementWith(element, methods);
 
     element._extendedByPrototype = Prototype.emptyFunction;
     return element;
 
   }, {
     refresh: function() {
-      // extend methods for all tags (Safari doesn't need this)
       if (!Prototype.BrowserFeatures.ElementExtensions) {
         Object.extend(Methods, Element.Methods);
         Object.extend(Methods, Element.Methods.Simulated);
@@ -2661,14 +3020,18 @@ Element.addMethods = function(methods) {
     klass = 'HTML' + tagName.capitalize() + 'Element';
     if (window[klass]) return window[klass];
 
-    window[klass] = { };
-    window[klass].prototype = document.createElement(tagName)['__proto__'];
-    return window[klass];
+    var element = document.createElement(tagName);
+    var proto = element['__proto__'] || element.constructor.prototype;
+    element = null;
+    return proto;
   }
 
+  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
+   Element.prototype;
+
   if (F.ElementExtensions) {
-    copy(Element.Methods, HTMLElement.prototype);
-    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    copy(Element.Methods, elementPrototype);
+    copy(Element.Methods.Simulated, elementPrototype, true);
   }
 
   if (F.SpecificElementExtensions) {
@@ -2686,38 +3049,109 @@ Element.addMethods = function(methods) {
   Element.cache = { };
 };
 
-document.viewport = {
-  getDimensions: function() {
-    var dimensions = { }, B = Prototype.Browser;
-    $w('width height').each(function(d) {
-      var D = d.capitalize();
-      if (B.WebKit && !document.evaluate) {
-        // Safari <3.0 needs self.innerWidth/Height
-        dimensions[d] = self['inner' + D];
-      } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
-        // Opera <9.5 needs document.body.clientWidth/Height
-        dimensions[d] = document.body['client' + D]
-      } else {
-        dimensions[d] = document.documentElement['client' + D];
-      }
-    });
-    return dimensions;
-  },
 
-  getWidth: function() {
-    return this.getDimensions().width;
-  },
+document.viewport = {
 
-  getHeight: function() {
-    return this.getDimensions().height;
+  getDimensions: function() {
+    return { width: this.getWidth(), height: this.getHeight() };
   },
 
   getScrollOffsets: function() {
     return Element._returnOffset(
       window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
-      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
   }
 };
+
+(function(viewport) {
+  var B = Prototype.Browser, doc = document, element, property = {};
+
+  function getRootElement() {
+    if (B.WebKit && !doc.evaluate)
+      return document;
+
+    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
+      return document.body;
+
+    return document.documentElement;
+  }
+
+  function define(D) {
+    if (!element) element = getRootElement();
+
+    property[D] = 'client' + D;
+
+    viewport['get' + D] = function() { return element[property[D]] };
+    return viewport['get' + D]();
+  }
+
+  viewport.getWidth  = define.curry('Width');
+
+  viewport.getHeight = define.curry('Height');
+})(document.viewport);
+
+
+Element.Storage = {
+  UID: 1
+};
+
+Element.addMethods({
+  getStorage: function(element) {
+    if (!(element = $(element))) return;
+
+    var uid;
+    if (element === window) {
+      uid = 0;
+    } else {
+      if (typeof element._prototypeUID === "undefined")
+        element._prototypeUID = [Element.Storage.UID++];
+      uid = element._prototypeUID[0];
+    }
+
+    if (!Element.Storage[uid])
+      Element.Storage[uid] = $H();
+
+    return Element.Storage[uid];
+  },
+
+  store: function(element, key, value) {
+    if (!(element = $(element))) return;
+
+    if (arguments.length === 2) {
+      Element.getStorage(element).update(key);
+    } else {
+      Element.getStorage(element).set(key, value);
+    }
+
+    return element;
+  },
+
+  retrieve: function(element, key, defaultValue) {
+    if (!(element = $(element))) return;
+    var hash = Element.getStorage(element), value = hash.get(key);
+
+    if (Object.isUndefined(value)) {
+      hash.set(key, defaultValue);
+      value = defaultValue;
+    }
+
+    return value;
+  },
+
+  clone: function(element, deep) {
+    if (!(element = $(element))) return;
+    var clone = element.cloneNode(deep);
+    clone._prototypeUID = void 0;
+    if (deep) {
+      var descendants = Element.select(clone, '*'),
+          i = descendants.length;
+      while (i--) {
+        descendants[i]._prototypeUID = void 0;
+      }
+    }
+    return Element.extend(clone);
+  }
+});
 /* Portions of the Selector class are derived from Jack Slocum's DomQuery,
  * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
  * license.  Please see http://www.yui-ext.com/ for more information. */
@@ -2738,31 +3172,52 @@ var Selector = Class.create({
 
   },
 
-  shouldUseXPath: function() {
-    if (!Prototype.BrowserFeatures.XPath) return false;
+  shouldUseXPath: (function() {
 
-    var e = this.expression;
+    var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
+      var isBuggy = false;
+      if (document.evaluate && window.XPathResult) {
+        var el = document.createElement('div');
+        el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
 
-    // Safari 3 chokes on :*-of-type and :empty
-    if (Prototype.Browser.WebKit &&
-     (e.include("-of-type") || e.include(":empty")))
-      return false;
+        var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
+          "//*[local-name()='li' or local-name()='LI']";
 
-    // XPath can't do namespaced attributes, nor can it read
-    // the "checked" property from DOM nodes
-    if ((/(\[[\w-]*?:|:checked)/).test(e))
-      return false;
+        var result = document.evaluate(xpath, el, null,
+          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
 
-    return true;
-  },
+        isBuggy = (result.snapshotLength !== 2);
+        el = null;
+      }
+      return isBuggy;
+    })();
+
+    return function() {
+      if (!Prototype.BrowserFeatures.XPath) return false;
+
+      var e = this.expression;
+
+      if (Prototype.Browser.WebKit &&
+       (e.include("-of-type") || e.include(":empty")))
+        return false;
+
+      if ((/(\[[\w-]*?:|:checked)/).test(e))
+        return false;
+
+      if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
+
+      return true;
+    }
+
+  })(),
 
   shouldUseSelectorsAPI: function() {
     if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
 
+    if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;
+
     if (!Selector._div) Selector._div = new Element('div');
 
-    // Make sure the browser treats the selector as valid. Test on an
-    // isolated element to minimize cost of this check.
     try {
       Selector._div.querySelector(this.expression);
     } catch(e) {
@@ -2774,7 +3229,7 @@ var Selector = Class.create({
 
   compileMatcher: function() {
     var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
-        c = Selector.criteria, le, p, m;
+        c = Selector.criteria, le, p, m, len = ps.length, name;
 
     if (Selector._cache[e]) {
       this.matcher = Selector._cache[e];
@@ -2786,11 +3241,12 @@ var Selector = Class.create({
 
     while (e && le != e && (/\S/).test(e)) {
       le = e;
-      for (var i in ps) {
-        p = ps[i];
+      for (var i = 0; i<len; i++) {
+        p = ps[i].re;
+        name = ps[i].name;
         if (m = e.match(p)) {
-          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
-            new Template(c[i]).evaluate(m));
+          this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
+            new Template(c[name]).evaluate(m));
           e = e.replace(m[0], '');
           break;
         }
@@ -2804,7 +3260,7 @@ var Selector = Class.create({
 
   compileXPathMatcher: function() {
     var e = this.expression, ps = Selector.patterns,
-        x = Selector.xpath, le, m;
+        x = Selector.xpath, le, m, len = ps.length, name;
 
     if (Selector._cache[e]) {
       this.xpath = Selector._cache[e]; return;
@@ -2813,10 +3269,11 @@ var Selector = Class.create({
     this.matcher = ['.//*'];
     while (e && le != e && (/\S/).test(e)) {
       le = e;
-      for (var i in ps) {
-        if (m = e.match(ps[i])) {
-          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
-            new Template(x[i]).evaluate(m));
+      for (var i = 0; i<len; i++) {
+        name = ps[i].name;
+        if (m = e.match(ps[i].re)) {
+          this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
+            new Template(x[name]).evaluate(m));
           e = e.replace(m[0], '');
           break;
         }
@@ -2833,11 +3290,9 @@ var Selector = Class.create({
 
     switch (this.mode) {
       case 'selectorsAPI':
-        // querySelectorAll queries document-wide, then filters to descendants
-        // of the context element. That's not what we want.
-        // Add an explicit context to the selector if necessary.
         if (root !== document) {
           var oldId = root.id, id = $(root).identify();
+          id = id.replace(/([\.:])/g, "\\$1");
           e = "#" + id + " " + e;
         }
 
@@ -2856,21 +3311,18 @@ var Selector = Class.create({
     this.tokens = [];
 
     var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
-    var le, p, m;
+    var le, p, m, len = ps.length, name;
 
     while (e && le !== e && (/\S/).test(e)) {
       le = e;
-      for (var i in ps) {
-        p = ps[i];
+      for (var i = 0; i<len; i++) {
+        p = ps[i].re;
+        name = ps[i].name;
         if (m = e.match(p)) {
-          // use the Selector.assertions methods unless the selector
-          // is too complex.
-          if (as[i]) {
-            this.tokens.push([i, Object.clone(m)]);
+          if (as[name]) {
+            this.tokens.push([name, Object.clone(m)]);
             e = e.replace(m[0], '');
           } else {
-            // reluctantly do a document-wide search
-            // and look for a match in the array
             return this.findElements(document).include(element);
           }
         }
@@ -2897,6 +3349,21 @@ var Selector = Class.create({
   }
 });
 
+if (Prototype.BrowserFeatures.SelectorsAPI &&
+ document.compatMode === 'BackCompat') {
+  Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
+    var div = document.createElement('div'),
+     span = document.createElement('span');
+
+    div.id = "prototype_test_id";
+    span.className = 'Test';
+    div.appendChild(span);
+    var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
+    div = span = null;
+    return isIgnored;
+  })();
+}
+
 Object.extend(Selector, {
   _cache: { },
 
@@ -2946,14 +3413,15 @@ Object.extend(Selector, {
       'enabled':     "[not(@disabled) and (@type!='hidden')]",
       'not': function(m) {
         var e = m[6], p = Selector.patterns,
-            x = Selector.xpath, le, v;
+            x = Selector.xpath, le, v, len = p.length, name;
 
         var exclusion = [];
         while (e && le != e && (/\S/).test(e)) {
           le = e;
-          for (var i in p) {
-            if (m = e.match(p[i])) {
-              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
+          for (var i = 0; i<len; i++) {
+            name = p[i].name
+            if (m = e.match(p[i].re)) {
+              v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
               exclusion.push("(" + v.substring(1, v.length - 1) + ")");
               e = e.replace(m[0], '');
               break;
@@ -3021,25 +3489,20 @@ Object.extend(Selector, {
     laterSibling: 'c = "laterSibling";'
   },
 
-  patterns: {
-    // combinators must be listed first
-    // (and descendant needs to be last combinator)
-    laterSibling: /^\s*~\s*/,
-    child:        /^\s*>\s*/,
-    adjacent:     /^\s*\+\s*/,
-    descendant:   /^\s/,
+  patterns: [
+    { name: 'laterSibling', re: /^\s*~\s*/ },
+    { name: 'child',        re: /^\s*>\s*/ },
+    { name: 'adjacent',     re: /^\s*\+\s*/ },
+    { name: 'descendant',   re: /^\s/ },
 
-    // selectors follow
-    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
-    id:           /^#([\w\-\*]+)(\b|$)/,
-    className:    /^\.([\w\-\*]+)(\b|$)/,
-    pseudo:
-/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
-    attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
-    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
-  },
+    { name: 'tagName',      re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
+    { name: 'id',           re: /^#([\w\-\*]+)(\b|$)/ },
+    { name: 'className',    re: /^\.([\w\-\*]+)(\b|$)/ },
+    { name: 'pseudo',       re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
+    { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
+    { name: 'attr',         re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
+  ],
 
-  // for Selector.match and Element#match
   assertions: {
     tagName: function(element, matches) {
       return matches[1].toUpperCase() == element.tagName.toUpperCase();
@@ -3064,15 +3527,12 @@ Object.extend(Selector, {
   },
 
   handlers: {
-    // UTILITY FUNCTIONS
-    // joins two collections
     concat: function(a, b) {
       for (var i = 0, node; node = b[i]; i++)
         a.push(node);
       return a;
     },
 
-    // marks an array of nodes for counting
     mark: function(nodes) {
       var _true = Prototype.emptyFunction;
       for (var i = 0, node; node = nodes[i]; i++)
@@ -3080,15 +3540,32 @@ Object.extend(Selector, {
       return nodes;
     },
 
-    unmark: function(nodes) {
-      for (var i = 0, node; node = nodes[i]; i++)
-        node._countedByPrototype = undefined;
-      return nodes;
-    },
+    unmark: (function(){
+
+      var PROPERTIES_ATTRIBUTES_MAP = (function(){
+        var el = document.createElement('div'),
+            isBuggy = false,
+            propName = '_countedByPrototype',
+            value = 'x'
+        el[propName] = value;
+        isBuggy = (el.getAttribute(propName) === value);
+        el = null;
+        return isBuggy;
+      })();
+
+      return PROPERTIES_ATTRIBUTES_MAP ?
+        function(nodes) {
+          for (var i = 0, node; node = nodes[i]; i++)
+            node.removeAttribute('_countedByPrototype');
+          return nodes;
+        } :
+        function(nodes) {
+          for (var i = 0, node; node = nodes[i]; i++)
+            node._countedByPrototype = void 0;
+          return nodes;
+        }
+    })(),
 
-    // mark each child node with its position (for nth calls)
-    // "ofType" flag indicates whether we're indexing for nth-of-type
-    // rather than nth-child
     index: function(parentNode, reverse, ofType) {
       parentNode._countedByPrototype = Prototype.emptyFunction;
       if (reverse) {
@@ -3102,19 +3579,17 @@ Object.extend(Selector, {
       }
     },
 
-    // filters out duplicates and extends all nodes
     unique: function(nodes) {
       if (nodes.length == 0) return nodes;
       var results = [], n;
       for (var i = 0, l = nodes.length; i < l; i++)
-        if (!(n = nodes[i])._countedByPrototype) {
+        if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
           n._countedByPrototype = Prototype.emptyFunction;
           results.push(Element.extend(n));
         }
       return Selector.handlers.unmark(results);
     },
 
-    // COMBINATOR FUNCTIONS
     descendant: function(nodes) {
       var h = Selector.handlers;
       for (var i = 0, results = [], node; node = nodes[i]; i++)
@@ -3158,13 +3633,11 @@ Object.extend(Selector, {
       return null;
     },
 
-    // TOKEN FUNCTIONS
     tagName: function(nodes, root, tagName, combinator) {
       var uTagName = tagName.toUpperCase();
       var results = [], h = Selector.handlers;
       if (nodes) {
         if (combinator) {
-          // fastlane for ordinary descendant combinators
           if (combinator == "descendant") {
             for (var i = 0, node; node = nodes[i]; i++)
               h.concat(results, node.getElementsByTagName(tagName));
@@ -3180,8 +3653,19 @@ Object.extend(Selector, {
 
     id: function(nodes, root, id, combinator) {
       var targetNode = $(id), h = Selector.handlers;
-      if (!targetNode) return [];
-      if (!nodes && root == document) return [targetNode];
+
+      if (root == document) {
+        if (!targetNode) return [];
+        if (!nodes) return [targetNode];
+      } else {
+        if (!root.sourceIndex || root.sourceIndex < 1) {
+          var nodes = root.getElementsByTagName('*');
+          for (var j = 0, node; node = nodes[j]; j++) {
+            if (node.id === id) return [node];
+          }
+        }
+      }
+
       if (nodes) {
         if (combinator) {
           if (combinator == 'child') {
@@ -3293,7 +3777,6 @@ Object.extend(Selector, {
       return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
     },
 
-    // handles the an+b logic
     getIndices: function(a, b, total) {
       if (a == 0) return b > 0 ? [b] : [];
       return $R(1, total).inject([], function(memo, i) {
@@ -3302,7 +3785,6 @@ Object.extend(Selector, {
       });
     },
 
-    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
     nth: function(nodes, formula, root, reverse, ofType) {
       if (nodes.length == 0) return [];
       if (formula == 'even') formula = '2n+0';
@@ -3336,7 +3818,6 @@ Object.extend(Selector, {
 
     'empty': function(nodes, value, root) {
       for (var i = 0, results = [], node; node = nodes[i]; i++) {
-        // IE treats comments as element nodes
         if (node.tagName == '!' || node.firstChild) continue;
         results.push(node);
       }
@@ -3379,8 +3860,6 @@ Object.extend(Selector, {
     '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
     '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
     '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
-    '$=': function(nv, v) { return nv.endsWith(v); },
-    '*=': function(nv, v) { return nv.include(v); },
     '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
     '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
      '-').include('-' + (v || "").toUpperCase() + '-'); }
@@ -3423,19 +3902,10 @@ Object.extend(Selector, {
 
 if (Prototype.Browser.IE) {
   Object.extend(Selector.handlers, {
-    // IE returns comment nodes on getElementsByTagName("*").
-    // Filter them out.
     concat: function(a, b) {
       for (var i = 0, node; node = b[i]; i++)
         if (node.tagName !== "!") a.push(node);
       return a;
-    },
-
-    // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
-    unmark: function(nodes) {
-      for (var i = 0, node; node = nodes[i]; i++)
-        node.removeAttribute('_countedByPrototype');
-      return nodes;
     }
   });
 }
@@ -3443,9 +3913,11 @@ if (Prototype.Browser.IE) {
 function $$() {
   return Selector.findChildElements(document, $A(arguments));
 }
+
 var Form = {
   reset: function(form) {
-    $(form).reset();
+    form = $(form);
+    form.reset();
     return form;
   },
 
@@ -3460,7 +3932,6 @@ var Form = {
         if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
             submit !== false && (!submit || key == submit) && (submitted = true)))) {
           if (key in result) {
-            // a key is already present; construct an array of values
             if (!Object.isArray(result[key])) result[key] = [result[key]];
             result[key].push(value);
           }
@@ -3480,13 +3951,18 @@ Form.Methods = {
   },
 
   getElements: function(form) {
-    return $A($(form).getElementsByTagName('*')).inject([],
-      function(elements, child) {
-        if (Form.Element.Serializers[child.tagName.toLowerCase()])
-          elements.push(Element.extend(child));
-        return elements;
-      }
-    );
+    var elements = $(form).getElementsByTagName('*'),
+        element,
+        arr = [ ],
+        serializers = Form.Element.Serializers;
+    for (var i = 0; element = elements[i]; i++) {
+      arr.push(element);
+    }
+    return arr.inject([], function(elements, child) {
+      if (serializers[child.tagName.toLowerCase()])
+        elements.push(Element.extend(child));
+      return elements;
+    })
   },
 
   getInputs: function(form, typeName, name) {
@@ -3526,7 +4002,7 @@ Form.Methods = {
     }).sortBy(function(element) { return element.tabIndex }).first();
 
     return firstByIndex ? firstByIndex : elements.find(function(element) {
-      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+      return /^(?:input|select|textarea)$/i.test(element.tagName);
     });
   },
 
@@ -3557,6 +4033,7 @@ Form.Methods = {
 
 /*--------------------------------------------------------------------------*/
 
+
 Form.Element = {
   focus: function(element) {
     $(element).focus();
@@ -3570,6 +4047,7 @@ Form.Element = {
 };
 
 Form.Element.Methods = {
+
   serialize: function(element) {
     element = $(element);
     if (!element.disabled && element.name) {
@@ -3610,7 +4088,7 @@ Form.Element.Methods = {
     try {
       element.focus();
       if (element.select && (element.tagName.toLowerCase() != 'input' ||
-          !['button', 'reset', 'submit'].include(element.type)))
+          !(/^(?:button|reset|submit)$/i.test(element.type))))
         element.select();
     } catch (e) { }
     return element;
@@ -3632,6 +4110,7 @@ Form.Element.Methods = {
 /*--------------------------------------------------------------------------*/
 
 var Field = Form.Element;
+
 var $F = Form.Element.Methods.getValue;
 
 /*--------------------------------------------------------------------------*/
@@ -3694,13 +4173,13 @@ Form.Element.Serializers = {
   },
 
   optionValue: function(opt) {
-    // extend element because hasAttribute may not be native
     return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
   }
 };
 
 /*--------------------------------------------------------------------------*/
 
+
 Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
   initialize: function($super, element, frequency, callback) {
     $super(callback, frequency);
@@ -3782,354 +4261,441 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
     return Form.serialize(this.element);
   }
 });
-if (!window.Event) var Event = { };
-
-Object.extend(Event, {
-  KEY_BACKSPACE: 8,
-  KEY_TAB:       9,
-  KEY_RETURN:   13,
-  KEY_ESC:      27,
-  KEY_LEFT:     37,
-  KEY_UP:       38,
-  KEY_RIGHT:    39,
-  KEY_DOWN:     40,
-  KEY_DELETE:   46,
-  KEY_HOME:     36,
-  KEY_END:      35,
-  KEY_PAGEUP:   33,
-  KEY_PAGEDOWN: 34,
-  KEY_INSERT:   45,
-
-  cache: { },
-
-  relatedTarget: function(event) {
-    var element;
-    switch(event.type) {
-      case 'mouseover': element = event.fromElement; break;
-      case 'mouseout':  element = event.toElement;   break;
-      default: return null;
-    }
-    return Element.extend(element);
-  }
-});
+(function() {
 
-Event.Methods = (function() {
-  var isButton;
+  var Event = {
+    KEY_BACKSPACE: 8,
+    KEY_TAB:       9,
+    KEY_RETURN:   13,
+    KEY_ESC:      27,
+    KEY_LEFT:     37,
+    KEY_UP:       38,
+    KEY_RIGHT:    39,
+    KEY_DOWN:     40,
+    KEY_DELETE:   46,
+    KEY_HOME:     36,
+    KEY_END:      35,
+    KEY_PAGEUP:   33,
+    KEY_PAGEDOWN: 34,
+    KEY_INSERT:   45,
+
+    cache: {}
+  };
+
+  var docEl = document.documentElement;
+  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
+    && 'onmouseleave' in docEl;
 
+  var _isButton;
   if (Prototype.Browser.IE) {
     var buttonMap = { 0: 1, 1: 4, 2: 2 };
-    isButton = function(event, code) {
-      return event.button == buttonMap[code];
+    _isButton = function(event, code) {
+      return event.button === buttonMap[code];
     };
-
   } else if (Prototype.Browser.WebKit) {
-    isButton = function(event, code) {
+    _isButton = function(event, code) {
       switch (code) {
         case 0: return event.which == 1 && !event.metaKey;
         case 1: return event.which == 1 && event.metaKey;
         default: return false;
       }
     };
-
   } else {
-    isButton = function(event, code) {
+    _isButton = function(event, code) {
       return event.which ? (event.which === code + 1) : (event.button === code);
     };
   }
 
-  return {
-    isLeftClick:   function(event) { return isButton(event, 0) },
-    isMiddleClick: function(event) { return isButton(event, 1) },
-    isRightClick:  function(event) { return isButton(event, 2) },
-
-    element: function(event) {
-      event = Event.extend(event);
-
-      var node          = event.target,
-          type          = event.type,
-          currentTarget = event.currentTarget;
-
-      if (currentTarget && currentTarget.tagName) {
-        // Firefox screws up the "click" event when moving between radio buttons
-        // via arrow keys. It also screws up the "load" and "error" events on images,
-        // reporting the document as the target instead of the original image.
-        if (type === 'load' || type === 'error' ||
-          (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
-            && currentTarget.type === 'radio'))
-              node = currentTarget;
-      }
-      if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
-      return Element.extend(node);
-    },
+  function isLeftClick(event)   { return _isButton(event, 0) }
 
-    findElement: function(event, expression) {
-      var element = Event.element(event);
-      if (!expression) return element;
-      var elements = [element].concat(element.ancestors());
-      return Selector.findElement(elements, expression, 0);
-    },
+  function isMiddleClick(event) { return _isButton(event, 1) }
 
-    pointer: function(event) {
-      var docElement = document.documentElement,
-      body = document.body || { scrollLeft: 0, scrollTop: 0 };
-      return {
-        x: event.pageX || (event.clientX +
-          (docElement.scrollLeft || body.scrollLeft) -
-          (docElement.clientLeft || 0)),
-        y: event.pageY || (event.clientY +
-          (docElement.scrollTop || body.scrollTop) -
-          (docElement.clientTop || 0))
-      };
-    },
+  function isRightClick(event)  { return _isButton(event, 2) }
+
+  function element(event) {
+    event = Event.extend(event);
 
-    pointerX: function(event) { return Event.pointer(event).x },
-    pointerY: function(event) { return Event.pointer(event).y },
+    var node = event.target, type = event.type,
+     currentTarget = event.currentTarget;
 
-    stop: function(event) {
-      Event.extend(event);
-      event.preventDefault();
-      event.stopPropagation();
-      event.stopped = true;
+    if (currentTarget && currentTarget.tagName) {
+      if (type === 'load' || type === 'error' ||
+        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
+          && currentTarget.type === 'radio'))
+            node = currentTarget;
     }
+
+    if (node.nodeType == Node.TEXT_NODE)
+      node = node.parentNode;
+
+    return Element.extend(node);
+  }
+
+  function findElement(event, expression) {
+    var element = Event.element(event);
+    if (!expression) return element;
+    var elements = [element].concat(element.ancestors());
+    return Selector.findElement(elements, expression, 0);
+  }
+
+  function pointer(event) {
+    return { x: pointerX(event), y: pointerY(event) };
+  }
+
+  function pointerX(event) {
+    var docElement = document.documentElement,
+     body = document.body || { scrollLeft: 0 };
+
+    return event.pageX || (event.clientX +
+      (docElement.scrollLeft || body.scrollLeft) -
+      (docElement.clientLeft || 0));
+  }
+
+  function pointerY(event) {
+    var docElement = document.documentElement,
+     body = document.body || { scrollTop: 0 };
+
+    return  event.pageY || (event.clientY +
+       (docElement.scrollTop || body.scrollTop) -
+       (docElement.clientTop || 0));
+  }
+
+
+  function stop(event) {
+    Event.extend(event);
+    event.preventDefault();
+    event.stopPropagation();
+
+    event.stopped = true;
+  }
+
+  Event.Methods = {
+    isLeftClick: isLeftClick,
+    isMiddleClick: isMiddleClick,
+    isRightClick: isRightClick,
+
+    element: element,
+    findElement: findElement,
+
+    pointer: pointer,
+    pointerX: pointerX,
+    pointerY: pointerY,
+
+    stop: stop
   };
-})();
 
-Event.extend = (function() {
+
   var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
     m[name] = Event.Methods[name].methodize();
     return m;
   });
 
   if (Prototype.Browser.IE) {
+    function _relatedTarget(event) {
+      var element;
+      switch (event.type) {
+        case 'mouseover': element = event.fromElement; break;
+        case 'mouseout':  element = event.toElement;   break;
+        default: return null;
+      }
+      return Element.extend(element);
+    }
+
     Object.extend(methods, {
       stopPropagation: function() { this.cancelBubble = true },
       preventDefault:  function() { this.returnValue = false },
-      inspect: function() { return "[object Event]" }
+      inspect: function() { return '[object Event]' }
     });
 
-    return function(event) {
+    Event.extend = function(event, element) {
       if (!event) return false;
       if (event._extendedByPrototype) return event;
 
       event._extendedByPrototype = Prototype.emptyFunction;
       var pointer = Event.pointer(event);
+
       Object.extend(event, {
-        target: event.srcElement,
-        relatedTarget: Event.relatedTarget(event),
+        target: event.srcElement || element,
+        relatedTarget: _relatedTarget(event),
         pageX:  pointer.x,
         pageY:  pointer.y
       });
+
       return Object.extend(event, methods);
     };
-
   } else {
-    Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
+    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
     Object.extend(Event.prototype, methods);
-    return Prototype.K;
+    Event.extend = Prototype.K;
   }
-})();
 
-Object.extend(Event, (function() {
-  var cache = Event.cache;
+  function _createResponder(element, eventName, handler) {
+    var registry = Element.retrieve(element, 'prototype_event_registry');
 
-  function getEventID(element) {
-    if (element._prototypeEventID) return element._prototypeEventID[0];
-    arguments.callee.id = arguments.callee.id || 1;
-    return element._prototypeEventID = [++arguments.callee.id];
-  }
-
-  function getDOMEventName(eventName) {
-    if (eventName && eventName.include(':')) return "dataavailable";
-    return eventName;
-  }
+    if (Object.isUndefined(registry)) {
+      CACHE.push(element);
+      registry = Element.retrieve(element, 'prototype_event_registry', $H());
+    }
 
-  function getCacheForID(id) {
-    return cache[id] = cache[id] || { };
-  }
+    var respondersForEvent = registry.get(eventName);
+    if (Object.isUndefined(respondersForEvent)) {
+      respondersForEvent = [];
+      registry.set(eventName, respondersForEvent);
+    }
 
-  function getWrappersForEventName(id, eventName) {
-    var c = getCacheForID(id);
-    return c[eventName] = c[eventName] || [];
-  }
+    if (respondersForEvent.pluck('handler').include(handler)) return false;
 
-  function createWrapper(element, eventName, handler) {
-    var id = getEventID(element);
-    var c = getWrappersForEventName(id, eventName);
-    if (c.pluck("handler").include(handler)) return false;
+    var responder;
+    if (eventName.include(":")) {
+      responder = function(event) {
+        if (Object.isUndefined(event.eventName))
+          return false;
 
-    var wrapper = function(event) {
-      if (!Event || !Event.extend ||
-        (event.eventName && event.eventName != eventName))
+        if (event.eventName !== eventName)
           return false;
 
-      Event.extend(event);
-      handler.call(element, event);
-    };
+        Event.extend(event, element);
+        handler.call(element, event);
+      };
+    } else {
+      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
+       (eventName === "mouseenter" || eventName === "mouseleave")) {
+        if (eventName === "mouseenter" || eventName === "mouseleave") {
+          responder = function(event) {
+            Event.extend(event, element);
+
+            var parent = event.relatedTarget;
+            while (parent && parent !== element) {
+              try { parent = parent.parentNode; }
+              catch(e) { parent = element; }
+            }
 
-    wrapper.handler = handler;
-    c.push(wrapper);
-    return wrapper;
-  }
+            if (parent === element) return;
 
-  function findWrapper(id, eventName, handler) {
-    var c = getWrappersForEventName(id, eventName);
-    return c.find(function(wrapper) { return wrapper.handler == handler });
-  }
+            handler.call(element, event);
+          };
+        }
+      } else {
+        responder = function(event) {
+          Event.extend(event, element);
+          handler.call(element, event);
+        };
+      }
+    }
 
-  function destroyWrapper(id, eventName, handler) {
-    var c = getCacheForID(id);
-    if (!c[eventName]) return false;
-    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+    responder.handler = handler;
+    respondersForEvent.push(responder);
+    return responder;
   }
 
-  function destroyCache() {
-    for (var id in cache)
-      for (var eventName in cache[id])
-        cache[id][eventName] = null;
+  function _destroyCache() {
+    for (var i = 0, length = CACHE.length; i < length; i++) {
+      Event.stopObserving(CACHE[i]);
+      CACHE[i] = null;
+    }
   }
 
+  var CACHE = [];
 
-  // Internet Explorer needs to remove event handlers on page unload
-  // in order to avoid memory leaks.
-  if (window.attachEvent) {
-    window.attachEvent("onunload", destroyCache);
-  }
+  if (Prototype.Browser.IE)
+    window.attachEvent('onunload', _destroyCache);
 
-  // Safari has a dummy event handler on page unload so that it won't
-  // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
-  // object when page is returned to via the back button using its bfcache.
-  if (Prototype.Browser.WebKit) {
+  if (Prototype.Browser.WebKit)
     window.addEventListener('unload', Prototype.emptyFunction, false);
+
+
+  var _getDOMEventName = Prototype.K;
+
+  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
+    _getDOMEventName = function(eventName) {
+      var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
+      return eventName in translations ? translations[eventName] : eventName;
+    };
   }
 
-  return {
-    observe: function(element, eventName, handler) {
-      element = $(element);
-      var name = getDOMEventName(eventName);
+  function observe(element, eventName, handler) {
+    element = $(element);
 
-      var wrapper = createWrapper(element, eventName, handler);
-      if (!wrapper) return element;
+    var responder = _createResponder(element, eventName, handler);
 
-      if (element.addEventListener) {
-        element.addEventListener(name, wrapper, false);
-      } else {
-        element.attachEvent("on" + name, wrapper);
+    if (!responder) return element;
+
+    if (eventName.include(':')) {
+      if (element.addEventListener)
+        element.addEventListener("dataavailable", responder, false);
+      else {
+        element.attachEvent("ondataavailable", responder);
+        element.attachEvent("onfilterchange", responder);
       }
+    } else {
+      var actualEventName = _getDOMEventName(eventName);
 
-      return element;
-    },
+      if (element.addEventListener)
+        element.addEventListener(actualEventName, responder, false);
+      else
+        element.attachEvent("on" + actualEventName, responder);
+    }
 
-    stopObserving: function(element, eventName, handler) {
-      element = $(element);
-      var id = getEventID(element), name = getDOMEventName(eventName);
+    return element;
+  }
 
-      if (!handler && eventName) {
-        getWrappersForEventName(id, eventName).each(function(wrapper) {
-          element.stopObserving(eventName, wrapper.handler);
-        });
-        return element;
+  function stopObserving(element, eventName, handler) {
+    element = $(element);
 
-      } else if (!eventName) {
-        Object.keys(getCacheForID(id)).each(function(eventName) {
-          element.stopObserving(eventName);
-        });
-        return element;
-      }
+    var registry = Element.retrieve(element, 'prototype_event_registry');
 
-      var wrapper = findWrapper(id, eventName, handler);
-      if (!wrapper) return element;
+    if (Object.isUndefined(registry)) return element;
 
-      if (element.removeEventListener) {
-        element.removeEventListener(name, wrapper, false);
-      } else {
-        element.detachEvent("on" + name, wrapper);
-      }
+    if (eventName && !handler) {
+      var responders = registry.get(eventName);
 
-      destroyWrapper(id, eventName, handler);
+      if (Object.isUndefined(responders)) return element;
 
+      responders.each( function(r) {
+        Element.stopObserving(element, eventName, r.handler);
+      });
       return element;
-    },
+    } else if (!eventName) {
+      registry.each( function(pair) {
+        var eventName = pair.key, responders = pair.value;
 
-    fire: function(element, eventName, memo) {
-      element = $(element);
-      if (element == document && document.createEvent && !element.dispatchEvent)
-        element = document.documentElement;
+        responders.each( function(r) {
+          Element.stopObserving(element, eventName, r.handler);
+        });
+      });
+      return element;
+    }
 
-      var event;
-      if (document.createEvent) {
-        event = document.createEvent("HTMLEvents");
-        event.initEvent("dataavailable", true, true);
-      } else {
-        event = document.createEventObject();
-        event.eventType = "ondataavailable";
-      }
+    var responders = registry.get(eventName);
 
-      event.eventName = eventName;
-      event.memo = memo || { };
+    if (!responders) return;
 
-      if (document.createEvent) {
-        element.dispatchEvent(event);
-      } else {
-        element.fireEvent(event.eventType, event);
+    var responder = responders.find( function(r) { return r.handler === handler; });
+    if (!responder) return element;
+
+    var actualEventName = _getDOMEventName(eventName);
+
+    if (eventName.include(':')) {
+      if (element.removeEventListener)
+        element.removeEventListener("dataavailable", responder, false);
+      else {
+        element.detachEvent("ondataavailable", responder);
+        element.detachEvent("onfilterchange",  responder);
       }
+    } else {
+      if (element.removeEventListener)
+        element.removeEventListener(actualEventName, responder, false);
+      else
+        element.detachEvent('on' + actualEventName, responder);
+    }
+
+    registry.set(eventName, responders.without(responder));
+
+    return element;
+  }
+
+  function fire(element, eventName, memo, bubble) {
+    element = $(element);
+
+    if (Object.isUndefined(bubble))
+      bubble = true;
+
+    if (element == document && document.createEvent && !element.dispatchEvent)
+      element = document.documentElement;
 
-      return Event.extend(event);
+    var event;
+    if (document.createEvent) {
+      event = document.createEvent('HTMLEvents');
+      event.initEvent('dataavailable', true, true);
+    } else {
+      event = document.createEventObject();
+      event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
     }
-  };
-})());
 
-Object.extend(Event, Event.Methods);
+    event.eventName = eventName;
+    event.memo = memo || { };
 
-Element.addMethods({
-  fire:          Event.fire,
-  observe:       Event.observe,
-  stopObserving: Event.stopObserving
-});
+    if (document.createEvent)
+      element.dispatchEvent(event);
+    else
+      element.fireEvent(event.eventType, event);
 
-Object.extend(document, {
-  fire:          Element.Methods.fire.methodize(),
-  observe:       Element.Methods.observe.methodize(),
-  stopObserving: Element.Methods.stopObserving.methodize(),
-  loaded:        false
-});
+    return Event.extend(event);
+  }
+
+
+  Object.extend(Event, Event.Methods);
+
+  Object.extend(Event, {
+    fire:          fire,
+    observe:       observe,
+    stopObserving: stopObserving
+  });
+
+  Element.addMethods({
+    fire:          fire,
+
+    observe:       observe,
+
+    stopObserving: stopObserving
+  });
+
+  Object.extend(document, {
+    fire:          fire.methodize(),
+
+    observe:       observe.methodize(),
+
+    stopObserving: stopObserving.methodize(),
+
+    loaded:        false
+  });
+
+  if (window.Event) Object.extend(window.Event, Event);
+  else window.Event = Event;
+})();
 
 (function() {
   /* Support for the DOMContentLoaded event is based on work by Dan Webb,
-     Matthias Miller, Dean Edwards and John Resig. */
+     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
 
   var timer;
 
   function fireContentLoadedEvent() {
     if (document.loaded) return;
-    if (timer) window.clearInterval(timer);
-    document.fire("dom:loaded");
+    if (timer) window.clearTimeout(timer);
     document.loaded = true;
+    document.fire('dom:loaded');
   }
 
-  if (document.addEventListener) {
-    if (Prototype.Browser.WebKit) {
-      timer = window.setInterval(function() {
-        if (/loaded|complete/.test(document.readyState))
-          fireContentLoadedEvent();
-      }, 0);
-
-      Event.observe(window, "load", fireContentLoadedEvent);
+  function checkReadyState() {
+    if (document.readyState === 'complete') {
+      document.stopObserving('readystatechange', checkReadyState);
+      fireContentLoadedEvent();
+    }
+  }
 
-    } else {
-      document.addEventListener("DOMContentLoaded",
-        fireContentLoadedEvent, false);
+  function pollDoScroll() {
+    try { document.documentElement.doScroll('left'); }
+    catch(e) {
+      timer = pollDoScroll.defer();
+      return;
     }
+    fireContentLoadedEvent();
+  }
 
+  if (document.addEventListener) {
+    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
   } else {
-    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
-    $("__onDOMContentLoaded").onreadystatechange = function() {
-      if (this.readyState == "complete") {
-        this.onreadystatechange = null;
-        fireContentLoadedEvent();
-      }
-    };
+    document.observe('readystatechange', checkReadyState);
+    if (window == top)
+      timer = pollDoScroll.defer();
   }
+
+  Event.observe(window, 'load', fireContentLoadedEvent);
 })();
+
+Element.addMethods();
+
 /*------------------------------- DEPRECATED -------------------------------*/
 
 Hash.toQueryString = Object.toQueryString;
@@ -4158,16 +4724,9 @@ var Insertion = {
 
 var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
 
-// This should be moved to script.aculo.us; notice the deprecated methods
-// further below, that map to the newer Element methods.
 var Position = {
-  // set to true if needed, warning: firefox performance problems
-  // NOT neeeded for page scrolling, only if draggable contained in
-  // scrollable elements
   includeScrollOffsets: false,
 
-  // must be called before calling withinIncludingScrolloffset, every time the
-  // page is scrolled
   prepare: function() {
     this.deltaX =  window.pageXOffset
                 || document.documentElement.scrollLeft
@@ -4179,7 +4738,6 @@ var Position = {
                 || 0;
   },
 
-  // caches x/y coordinate pair to use with overlap
   within: function(element, x, y) {
     if (this.includeScrollOffsets)
       return this.withinIncludingScrolloffsets(element, x, y);
@@ -4206,7 +4764,6 @@ var Position = {
             this.xcomp <  this.offset[0] + element.offsetWidth);
   },
 
-  // within must be called directly before
   overlap: function(mode, element) {
     if (!mode) return 0;
     if (mode == 'vertical')
@@ -4217,7 +4774,6 @@ var Position = {
         element.offsetWidth;
   },
 
-  // Deprecation layer -- use newer Element methods now (1.5.2).
 
   cumulativeOffset: Element.Methods.cumulativeOffset,
 
@@ -4316,5 +4872,3 @@ Element.ClassNames.prototype = {
 Object.extend(Element.ClassNames.prototype, Enumerable);
 
 /*--------------------------------------------------------------------------*/
-
-Element.addMethods();
\ No newline at end of file
diff --git a/js/src/scriptaculous.js b/js/src/scriptaculous.js
index c976e6b..de4289e 100644
--- a/js/src/scriptaculous.js
+++ b/js/src/scriptaculous.js
@@ -1,6 +1,6 @@
 // script.aculo.us scriptaculous.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
 
-// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Copyright 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
 // 
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
diff --git a/lib/Block/tree_menu.php b/lib/Block/tree_menu.php
index 10c52dc..f40e6c1 100644
--- a/lib/Block/tree_menu.php
+++ b/lib/Block/tree_menu.php
@@ -4,7 +4,7 @@ $block_name = _("Menu List");
 $block_type = 'tree';
 
 /**
- * $Horde: turba/lib/Block/tree_menu.php,v 1.5.2.5 2008/08/11 08:29:21 jan Exp $
+ * $Horde: turba/lib/Block/tree_menu.php,v 1.5.2.6 2009/06/04 19:00:36 mrubinsk Exp $
  *
  * @package Horde_Block
  */
@@ -22,7 +22,7 @@ class Horde_Block_turba_tree_menu extends Horde_Block {
         $add = Horde::applicationUrl('add.php');
         $icondir = $registry->getImageDir() . '/menu';
 
-        if ($addSources) {
+        if ($GLOBALS['addSources']) {
             $tree->addNode($parent . '__new',
                            $parent,
                            _("New Contact"),
@@ -32,7 +32,7 @@ class Horde_Block_turba_tree_menu extends Horde_Block {
                                  'icondir' => $icondir,
                                  'url' => $add));
 
-            foreach ($addSources as $addressbook => $config) {
+            foreach ($GLOBALS['addSources'] as $addressbook => $config) {
                 $tree->addNode($parent . $addressbook . '__new',
                                $parent . '__new',
                                sprintf(_("in %s"), $config['title']),
diff --git a/lib/Data/ldif.php b/lib/Data/ldif.php
index 2488e50..c306706 100644
--- a/lib/Data/ldif.php
+++ b/lib/Data/ldif.php
@@ -2,9 +2,9 @@
 /**
  * Horde_Data implementation for LDAP Data Interchange Format (LDIF).
  *
- * $Horde: turba/lib/Data/ldif.php,v 1.2.2.3 2008/03/23 07:59:59 selsky Exp $
+ * $Horde: turba/lib/Data/ldif.php,v 1.2.2.4 2009/01/06 15:27:49 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/lib/Driver.php b/lib/Driver.php
index a138d71..7847533 100644
--- a/lib/Driver.php
+++ b/lib/Driver.php
@@ -4,7 +4,7 @@
  * various directory search drivers.  It includes functions for searching,
  * adding, removing, and modifying directory entries.
  *
- * $Horde: turba/lib/Driver.php,v 1.57.2.83 2008/10/28 23:40:38 jan Exp $
+ * $Horde: turba/lib/Driver.php,v 1.57.2.88 2009/07/14 16:21:21 mrubinsk Exp $
  *
  * @author  Chuck Hagenbuch <chuck at horde.org>
  * @author  Jon Parise <jon at csh.rit.edu>
@@ -234,11 +234,15 @@ class Turba_Driver {
                         $count = 0;
                         $tmp_fields = array();
                         foreach ($parse['fields'] as $mapfield) {
+                            if (isset($hash[$mapfield])) {
+                                // If the compositing fields are set
+                                // individually, then don't set them at all.
+                                break 2;
+                            }
                             $tmp_fields[$this->map[$mapfield]] = $splitval[$count++];
                         }
                         // Exit if we found the best match.
                         if ($splitval[$count - 1] !== null) {
-                            $fields = array_merge($fields, $tmp_fields);
                             break;
                         }
                     }
@@ -338,6 +342,14 @@ class Turba_Driver {
                                         'approximate' => !empty($this->approximate[$field]),
                                     );
                                 }
+                                $atomsearch[] = array(
+                                    'field' => $field,
+                                    'op' => '=',
+                                    'test' => '',
+                                    'begin' => $match_begin,
+                                    'approximate' => !empty($this->approximate[$field])
+                                );
+
                                 $subsearch[] = array('OR' => $atomsearch);
                                 unset($atomsearch);
                                 $glue = 'AND';
@@ -381,7 +393,7 @@ class Turba_Driver {
         }
 
         if (count($strict_search) && count($search)) {
-            return array('AND' => array($strict_search,
+            return array('AND' => array($search_type => $strict_search,
                                         array($search_type => $search)));
         } elseif (count($strict_search)) {
             return array('AND' => $strict_search);
@@ -809,6 +821,14 @@ class Turba_Driver {
         if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
+    
+        $own_contact = $GLOBALS['prefs']->getValue('own_contact');
+        if (!empty($own_contact)) {
+            @list($source, $id) = explode(';', $own_contact);
+            if ($id == $object_id) {
+                $GLOBALS['prefs']->setValue('own_contact', '');
+            }
+        }
 
         /* Log the deletion of this item in the history log. */
         if ($object->getValue('__uid')) {
@@ -2147,6 +2167,15 @@ class Turba_Driver {
 
     function checkDefaultShare(&$share, $srcconfig)
     {
+    /**
+     * Check if the passed in share is the default share for this source.
+     *
+     * @param Horde_Share $share  The share object e
+     * @param array $srcconfig    The cfgSource entry for the share (not used in
+     *                            this method, but a child class may need it).
+     *
+     * @return boolean
+     */
         $params = @unserialize($share->get('params'));
         if (!isset($params['default'])) {
             $params['default'] = ($params['name'] == Auth::getAuth());
diff --git a/lib/Driver/imsp.php b/lib/Driver/imsp.php
index 407eac6..6f05203 100644
--- a/lib/Driver/imsp.php
+++ b/lib/Driver/imsp.php
@@ -5,7 +5,7 @@ require_once 'Horde/Cache.php';
 /**
  * Turba directory driver implementation for an IMSP server.
  *
- * $Horde: turba/lib/Driver/imsp.php,v 1.21.4.21 2008/04/09 20:30:53 mrubinsk Exp $
+ * $Horde: turba/lib/Driver/imsp.php,v 1.21.4.22 2009/06/04 19:00:36 mrubinsk Exp $
  *
  * @author  Michael Rubinsky <mrubinsk at horde.org>
  * @package Turba
@@ -677,6 +677,11 @@ class Turba_Driver_imsp extends Turba_Driver {
        return $this->params['name'];
     }
 
+    /**
+     * Check if the passed in share is the default share for this source.
+     *
+     * @see turba/lib/Turba_Driver#checkDefaultShare($share, $srcconfig)
+     */
     function checkDefaultShare(&$share, $srcConfig)
     {
         $params = @unserialize($share->get('params'));
diff --git a/lib/Driver/kolab.php b/lib/Driver/kolab.php
index 166c0a6..b3dece6 100644
--- a/lib/Driver/kolab.php
+++ b/lib/Driver/kolab.php
@@ -2,7 +2,7 @@
 /**
  * @package Turba
  *
- * $Horde: turba/lib/Driver/kolab.php,v 1.5.10.23 2008/11/07 13:15:23 wrobel Exp $
+ * $Horde: turba/lib/Driver/kolab.php,v 1.5.10.25 2009/03/19 10:17:01 jan Exp $
  */
 
 /** Kolab support class. */
@@ -10,7 +10,7 @@ require_once 'Horde/Kolab.php';
 
 /**
  * Horde Turba driver for the Kolab IMAP Server.
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
@@ -184,9 +184,9 @@ class Turba_Driver_kolab extends Turba_Driver {
 /**
  * Horde Turba wrapper to distinguish between both Kolab driver implementations.
  *
- * $Horde: turba/lib/Driver/kolab.php,v 1.5.10.23 2008/11/07 13:15:23 wrobel Exp $
+ * $Horde: turba/lib/Driver/kolab.php,v 1.5.10.25 2009/03/19 10:17:01 jan Exp $
  *
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL). If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
@@ -260,7 +260,7 @@ class Turba_Driver_kolab_wrapper {
 
 /**
  * Horde Turba driver for the Kolab IMAP Server.
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
@@ -702,7 +702,7 @@ class Turba_Driver_kolab_wrapper_old extends Turba_Driver_kolab_wrapper {
 
 /**
  * New Horde Turba driver for the Kolab IMAP Server.
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
@@ -1116,7 +1116,7 @@ class Turba_Driver_kolab_wrapper_new extends Turba_Driver_kolab_wrapper {
         }
 
         if ($object_key != 'uid') {
-            return PEAR::raiseError(sprintf(_("Key for saving must be \'uid\' not %s!"), $object_key));
+            return PEAR::raiseError(sprintf('Key for saving must be \'uid\' not %s!', $object_key));
         }
 
         return $this->_store($attributes, $object_id);
@@ -1200,7 +1200,7 @@ class Turba_Driver_kolab_wrapper_new extends Turba_Driver_kolab_wrapper {
         }
 
         if ($object_key != 'uid') {
-            return PEAR::raiseError(sprintf(_("Key for saving must be a UID not %s!"), $object_key));
+            return PEAR::raiseError(sprintf('Key for saving must be a UID not %s!', $object_key));
         }
 
         if (!in_array($object_id, array_keys($this->_contacts_cache))) {
diff --git a/lib/Driver/ldap.php b/lib/Driver/ldap.php
index 34edccb..a4ae020 100644
--- a/lib/Driver/ldap.php
+++ b/lib/Driver/ldap.php
@@ -2,7 +2,7 @@
 /**
  * Turba directory driver implementation for PHP's LDAP extension.
  *
- * $Horde: turba/lib/Driver/ldap.php,v 1.54.4.20 2008/06/09 03:28:07 chuck Exp $
+ * $Horde: turba/lib/Driver/ldap.php,v 1.54.4.22 2009/08/18 17:00:06 jan Exp $
  *
  * @author  Chuck Hagenbuch <chuck at horde.org>
  * @author  Jon Parise <jon at csh.rit.edu>
@@ -78,6 +78,11 @@ class Turba_Driver_ldap extends Turba_Driver {
             @ldap_set_option($this->_ds, LDAP_OPT_DEREF, $this->_params['deref']);
         }
 
+        /* Set the LDAP referrals. */
+        if (!empty($this->_params['referrals'])) {
+            @ldap_set_option($this->_ds, LDAP_OPT_REFERRALS, $this->_params['referrals']);
+        }
+
         /* Start TLS if we're using it. */
         if (!empty($this->_params['tls'])) {
             if (!@ldap_start_tls($this->_ds)) {
@@ -540,8 +545,11 @@ class Turba_Driver_ldap extends Turba_Driver {
     function _emptyAttributeFilter($var)
     {
         if (!is_array($var)) {
-            return ($var != '');
+            return $var != '';
         } else {
+            if (!count($var)) {
+                return false;
+            }
             foreach ($var as $v) {
                 if ($v == '') {
                     return false;
diff --git a/lib/Driver/sql.php b/lib/Driver/sql.php
index 5bb64b3..da93d91 100644
--- a/lib/Driver/sql.php
+++ b/lib/Driver/sql.php
@@ -3,7 +3,7 @@
  * Turba directory driver implementation for PHP's PEAR database abstraction
  * layer.
  *
- * $Horde: turba/lib/Driver/sql.php,v 1.59.10.29 2008/08/12 09:24:50 jan Exp $
+ * $Horde: turba/lib/Driver/sql.php,v 1.59.10.31 2009/07/10 00:37:32 mrubinsk Exp $
  *
  * @author  Jon Parise <jon at csh.rit.edu>
  * @package Turba
@@ -39,7 +39,8 @@ class Turba_Driver_sql extends Turba_Driver {
     {
         include_once 'DB.php';
         $this->_write_db = &DB::connect($this->_params,
-                                        array('persistent' => !empty($this->_params['persistent'])));
+                                        array('persistent' => !empty($this->_params['persistent']),
+                                              'ssl' => !empty($this->_params['ssl'])));
         if (is_a($this->_write_db, 'PEAR_Error')) {
             return $this->_write_db;
         }
@@ -62,7 +63,8 @@ class Turba_Driver_sql extends Turba_Driver {
         if (!empty($this->_params['splitread'])) {
             $params = array_merge($this->_params, $this->_params['read']);
             $this->_db = &DB::connect($params,
-                                      array('persistent' => !empty($params['persistent'])));
+                                      array('persistent' => !empty($params['persistent']),
+                                            'ssl' => !empty($params['ssl'])));
             if (is_a($this->_db, 'PEAR_Error')) {
                 return $this->_db;
             }
@@ -461,12 +463,16 @@ class Turba_Driver_sql extends Turba_Driver {
                                 $clause .= ' ' . $key . ' ';
                             }
                             $rhs = $this->_convertToDriver($test['test']);
-                            $binds = Horde_SQL::buildClause($this->_db, $test['field'], $test['op'], $rhs, true, array('begin' => !empty($test['begin'])));
-                            if (is_array($binds)) {
-                                $clause .= $binds[0];
-                                $values = array_merge($values, $binds[1]);
+                            if ($rhs == '' && $test['op'] == '=') {
+                                $clause .= '(' . Horde_SQL::buildClause($this->_db, $test['field'], '=', $rhs) . ' OR ' . $test['field'] . ' IS NULL)';
                             } else {
-                                $clause .= $binds;
+                                $binds = Horde_SQL::buildClause($this->_db, $test['field'], $test['op'], $rhs, true, array('begin' => !empty($test['begin'])));
+                                if (is_array($binds)) {
+                                    $clause .= $binds[0];
+                                    $values = array_merge($values, $binds[1]);
+                                } else {
+                                    $clause .= $binds;
+                                }
                             }
                         }
                     }
diff --git a/lib/Driver/vbook.php b/lib/Driver/vbook.php
index 6abacef..3f516d7 100644
--- a/lib/Driver/vbook.php
+++ b/lib/Driver/vbook.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * $Horde: turba/lib/Driver/vbook.php,v 1.8.2.4 2008/02/15 16:44:06 chuck Exp $
+ * $Horde: turba/lib/Driver/vbook.php,v 1.8.2.5 2009/01/06 15:27:50 jan Exp $
  *
  * @package Horde
  */
@@ -8,7 +8,7 @@
 /**
  * Turba directory driver implementation for virtual address books.
  *
- * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2005-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/lib/Forms/Contact.php b/lib/Forms/Contact.php
index 292507d..d5a71cb 100644
--- a/lib/Forms/Contact.php
+++ b/lib/Forms/Contact.php
@@ -2,7 +2,7 @@
 /**
  * @package Turba
  *
- * $Horde: turba/lib/Forms/Contact.php,v 1.3.2.3 2008/04/23 21:27:46 chuck Exp $
+ * $Horde: turba/lib/Forms/Contact.php,v 1.3.2.4 2008/12/29 07:58:45 wrobel Exp $
  */
 
 /** Horde_Form */
@@ -18,7 +18,7 @@ class Turba_ContactForm extends Horde_Form {
 
     function Turba_ContactForm(&$vars, &$contact)
     {
-        global $conf;
+        global $conf, $notification;
 
         parent::Horde_Form($vars, '', 'Turba_View_Contact');
 
diff --git a/lib/ListView.php b/lib/ListView.php
index 38c62d4..4f11e91 100644
--- a/lib/ListView.php
+++ b/lib/ListView.php
@@ -3,7 +3,7 @@
  * The Turba_ListView:: class provides an interface for objects that
  * visualize Turba_lists.
  *
- * $Horde: turba/lib/ListView.php,v 1.17.10.21 2008/07/20 08:01:45 jan Exp $
+ * $Horde: turba/lib/ListView.php,v 1.17.10.23 2009/01/19 15:07:25 mrubinsk Exp $
  *
  * @author  Chuck Hagenbuch <chuck at horde.org>
  * @author  Jon Parise <jon at csh.rit.edu>
@@ -179,10 +179,10 @@ class Turba_ListView {
         }
         list($addToList, $addToListSources) = $this->getAddSources();
 
-        $viewurl = Util::addParameter(
+        $viewurl = urldecode(Util::addParameter(
             'browse.php',
             array('key' => Util::getFormData('key'),
-                  'url' => Horde::selfUrl(true, false, true)));
+                  'url' => Horde::selfUrl(true, false, true))));
 
         if ($this->type == 'search') {
             $page = Util::getFormData('page', 0);
@@ -219,7 +219,7 @@ class Turba_ListView {
                 'val' => Util::getFormData('val'),
                 'source' => Util::getFormData('source', $default_source)
             ));
-            $viewurl = Util::addParameter('search.php', $params);
+            $viewurl = urldecode(Util::addParameter('search.php', $params));
 
             require_once 'Horde/UI/Pager.php';
             $vars = Variables::getDefaultVariables();
diff --git a/lib/Object.php b/lib/Object.php
index 57f21f3..38afa64 100644
--- a/lib/Object.php
+++ b/lib/Object.php
@@ -3,7 +3,7 @@
  * The Turba_Object:: class provides a base implementation for Turba
  * objects - people, groups, restaurants, etc.
  *
- * $Horde: turba/lib/Object.php,v 1.17.10.10 2008/11/07 13:20:23 wrobel Exp $
+ * $Horde: turba/lib/Object.php,v 1.17.10.12 2009/01/23 14:48:39 jan Exp $
  *
  * @author  Chuck Hagenbuch <chuck at horde.org>
  * @author  Jon Parise <jon at csh.rit.edu>
@@ -80,7 +80,8 @@ class Turba_Object {
      *
      * @param string $attribute  The attribute to retrieve.
      *
-     * @return string  The value of $attribute, or the empty string.
+     * @return mixed  The value of $attribute, an array (for photo type)
+     *                or the empty string.
      */
     function getValue($attribute)
     {
@@ -122,8 +123,10 @@ class Turba_Object {
             return null;
         } elseif (isset($GLOBALS['attributes'][$attribute]) &&
                   $GLOBALS['attributes'][$attribute]['type'] == 'image') {
-            return array('load' => array('file' => basename(tempnam(Horde::getTempDir(), 'horde_form_')),
-                                         'data' => $this->attributes[$attribute]));
+            return empty($this->attributes[$attribute])
+                ? null
+                : array('load' => array('file' => basename(tempnam(Horde::getTempDir(), 'horde_form_')),
+                                        'data' => $this->attributes[$attribute]));
         } else {
             return $this->attributes[$attribute];
         }
diff --git a/lib/Turba.php b/lib/Turba.php
index e785172..a2046a1 100644
--- a/lib/Turba.php
+++ b/lib/Turba.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * $Horde: turba/lib/Turba.php,v 1.59.4.43 2008/10/07 12:56:17 jan Exp $
+ * $Horde: turba/lib/Turba.php,v 1.59.4.44 2009/08/04 14:37:30 mrubinsk Exp $
  *
  * @package Turba
  */
@@ -339,6 +339,7 @@ class Turba {
         foreach ($in as $sourceId => $source) {
             $driver = &Turba_Driver::singleton($sourceId);
             if (is_a($driver, 'PEAR_Error')) {
+                Horde::logMessage(sprintf("Could not instantiate the %s source: %s", $sourceId, $driver->getMessage()), __FILE__, __LINE__, PEAR_LOG_ERR);
                 continue;
             }
 
diff --git a/lib/Views/Browse.php b/lib/Views/Browse.php
index c1433cf..a003a05 100644
--- a/lib/Views/Browse.php
+++ b/lib/Views/Browse.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/lib/Views/Browse.php,v 1.12.2.8 2008/09/11 08:46:20 jan Exp $
+ * $Horde: turba/lib/Views/Browse.php,v 1.12.2.9 2009/01/06 15:27:50 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you did
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/lib/api.php b/lib/api.php
index b4d18d1..270fd2a 100644
--- a/lib/api.php
+++ b/lib/api.php
@@ -2,7 +2,7 @@
 /**
  * Turba external API interface.
  *
- * $Horde: turba/lib/api.php,v 1.120.2.61 2008/09/18 17:25:41 mrubinsk Exp $
+ * $Horde: turba/lib/api.php,v 1.120.2.68 2009/09/04 10:38:38 jan Exp $
  *
  * This file defines Turba's external API interface. Other applications can
  * interact with Turba through this API.
@@ -50,12 +50,12 @@ $_services['list'] = array(
 );
 
 $_services['listBy'] = array(
-    'args' => array('action' => 'string', 'timestamp' => 'int'),
+    'args' => array('action' => 'string', 'timestamp' => 'int', 'sources' => '{urn:horde}stringArray'),
     'type' => '{urn:horde}stringArray',
 );
 
 $_services['getActionTimestamp'] = array(
-    'args' => array('uid' => 'string', 'timestamp' => 'int'),
+    'args' => array('uid' => 'string', 'action' => 'string', 'sources' => '{urn:horde}stringArray'),
     'type' => 'int',
 );
 
@@ -188,6 +188,11 @@ $_services['hasComments'] = array(
     'type' => 'boolean'
 );
 
+$_services['getDefaultShare'] = array(
+    'args' => array(),
+    'type' => 'string'
+);
+
 /**
  * Removes user data.
  *
@@ -225,7 +230,7 @@ function _turba_removeUserData($user)
     }
 
     /* Only attempt share removal if we have shares configured */
-    if ($_SESSION['turba']['has_share']) {
+    if (!empty($_SESSION['turba']['has_share'])) {
         $shares = &$GLOBALS['turba_shares']->listShares(
             $user, PERMS_EDIT, $user);
 
@@ -243,7 +248,7 @@ function _turba_removeUserData($user)
                 }
             }
         }
-        
+
         /* Get a list of all shares this user has perms to and remove the perms */
         $shares = $GLOBALS['turba_shares']->listShares($user);
         if (is_a($shares, 'PEAR_Error')) {
@@ -383,6 +388,42 @@ function _turba_fields($source = null)
 
 /**
  * Browses through Turba's object tree.
+ * Retrieve the UID for the current user's default Turba share.
+ *
+ */
+function _turba_getDefaultShare()
+{
+    global $prefs;
+
+    // Bring in turba's base and a clean copy of sources.
+    require_once dirname(__FILE__) . '/base.php';
+    require TURBA_BASE . '/config/sources.php';
+
+    if (!empty($_SESSION['turba']['has_share'])) {
+        $shares = Turba::listShares(true);
+        if (is_a($shares, 'PEAR_Error')) {
+            return false;
+        }
+        foreach ($shares as $uid => $share) {
+            $params = @unserialize($share->get('params'));
+            if (empty($params['source'])) {
+                return false;
+            }
+            $driver = &Turba_Driver::factory($params['source'], $cfgSources[$params['source']]);
+            if (is_a($driver, 'PEAR_Error')) {
+                return false;
+            }
+            if ($driver->checkDefaultShare($share, $cfgSources[$params['source']])) {
+                return $uid;
+            }
+        }
+    }
+
+    // Return Turba's default_dir as default
+    return $prefs->getValue('default_dir');
+}
+
+/**
  *
  * @param string $path       The path of the tree to browse.
  * @param array $properties  The item properties to return. Defaults to 'name',
@@ -805,6 +846,7 @@ function _turba_getActionTimestamp($uid, $action, $sources = null)
         return PEAR::raiseError(_("No address book specified"), 'horde.error');
     }
 
+    $last = 0;
     foreach ($sources as $source) {
         if (empty($source) || !isset($cfgSources[$source])) {
             return PEAR::raiseError(sprintf(_("Invalid address book: %s"), $source), 'horde.error', null, null, $source);
@@ -819,12 +861,12 @@ function _turba_getActionTimestamp($uid, $action, $sources = null)
         $ts = $history->getActionTimestamp('turba:' . $driver->getName()
                                            . ':' . $uid,
                                            $action);
-        if (!empty($ts)) {
-            return $ts;
+        if (!empty($ts) && $ts > $last) {
+            $last = $ts;
         }
     }
 
-    return 0;
+    return $last;
 }
 
 /**
@@ -1429,8 +1471,13 @@ function _turba_search($names = array(), $sources = array(), $fields = array(),
                                 if (empty($value)) {
                                     continue;
                                 }
-                                $seen_key = trim(String::lower($ob->getValue('name')))
-                                    . trim(String::lower($value));
+                                if (!is_array($value)) {
+                                    $seen_key = trim(String::lower($ob->getValue('name')))
+                                        . trim(String::lower($value));
+                                } else {
+                                    $seen_key = trim(String::lower($ob->getValue('name')))
+                                        . trim(String::lower($value['load']['file']));
+                                }
                                 if (isset($attributes[$key]) &&
                                     $attributes[$key]['type'] == 'email' &&
                                     empty($seeninlist[$seen_key])) {
@@ -1591,13 +1638,22 @@ function _turba_listTimeObjectCategories()
 {
     include dirname(__FILE__) . '/../config/attributes.php';
     $categories = array();
+    include dirname(__FILE__) . '/../config/sources.php';
     foreach ($attributes as $key => $attribute) {
         if ($attribute['type'] == 'monthdayyear' &&
             !empty($attribute['time_object_label'])) {
 
-            $categories[$key] = $attribute['time_object_label'];
+            foreach ($cfgSources as $source) {
+                if (!empty($source['map'][$key])) {
+                    $categories[$key] = $attribute['time_object_label'];
+                    break;
+                }
+            }
         }
     }
+
+
+
     return $categories;
 }
 
@@ -1649,6 +1705,7 @@ function _turba_listTimeObjects($time_categories, $start, $end)
             $objects = array_merge($objects, $new_objects);
         }
     }
+
     return $objects;
 }
 
diff --git a/lib/base.php b/lib/base.php
index dc5e5b5..17abd5e 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -2,10 +2,13 @@
 /**
  * Turba base inclusion file.
  *
- * $Horde: turba/lib/base.php,v 1.62.10.20 2008/05/25 17:40:02 chuck Exp $
+ * $Horde: turba/lib/base.php,v 1.62.10.22 2009/08/12 22:28:13 jan Exp $
  *
  * This file brings in all of the dependencies that every Turba script will
  * need, and sets up objects that all scripts use.
+ *
+ * The following global variables are used:
+ *   $no_compress  -  Controls whether the page should be compressed
  */
 
 // Check for a prior definition of HORDE_BASE (perhaps by an auto_prepend_file
@@ -114,6 +117,9 @@ foreach ($copymoveSources as $key => $curSource) {
             htmlspecialchars($curSource['title']) . '</option>';
     }
 }
+$GLOBALS['addSources'] = $addSources;
 
 // Start compression, if requested.
-Horde::compressOutput();
+if (!Util::nonInputVar('no_compress')) {
+    Horde::compressOutput();
+}
diff --git a/lib/prefs.php b/lib/prefs.php
index b8416df..e6a6d03 100644
--- a/lib/prefs.php
+++ b/lib/prefs.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/lib/prefs.php,v 1.2.10.10 2008/08/25 17:10:33 jan Exp $
+ * $Horde: turba/lib/prefs.php,v 1.2.10.11 2009/01/06 15:27:47 jan Exp $
  *
- * Copyright 2001-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/lib/tests/KolabTestBase.php b/lib/tests/KolabTestBase.php
index ab1048e..4ac1e68 100644
--- a/lib/tests/KolabTestBase.php
+++ b/lib/tests/KolabTestBase.php
@@ -2,7 +2,7 @@
 /**
  * Base for PHPUnit scenarios.
  *
- * $Horde: turba/lib/tests/KolabTestBase.php,v 1.1.2.1 2008/11/07 13:20:23 wrobel Exp $
+ * $Horde: turba/lib/tests/KolabTestBase.php,v 1.1.2.2 2009/01/06 15:27:51 jan Exp $
  *
  * PHP version 5
  *
@@ -27,9 +27,9 @@ require_once 'Horde/Kolab.php';
 /**
  * Base for PHPUnit scenarios.
  *
- * $Horde: turba/lib/tests/KolabTestBase.php,v 1.1.2.1 2008/11/07 13:20:23 wrobel Exp $
+ * $Horde: turba/lib/tests/KolabTestBase.php,v 1.1.2.2 2009/01/06 15:27:51 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/lib/version.php b/lib/version.php
index d7dfb6c..a6c2c77 100644
--- a/lib/version.php
+++ b/lib/version.php
@@ -1 +1 @@
-<?php define('TURBA_VERSION', 'H3 (2.3.1)') ?>
+<?php define('TURBA_VERSION', 'H3 (2.3.2)') ?>
diff --git a/locale/da_DK/LC_MESSAGES/turba.mo b/locale/da_DK/LC_MESSAGES/turba.mo
index cb73326..fe7bf38 100644
Binary files a/locale/da_DK/LC_MESSAGES/turba.mo and b/locale/da_DK/LC_MESSAGES/turba.mo differ
diff --git a/locale/de_DE/LC_MESSAGES/turba.mo b/locale/de_DE/LC_MESSAGES/turba.mo
index 1884a7a..2703a4c 100644
Binary files a/locale/de_DE/LC_MESSAGES/turba.mo and b/locale/de_DE/LC_MESSAGES/turba.mo differ
diff --git a/locale/es_ES/LC_MESSAGES/turba.mo b/locale/es_ES/LC_MESSAGES/turba.mo
index 30ee396..292a6b5 100644
Binary files a/locale/es_ES/LC_MESSAGES/turba.mo and b/locale/es_ES/LC_MESSAGES/turba.mo differ
diff --git a/locale/fi_FI/LC_MESSAGES/turba.mo b/locale/fi_FI/LC_MESSAGES/turba.mo
index caca5ac..78748c7 100644
Binary files a/locale/fi_FI/LC_MESSAGES/turba.mo and b/locale/fi_FI/LC_MESSAGES/turba.mo differ
diff --git a/locale/fi_FI/help.xml b/locale/fi_FI/help.xml
index d2f89dc..d67f9a8 100644
--- a/locale/fi_FI/help.xml
+++ b/locale/fi_FI/help.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!-- $Horde: turba/locale/fi_FI/help.xml,v 1.4.10.5 2008/02/22 13:42:51 jan Exp $ -->
+<!-- $Horde: turba/locale/fi_FI/help.xml,v 1.4.10.6 2009/02/03 00:16:10 jan Exp $ -->
 <help>
   <entry id="Overview" md5="290506ade4e6f749246f77bbe5d48835" state="uptodate">
     <title>Yleiskuva</title>
diff --git a/locale/fr_FR/LC_MESSAGES/turba.mo b/locale/fr_FR/LC_MESSAGES/turba.mo
index 5f48e18..910990c 100644
Binary files a/locale/fr_FR/LC_MESSAGES/turba.mo and b/locale/fr_FR/LC_MESSAGES/turba.mo differ
diff --git a/locale/it_IT/LC_MESSAGES/turba.mo b/locale/it_IT/LC_MESSAGES/turba.mo
index 9a2c3ed..baa2e96 100644
Binary files a/locale/it_IT/LC_MESSAGES/turba.mo and b/locale/it_IT/LC_MESSAGES/turba.mo differ
diff --git a/locale/ja_JP/LC_MESSAGES/turba.mo b/locale/ja_JP/LC_MESSAGES/turba.mo
index 660c9d8..e35deb3 100644
Binary files a/locale/ja_JP/LC_MESSAGES/turba.mo and b/locale/ja_JP/LC_MESSAGES/turba.mo differ
diff --git a/locale/ru_RU/LC_MESSAGES/turba.mo b/locale/ru_RU/LC_MESSAGES/turba.mo
index 548d335..a5f2fc0 100644
Binary files a/locale/ru_RU/LC_MESSAGES/turba.mo and b/locale/ru_RU/LC_MESSAGES/turba.mo differ
diff --git a/locale/zh_TW/LC_MESSAGES/turba.mo b/locale/zh_TW/LC_MESSAGES/turba.mo
index bbbac87..2c34e53 100644
Binary files a/locale/zh_TW/LC_MESSAGES/turba.mo and b/locale/zh_TW/LC_MESSAGES/turba.mo differ
diff --git a/minisearch.php b/minisearch.php
index 9c64823..e4f30b1 100644
--- a/minisearch.php
+++ b/minisearch.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/minisearch.php,v 1.20.4.15 2008/05/20 09:32:44 jan Exp $
+ * $Horde: turba/minisearch.php,v 1.20.4.16 2009/01/06 15:27:39 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/po/ar_SY.po b/po/ar_SY.po
index 2353431..1b4855b 100644
--- a/po/ar_SY.po
+++ b/po/ar_SY.po
@@ -1,6 +1,6 @@
 # Turba Arabic Translation.
 # This file is distributed under the same license as the Turba package.
-# Copyright (C) 2003 Platinum Inc. <pl at tinum.info>
+# Copyright 2003 Platinum Inc. <pl at tinum.info>
 # Custom Web Applications <http://platinum-sy.com>
 # Platinum Development Team <devteam at platinum-sy.net>
 #
diff --git a/po/bg_BG.po b/po/bg_BG.po
index 7d07169..28d4484 100644
--- a/po/bg_BG.po
+++ b/po/bg_BG.po
@@ -1,5 +1,5 @@
 # Bulgarian translations for Turba package.
-# Copyright (C) 2002 Horde Project
+# Copyright 2002-2009 The Horde Project
 # This file is distributed under the same license as the Turba package.
 # Miroslav Pendev <miro at cybershade.us>, 2002.
 #
diff --git a/po/ca_ES.po b/po/ca_ES.po
index f47b98a..3533615 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -1,5 +1,5 @@
 # Turba Catalan translation.
-# Copyright (C) 2004 Horde Project
+# Copyright 2004-2009 The Horde Project
 # This file is distributed under the same license as the Turba package.
 # Jordi Giralt <projecte.k2 at upcnet.es>, 2006.
 #
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index a8ed468..93288e4 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -1,6 +1,6 @@
 # translation of turba.po to Cestina
 # Turba Czech Translation.
-# Copyright (C) 2004 Horde Project
+# Copyright 2004-2009 The Horde Project
 # This file is distributed under the same license as the Horde package.
 # Pavel Chytil <pavel at chytil.tk>, 2001-2004.
 #
diff --git a/po/da_DK.po b/po/da_DK.po
index ac9e16e..70c70d6 100644
--- a/po/da_DK.po
+++ b/po/da_DK.po
@@ -4,14 +4,15 @@
 # This file is distributed under the same license as the Turba package.
 # Martin List-Petersen <martin at list-petersen.dk>, 2001.
 # Brian Truelsen <horde+i18n at briantruelsen.dk>, 2005-2006.
+# Niels Baggesen <nba at users.sourceforge.net>, 2009.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Turba H3 (2.2-cvs)\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2006-03-11 12:34+0100\n"
-"PO-Revision-Date: 2006-03-11 12:45+0100\n"
-"Last-Translator: Brian Truelsen <horde+i18n at briantruelsen.dk>\n"
+"POT-Creation-Date: 2009-06-15 19:54+0200\n"
+"PO-Revision-Date: 2009-04-25 12:45+0100\n"
+"Last-Translator: Niels Baggesen <nba at users.sourceforge.net>\n"
 "Language-Team: i18n at lists.horde.org\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
@@ -26,17 +27,27 @@ msgstr "Tilf
 msgid " Delete IMSP Address Book"
 msgstr "Slet IMSP-adressekartotek"
 
-#: data.php:334
+#: data.php:455
 #, php-format
 msgid "\"%s\" already exists and was not imported."
 msgstr "\"%s\" findes allerede og blev ikke importeret."
 
-#: browse.php:140
+#: lib/Forms/EditContact.php:83
+#, php-format
+msgid "\"%s\" updated, but saving the uploaded file failed: %s"
+msgstr "\"%s\" opdateret, men lagring af overført fil mislykkedes: %s"
+
+#: lib/Forms/EditContact.php:85 lib/Forms/EditContact.php:88
+#, php-format
+msgid "\"%s\" updated."
+msgstr "\"%s\" opdateret."
+
+#: lib/Views/Browse.php:192
 #, php-format
 msgid "\"%s\" was not copied because it is a list."
 msgstr "\"%s\" blev ikke kopieret, fordi den er en liste."
 
-#: browse.php:138
+#: lib/Views/Browse.php:190
 #, php-format
 msgid "\"%s\" was not moved because it is a list."
 msgstr "\"%s\" blev ikke flyttet, fordi den er en liste."
@@ -49,68 +60,73 @@ msgstr "\"Fornavn Efternavn\"  (fx Jens Hansen)"
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr "\"Efternavn, Fornavn\" (fx Hansen, Jens)"
 
-#: add.php:109
+#: lib/Driver.php:624
+#, php-format
+msgid "%d. %s of %s"
+msgstr "%d. %s af %s"
+
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr "%s tilføjet"
 
-#: data.php:352
+#: data.php:483
 #, php-format
-msgid "%s file successfully imported"
+msgid "%s file successfully imported."
 msgstr "%s-fil importeret"
 
-#: templates/browse/footer.inc:5
+#: templates/list/numPager.inc:6
 #, php-format
 msgid "%s to %s of %s"
 msgstr "%s til %s af %s"
 
-#: lib/Turba.php:507
+#: lib/Turba.php:541
 #, php-format
 msgid "%s's Address Book"
 msgstr "%ss adressekartotek"
 
-#: lib/Block/minisearch.php:42
-msgid "A browser that supports iFrames is required"
-msgstr "En browser som understøtter <em>iFrames</em> er nødvendig"
+#: lib/Block/minisearch.php:44
+msgid "A browser that supports iframes is required"
+msgstr "En browser som understøtter iframes er nødvendig"
 
-#: config/prefs.php.dist:150
-msgid "Above search form"
-msgstr "Ovenstående søgeformular"
-
-#: view.php:52
+#: view.php:54
 #, php-format
 msgid "Access denied to %s"
 msgstr "Adgang nægtet til %s"
 
-#: add.php:56 templates/browse/actions.inc:29
+#: templates/browse/actions.inc:30 lib/Forms/AddContact.php:25
 msgid "Add"
 msgstr "Tilføj"
 
-#: templates/prefs/addressbookselect.inc:174
+#: lib/Forms/AddContact.php:22
+msgid "Add Contact"
+msgstr "Tilføj kontrakt"
+
+#: templates/prefs/addressbookselect.inc:173
 msgid "Add address book"
 msgstr "Tilføj adressekartotek"
 
-#: templates/prefs/columnselect.inc:237
-msgid "Add column"
-msgstr "Tilføj kolonne"
-
-#: edit.php:133 lib/Views/EditContact.php:68
+#: lib/Forms/EditContact.php:34
 msgid "Add file"
 msgstr "Tilføj fil"
 
-#: templates/browse/actions.inc:29
+#: templates/browse/actions.inc:30
 msgid "Add to"
 msgstr "Tilføj til"
 
-#: lib/Driver.php:1137
+#: lib/Driver.php:2119 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr "Tilføjelse af kontakter er ikke tilgængelig."
 
-#: templates/addressbooks.inc:88
+#: templates/addressbook_list.php:16 templates/browse/search.inc:125
 msgid "Address Book"
 msgstr "Adressekartotek"
 
-#: browse.php:28 config/prefs.php.dist:115
+#: templates/addressbook_list.php:12
+msgid "Address Book List"
+msgstr "Adressekartoteket-fortegnelse"
+
+#: lib/Views/Browse.php:78 config/prefs.php.dist:115
 msgid "Address Book Listing"
 msgstr "Adressekartoteket-fortegnelse"
 
@@ -118,102 +134,133 @@ msgstr "Adressekartoteket-fortegnelse"
 msgid "Address Books"
 msgstr "Adressekartoteker"
 
-#: add.php:108
-msgid "Address book entry"
-msgstr "Adressekartotekspost"
-
-#: data.php:314
+#: data.php:435
 msgid "Address book successfully purged."
 msgstr "Adressekartotek tømt."
 
-#: templates/addressbooks.inc:64
-msgid "Address book to delete "
-msgstr "Adressekartotek, der skal slettes "
-
-#: templates/prefs/addressbookselect.inc:170
+#: templates/prefs/addressbookselect.inc:167
+#: templates/prefs/addressbookselect.inc:169
 msgid "Address books that will not be displayed:"
 msgstr "Adressekartoteker, som ikke vil blive vist:"
 
-#: search.php:207 templates/browse/search.inc:48
+#: search.php:184 templates/browse/search.inc:47
 msgid "Advanced Search"
 msgstr "Udvidet søgning"
 
-#: config/attributes.php.dist:64
+#: config/attributes.php.dist:83
 msgid "Alias"
 msgstr "Kaldenavn"
 
-#: templates/browse/actions.inc:48 templates/browse/footerAlpha.inc:7
-#: templates/browse/footerAlpha.inc:10
+#: templates/list/alphaPager.inc:7 templates/list/alphaPager.inc:10
 msgid "All"
 msgstr "Alle"
 
-#: lib/api.php:575
+#: lib/api.php:982
 msgid "Already Exists"
 msgstr "Findes allerede"
 
-#: templates/browse/javascript.inc:93
+#: config/attributes.php.dist:106
+msgid "Anniversaries"
+msgstr "Årsdage"
+
+#: config/attributes.php.dist:102
+msgid "Anniversary"
+msgstr "Årsdag"
+
+#: templates/browse/javascript.inc:85
 #, php-format
 msgid "Are you sure that you want to delete %s?"
 msgstr "Er du sikker på, at du vil slette %s?"
 
-#: templates/browse/javascript.inc:67
-msgid "Are you sure that you want to delete the selected entries?"
-msgstr "Er du sikker på, at du vil slette de valgte poster?"
+#: templates/browse/javascript.inc:66
+msgid "Are you sure that you want to delete the selected contacts?"
+msgstr "Er du sikker på, at du vil slette de valgte kontakter?"
 
-#: config/prefs.php.dist:86
-msgid "Ascending"
-msgstr "Stigende"
+#: config/attributes.php.dist:430
+msgid "Assistant"
+msgstr "Assistent"
 
-#: search.php:204 templates/browse/search.inc:47
+#: search.php:181 templates/browse/search.inc:46
 msgid "Basic Search"
 msgstr "Simpel søgning"
 
-#: config/prefs.php.dist:149
-msgid "Below search form"
-msgstr "Nedenstående søgeformular"
-
-#: lib/Driver/ldap.php:84 lib/Driver/ldap.php:87
+#: lib/Driver/ldap.php:92 lib/Driver/ldap.php:95
 #, php-format
 msgid "Bind failed: (%s) %s"
 msgstr "Tilkobling fejlede: (%s) %s"
 
-#: config/attributes.php.dist:178
+#: config/attributes.php.dist:95
 msgid "Birthday"
 msgstr "Fødselsdag"
 
-#: templates/menu.inc:7
+#: config/attributes.php.dist:99
+msgid "Birthdays"
+msgstr "Fødselsdage"
+
+#: contact.php:128 templates/browse/row.inc:10
+msgid "Blank name"
+msgstr ""
+
+#: templates/browse/actions.inc:51
+msgid "Both"
+msgstr "Begge"
+
+#: templates/addressbook_list.php:29 templates/menu.inc:8
+#: addressbooks/index.php:39
 msgid "Browse"
 msgstr "Skim"
 
-#: config/attributes.php.dist:173
+#: config/attributes.php.dist:300
 msgid "Business Category"
 msgstr "Firmakategori"
 
-#: data.php:58
+#: data.php:101
 msgid "CSV"
 msgstr "CSV"
 
-#: lib/Object/Group.php:57
+#: lib/Object/Group.php:68
 msgid "Can't add a group to itself."
 msgstr "Kan ikke tilføje en gruppe til sig selv."
 
-#: templates/browse/column_headers.inc:7
+#: lib/Forms/DeleteAddressBook.php:45 lib/Forms/DeleteAddressBook.php:54
+msgid "Cancel"
+msgstr "Annuller"
+
+#: lib/Driver/kolab.php:624
+#, php-format
+msgid "Cannot delete all address book entries for %s"
+msgstr "Kan ikke slette alle adresseindgange for %s"
+
+#: config/attributes.php.dist:388
+msgid "Category"
+msgstr "Kategori"
+
+#: templates/browse/column_headers.inc:25
+#, php-format
+msgid "Change %s sort to %s"
+msgstr "Skift %s sortering til %s"
+
+#: templates/addressbook_list.php:33 addressbooks/index.php:41
+msgid "Change Permissions"
+msgstr "Opdater rettigheder"
+
+#: templates/browse/column_headers.inc:8
+msgid "Check All/None"
+msgstr "Hak alle/ingen af"
+
+#: templates/browse/column_headers.inc:8
 msgid "Check _All/None"
 msgstr "Hak alle/ingen af"
 
-#: templates/addressbooks.inc:45
-msgid "Choose a name"
-msgstr "Vælg et navn"
+#: config/attributes.php.dist:115
+msgid "Children"
+msgstr "Børn"
 
-#: add.php:48
+#: lib/Forms/AddContact.php:36
 msgid "Choose an address book"
 msgstr "Vælg et adressekartotek"
 
-#: templates/prefs/columnselect.inc:221
-msgid "Choose an address book:"
-msgstr "Vælg et adressekartotek:"
-
-#: templates/prefs/addressbookselect.inc:165
+#: templates/prefs/addressbookselect.inc:163
 msgid "Choose which address books to display, and in what order:"
 msgstr "Vælg de adressekartoteker, der skal vises og tilhørende rækkefølge:"
 
@@ -221,22 +268,24 @@ msgstr "V
 msgid "Choose which address books to use."
 msgstr "Vælg de adressekartoteker, der skal anvendes."
 
-#: templates/prefs/columnselect.inc:228
-msgid "Choose which columns to display and in what order:"
-msgstr "Vælg hvilke kolonner, der skal vises og i hvilken rækkefølge:"
+#: templates/prefs/columnselect.inc:41
+msgid ""
+"Click an address book to sort its columns. Drag columns to re-arrange them. "
+"Check a column to enable it."
+msgstr ""
 
 #: templates/block/minisearch.inc:26
 msgid "Close"
 msgstr "Luk"
 
+#: templates/browse/header.inc:7
+msgid "Close Search"
+msgstr "Afslut søgning"
+
 #: config/prefs.php.dist:17
 msgid "Column Options"
 msgstr "Kolonne-indstillinger"
 
-#: templates/prefs/columnselect.inc:233
-msgid "Columns that will not be displayed:"
-msgstr "Kolonner, som ikke vil blive vist:"
-
 #: templates/data/export.inc:12 templates/data/import.inc:13
 msgid "Comma separated values"
 msgstr "Kommaseparerede værdier"
@@ -245,22 +294,65 @@ msgstr "Kommaseparerede v
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr "Kommaseparerede værdier (Microsoft Outlook)"
 
-#: config/attributes.php.dist:76
+#: config/attributes.php.dist:528
+msgid "Common Address Extended"
+msgstr "Udvidet Adresse (fælles)"
+
+#: config/attributes.php.dist:546
+msgid "Common City"
+msgstr "By (fælles)"
+
+#: config/attributes.php.dist:564
+msgid "Common Country"
+msgstr "Land (fælles)"
+
+#: config/attributes.php.dist:472
+msgid "Common Phone"
+msgstr "Telefon (fælles)"
+
+#: config/attributes.php.dist:540
+msgid "Common Post Office Box"
+msgstr "Postboks (fælles)"
+
+#: config/attributes.php.dist:558
+msgid "Common Postal Code"
+msgstr "Postnummer (fælles)"
+
+#: config/attributes.php.dist:552
+msgid "Common State/Province"
+msgstr "Region (fælles)"
+
+#: config/attributes.php.dist:534
+msgid "Common Street"
+msgstr "Gade (fælles)"
+
+#: config/attributes.php.dist:497
+msgid "Common Video Call"
+msgstr "Video link (fælles)"
+
+#: config/sources.php.dist:256 config/sources.php.dist:952
+msgid "Communications"
+msgstr "Kontaktformer"
+
+#: config/attributes.php.dist:306
 msgid "Company"
 msgstr "Firma"
 
-#: config/attributes.php.dist:144
+#: config/attributes.php.dist:235
 msgid "Company Address"
 msgstr "Adresse (arbejde)"
 
-#: lib/api.php:319 lib/api.php:364 lib/api.php:408 lib/api.php:514
-#: lib/api.php:640 lib/api.php:727 lib/api.php:780 lib/api.php:861
-#: lib/api.php:1058 lib/api.php:1146
+#: scripts/import_squirrelmail_file_abook.php:114
+#: scripts/import_squirrelmail_sql_abook.php:125 lib/api.php:587
+#: lib/api.php:641 lib/api.php:694 lib/api.php:742 lib/api.php:797
+#: lib/api.php:856 lib/api.php:907 lib/api.php:1045 lib/api.php:1107
+#: lib/api.php:1178 lib/api.php:1245 lib/api.php:1365 lib/api.php:1609
+#: lib/api.php:1695 lib/api.php:1847
 #, php-format
 msgid "Connection failed: %s"
 msgstr "Forbindelse fejlede: %s"
 
-#: lib/Driver/ldap.php:65
+#: lib/Driver/ldap.php:68
 msgid "Connection failure"
 msgstr "Forbindelsesfejl"
 
@@ -268,7 +360,15 @@ msgstr "Forbindelsesfejl"
 msgid "Contact Search"
 msgstr "Kontakt-søgning"
 
-#: browse.php:306
+#: config/sources.php.dist:868
+msgid "Contacts"
+msgstr "Kontakter"
+
+#: templates/list/numPager.inc:3
+msgid "Contacts displayed:"
+msgstr "Kontakter vist:"
+
+#: lib/Views/Browse.php:346
 #, php-format
 msgid "Contacts in list: %s"
 msgstr "Kontakter i liste: %s"
@@ -277,97 +377,66 @@ msgstr "Kontakter i liste: %s"
 msgid "Copy"
 msgstr "Kopier"
 
-#: lib/VBook.php:284 lib/VBook.php:342
-#, php-format
-msgid "Could not find the virtual address book \"%s\""
-msgstr "Kunne ikke finde det virtuelle adressekartoteket, \"%s\""
-
-#: search.php:97
-#, php-format
-msgid "Could not update the virtual address book \"%s\""
-msgstr "Kunne ikke opdateret det virtuelle adressekartoteket, \"%s\""
-
-#: templates/addressbooks.inc:54
+#: lib/Forms/CreateAddressBook.php:39
 msgid "Create"
 msgstr "Opret"
 
-#: templates/addressbooks.inc:41
+#: lib/Forms/CreateAddressBook.php:34
 msgid "Create Address Book"
 msgstr "Opret adressekartotek"
 
-#: lib/ListView.php:381
+#: templates/addressbook_list.php:8
+msgid "Create a new Address Book"
+msgstr "Opret et nyt adressekartotek"
+
+#: lib/ListView.php:448
 msgid "Create a new Contact List in:"
-msgstr "Opret en nyt brevpapir"
+msgstr "Opret en ny kontaktliste i:"
 
-#: lib/ObjectView.php:125
+#: lib/Views/Contact.php:80
 msgid "Created"
 msgstr "Oprettet"
 
-#: contact.php:83
+#: contact.php:95
 msgid "De_lete"
 msgstr "Slet"
 
-#: config/prefs.php.dist:88
-msgid "Default sorting direction:"
-msgstr "Standard sorteringsretning:"
-
-#: templates/addressbooks.inc:78 templates/browse/actions.inc:3
-#: templates/browse/header.inc:23 lib/Object.php:329
-#: lib/Views/DeleteContact.php:58
+#: templates/addressbook_list.php:35 templates/browse/actions.inc:3
+#: lib/Views/DeleteContact.php:58 lib/Forms/DeleteAddressBook.php:45
+#: addressbooks/index.php:42
 msgid "Delete"
 msgstr "Slet"
 
-#: lib/Views/DeleteContact.php:28
+#: lib/Views/DeleteContact.php:28 lib/Forms/DeleteAddressBook.php:40
 #, php-format
 msgid "Delete %s"
 msgstr "Slet %s"
 
-#: templates/addressbooks.inc:60
-msgid "Delete Address Book"
-msgstr "Slet adressekartotek"
-
-#: config/prefs.php.dist:38
-msgid "Delete Confirmation"
-msgstr "Godkend sletning"
+#: lib/api.php:685
+msgid "Delete denied."
+msgstr "Sletning nægtet."
 
-#: config/prefs.php.dist:39
-msgid "Delete button behaviour"
-msgstr "Opførsel af slette-knap"
-
-#: lib/Driver/ldap.php:277
+#: lib/Driver/ldap.php:321
 #, php-format
 msgid "Delete failed: (%s) %s"
 msgstr "Sletning mislykkedes: (%s) %s"
 
-#: templates/browse/header.inc:19
-#, php-format
-msgid "Delete virtual address book \"%s\""
-msgstr "Slet virtueltadressekartotek, \"%s\""
-
-#: lib/Driver.php:1145
+#: lib/Driver.php:2127 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr "Sletning af kontakter er ikke tilgængelig."
 
-#: delete.php:38
+#: delete.php:40
 msgid "Deletion failed"
 msgstr "Sletning mislykkedes"
 
-#: config/attributes.php.dist:213
+#: config/attributes.php.dist:312
 msgid "Department"
 msgstr "Afdeling"
 
-#: config/prefs.php.dist:87
-msgid "Descending"
-msgstr "Faldende"
-
-#: templates/addressbooks.inc:117
+#: lib/Forms/CreateAddressBook.php:37 lib/Forms/EditAddressBook.php:44
 msgid "Description"
 msgstr "Beskrivelse"
 
-#: templates/browse/search.inc:144
-msgid "Directory"
-msgstr "Katalog"
-
 #: config/prefs.php.dist:24
 msgid "Display"
 msgstr "Vis"
@@ -377,113 +446,78 @@ msgstr "Vis"
 msgid "Display Options"
 msgstr "Indstillinger for visning"
 
-#: config/prefs.php.dist:167
-msgid "Do you want to confirm deleting entries?"
-msgstr "Vil du godkende sletning af poster?"
-
-#: lib/Object.php:298
+#: lib/Object.php:360
 msgid "Download"
 msgstr "Hent"
 
-#: templates/browse/row.inc:17
+#: templates/browse/row.inc:27 templates/browse/row.inc:28
+#: templates/browse/contactrow.inc:25
 msgid "Download vCard"
 msgstr "Hent vCard"
 
-#: templates/addressbooks.inc:104 templates/browse/actions.inc:6
-#: templates/browse/column_headers.inc:10 templates/browse/header.inc:20
-#: templates/browse/row.inc:26
+#: templates/addressbook_list.php:31 templates/browse/actions.inc:6
+#: templates/browse/column_headers.inc:11 templates/browse/row.inc:40
+#: templates/browse/row.inc:41 templates/browse/contactrow.inc:33
+#: addressbooks/index.php:40
 msgid "Edit"
 msgstr "Rediger"
 
-#: templates/browse/row.inc:26
+#: edit.php:91 templates/browse/contactrow.inc:33
 #, php-format
 msgid "Edit \"%s\""
 msgstr "Redigér \"%s\""
 
-#: lib/Views/EditContact.php:28
+#: lib/Views/EditContact.php:35 lib/Forms/EditAddressBook.php:40
 #, php-format
 msgid "Edit %s"
 msgstr "Ret %s"
 
-#: templates/addressbooks.inc:83
-msgid "Edit Address Books"
-msgstr "Ændre adressekartoteker"
-
-#: templates/browse/header.inc:22
-msgid "Edit Permissions"
-msgstr "Ændre tilladelser"
-
-#: templates/browse/vbook_header.inc:2
-msgid "Edit Virtual Address Book"
-msgstr "Redigér virtuelt adressekartotek"
-
-#: edit.php:84 edit.php:159
-#, php-format
-msgid "Edit entry for %s"
-msgstr "Redigér post for %s"
-
-#: templates/browse/header.inc:18
-#, php-format
-msgid "Edit permissions for virtual address book \"%s\""
-msgstr "Redigér tilladelser for virtuelt adressekartotek, \"%s\""
-
-#: templates/browse/header.inc:17
-#, php-format
-msgid "Edit virtual address book definition of \"%s\""
-msgstr "Redigér definition af virtuelt adressekartotek, \"%s\""
-
-#: config/attributes.php.dist:58
+#: config/attributes.php.dist:249
 msgid "Email"
 msgstr "E-post"
 
-#: edit.php:152
-#, php-format
-msgid "Entry for %s updated, but saving the uploaded file failed: %s"
-msgstr "Post for %s opdateret, men lagring af overført fil mislykkedes: %s"
-
-#: edit.php:154 edit.php:157
-#, php-format
-msgid "Entry for %s updated."
-msgstr "Registrering for %s opdateret."
+#: config/attributes.php.dist:255
+msgid "Emails"
+msgstr "E-post"
 
-#: browse.php:216 browse.php:264
+#: lib/Views/Browse.php:270 lib/Views/Browse.php:310
 #, php-format
 msgid "Error adding %d contact(s) to list."
 msgstr "Fejl under tilføjelse af %d kontakt(er) til liste."
 
-#: browse.php:218 browse.php:266
+#: lib/Views/Browse.php:272 lib/Views/Browse.php:312
 #, php-format
 msgid "Error adding %d of %d requested contact(s) to list."
 msgstr "Fejl under tilføjelse af %d ud af %d anmodede kontakter til liste."
 
-#: browse.php:86
+#: lib/Views/Browse.php:134
 #, php-format
 msgid "Error deleting %d contact(s)."
 msgstr "Der opstod en fejl under sletning af %d kontakt(er)."
 
-#: browse.php:88
+#: lib/Views/Browse.php:136
 #, php-format
 msgid "Error deleting %d of %d requested contacts(s)."
 msgstr "Fejl under sletning af %d ud af %d anmodede kontakter."
 
-#: browse.php:66
+#: lib/Views/Browse.php:117
 #, php-format
 msgid "Error removing %d contact(s) from list."
 msgstr "Der opstod et problem under sletning af %d kontakt(er) fra liste."
 
-#: browse.php:68
+#: lib/Views/Browse.php:119
 #, php-format
 msgid "Error removing %d of %d requested contact(s) from list."
 msgstr ""
 "Der opstod et problem under sletning af %d ud af %d anmodede kontakt(er) fra "
 "liste."
 
-#: lib/api.php:414
+#: lib/api.php:748
 #, php-format
 msgid "Error searching the address book: %s"
 msgstr "Der opstod en fejl under søgning i adressekartoteket: %s"
 
-#: templates/data/export.inc:41 templates/browse/actions.inc:10
+#: templates/browse/actions.inc:10 templates/data/export.inc:42
 msgid "Export"
 msgstr "Eksportér"
 
@@ -491,126 +525,161 @@ msgstr "Eksport
 msgid "Export Address Book"
 msgstr "Eksportér adressekartotek"
 
-#: templates/data/export.inc:21
+#: templates/data/export.inc:22
 msgid "Export only the selected contacts."
 msgstr "Eksportér kun de valgte kontakter."
 
-#: templates/data/export.inc:27
+#: templates/data/export.inc:28
 msgid "Export the following address book completely."
 msgstr "Eksportér hele følgende adressekartotek."
 
-#: add.php:67 browse.php:35 browse.php:103 browse.php:130 data.php:143
-#: data.php:237 data.php:306 search.php:66
+#: add.php:42 data.php:247 data.php:346 data.php:424 search.php:106
+#: lib/Views/Browse.php:84 lib/Views/Browse.php:152 lib/Views/Browse.php:180
 #, php-format
 msgid "Failed to access the address book: %s"
 msgstr "Kunne ikke tilgå kataloget: %s"
 
-#: browse.php:158
+#: lib/Views/Browse.php:211
 #, php-format
 msgid "Failed to add %s to %s: %s"
 msgstr "Kunne ikke tilføje %s til %s: %s"
 
-#: browse.php:312
+#: lib/Views/Browse.php:352
 msgid "Failed to browse list"
 msgstr "Skimning af liste fejlede"
 
-#: browse.php:350
+#: lib/Views/Browse.php:383
 msgid "Failed to browse the directory"
 msgstr "Kunne ikke skimme fortegnelsen"
 
-#: lib/Driver/ldap.php:316
+#: lib/Driver/ldap.php:354
 #, php-format
 msgid "Failed to change name: (%s) %s; Old DN = %s, New DN = %s, Root = %s"
 msgstr "Navnskift fejlede: (%s) %s; Gammel DN = %s, ny DN = %s, rod = %s\""
 
-#: search.php:128
-#, php-format
-msgid "Failed to delete the virtual address book. %s"
-msgstr "Kunne ikke slette det virtuelle adressekartotek. %s"
-
-#: browse.php:134
+#: lib/Views/Browse.php:186
 #, php-format
 msgid "Failed to find object to be added: %s"
 msgstr "Kunne ikke finde objektet, som skulle tilføjes: %s"
 
-#: search.php:198
+#: search.php:175
 msgid "Failed to search the address book"
 msgstr "Kunne ikke søge i adressekartoteket"
 
-#: data.php:158
+#: data.php:262
 #, php-format
 msgid "Failed to search the directory: %s"
 msgstr "Kunne ikke søge i kataloget: %s"
 
-#: config/sources.php.dist:453
+#: config/sources.php.dist:565
 msgid "Favourite Recipients"
 msgstr "Foretrukne modtagere"
 
-#: config/attributes.php.dist:167
+#: config/attributes.php.dist:276
 msgid "Fax"
 msgstr "Fax"
 
-#: edit.php:129 lib/Views/Contact.php:83 lib/Views/EditContact.php:64
+#: lib/Forms/Contact.php:41
 msgid "Files"
 msgstr "Filer"
 
-#: templates/browse/search.inc:94
+#: templates/browse/search.inc:104
 msgid "Find"
 msgstr "Find"
 
-#: edit.php:103 edit.php:192
+#: lib/Forms/EditContact.php:128 lib/Forms/EditContact.php:167
 msgid "Finish"
 msgstr "Afslut"
 
-#: config/attributes.php.dist:48
+#: config/attributes.php.dist:53
 msgid "First Name"
 msgstr "Fornavn"
 
-#: config/attributes.php.dist:202
+#: config/attributes.php.dist:350
 msgid "Freebusy URL"
 msgstr "Ledig/optaget URL"
 
-#: templates/browse/search.inc:107
+#: templates/browse/search.inc:98
 msgid "From"
 msgstr "Fra"
 
-#: config/sources.php.dist:637
+#: config/attributes.php.dist:436
+msgid "Gender"
+msgstr "Køn"
+
+#: config/sources.php.dist:791
 msgid "Global Address Book"
-msgstr "Global adressekartotek"
+msgstr "Globalt adressekartotek"
 
-#: templates/browse/row.inc:44
+#: templates/browse/row.inc:61 templates/browse/contactrow.inc:44
 msgid "Group"
 msgstr "Gruppe"
 
-#: config/attributes.php.dist:82
+#: config/attributes.php.dist:135
 msgid "Home Address"
 msgstr "Privat-adresse"
 
-#: config/attributes.php.dist:93
+#: config/attributes.php.dist:598
+msgid "Home Address Extended"
+msgstr "Privat-adresse (udvidet)"
+
+#: config/attributes.php.dist:153
 msgid "Home City"
 msgstr "By (hjemme)"
 
-#: config/attributes.php.dist:108
+#: config/attributes.php.dist:171
 msgid "Home Country"
 msgstr "Land (hjemme)"
 
-#: config/attributes.php.dist:150
+#: config/attributes.php.dist:466
+msgid "Home Email"
+msgstr "E-post (hjemme)"
+
+#: config/attributes.php.dist:482
+msgid "Home Fax"
+msgstr "Fax (hjemme)"
+
+#: config/attributes.php.dist:604
+msgid "Home Latitude"
+msgstr "Breddegrad (hjemme)"
+
+#: config/attributes.php.dist:609
+msgid "Home Longitude"
+msgstr "Længdegrad (hjemme)"
+
+#: config/attributes.php.dist:492
+msgid "Home Mobile Phone"
+msgstr "Mobil (hjemme)"
+
+#: config/attributes.php.dist:261
 msgid "Home Phone"
 msgstr "Privat-telefon"
 
-#: config/attributes.php.dist:103
+#: config/attributes.php.dist:147
+msgid "Home Post Office Box"
+msgstr "Postboks (hjemme)"
+
+#: config/attributes.php.dist:165
 msgid "Home Postal Code"
 msgstr "Postnummer (hjemme)"
 
-#: config/attributes.php.dist:98
+#: config/attributes.php.dist:159
 msgid "Home State/Province"
 msgstr "Region (hjemme)"
 
-#: config/attributes.php.dist:88
+#: config/attributes.php.dist:141
 msgid "Home Street Address"
 msgstr "Adresse (hjemme)"
 
-#: config/sources.php.dist:536
+#: config/attributes.php.dist:507
+msgid "Home Video Call"
+msgstr "Videolink (hjemme)"
+
+#: config/attributes.php.dist:592
+msgid "Home Website URL"
+msgstr "Hjemmeside (hjemme)"
+
+#: config/sources.php.dist:682
 msgid "IMSP"
 msgstr "IMSP"
 
@@ -619,64 +688,128 @@ msgstr "IMSP"
 msgid "Import Address Book, Step %d"
 msgstr "Importér adressekartotek, trin %d"
 
-#: data.php:370
+#: data.php:501
 msgid "Import/Export Address Books"
 msgstr "Import/eksport af adressekartoteker"
 
-#: lib/api.php:635 lib/api.php:722
+#: config/attributes.php.dist:412
+msgid "Initials"
+msgstr "Initialer"
+
+#: config/attributes.php.dist:418
+#, fuzzy
+msgid "Instant Messenger"
+msgstr "Vigtige beskeder"
+
+#: lib/api.php:1040 lib/api.php:1173
 msgid "Invalid ID"
 msgstr "Ugyldig ID"
 
-#: lib/api.php:231 lib/api.php:403 lib/api.php:446 lib/api.php:480
-#: lib/api.php:509 lib/api.php:631 lib/api.php:718 lib/api.php:770
-#: lib/api.php:1129
-msgid "Invalid address book"
-msgstr "Ugyldigt adressekartotek"
+#: scripts/import_squirrelmail_file_abook.php:107
+#: scripts/import_squirrelmail_sql_abook.php:118 lib/api.php:373
+#: lib/api.php:737 lib/api.php:792 lib/api.php:851 lib/api.php:900
+#: lib/api.php:1036 lib/api.php:1169 lib/api.php:1235 lib/api.php:1830
+#, php-format
+msgid "Invalid address book: %s"
+msgstr "Ugyldigt adressekartotek: %s"
+
+#: lib/api.php:1239
+msgid "Invalid contact unique ID"
+msgstr "Ugyldigt kontakt-ID."
 
-#: lib/api.php:1133 lib/api.php:1207 lib/api.php:1260
+#: lib/api.php:1834 lib/api.php:1920 lib/api.php:1981
 msgid "Invalid email"
 msgstr "Ugyldig e-mail-adresse"
 
-#: lib/api.php:1141
+#: lib/api.php:1842
 msgid "Invalid entry"
 msgstr "Ugyldig post"
 
-#: lib/Driver/ldap.php:273
+#: lib/Driver/ldap.php:317
 msgid "Invalid key specified."
 msgstr "Ugyldig nøgle angivet."
 
-#: lib/api.php:1137
+#: lib/api.php:1838
 msgid "Invalid name"
 msgstr "Ugyldigt navn"
 
-#: lib/api.php:774
-msgid "Invalid objectId"
-msgstr "Ugyldigt objekt-id"
+#: config/attributes.php.dist:288
+msgid "Job Title"
+msgstr "Titel"
+
+#: config/attributes.php.dist:406
+msgid "Kolab Home Server"
+msgstr ""
 
-#: lib/Driver/ldap.php:61
+#: lib/Driver/ldap.php:64
 msgid ""
 "LDAP support is required but the LDAP module is not available or not loaded."
 msgstr ""
 "LDAP understøttelse er nødvendig men LDAP-modulet er ikke tilgængelig eller "
 "ikke lastet."
 
-#: lib/ObjectView.php:130
+#: data.php:106 templates/data/export.inc:16 templates/data/import.inc:18
+msgid "LDIF Address Book"
+msgstr "LDIF adressekartotek"
+
+#: config/attributes.php.dist:442
+msgid "Language"
+msgstr "Sprog"
+
+#: lib/Views/Contact.php:91
 msgid "Last Modified"
 msgstr "Sidst ændret"
 
-#: config/attributes.php.dist:53
+#: config/attributes.php.dist:59
 msgid "Last Name"
 msgstr "Efternavn"
 
-#: templates/browse/column_headers.inc:16
+#: config/attributes.php.dist:448
+msgid "Latitude"
+msgstr "Breddegrad"
+
+#: templates/browse/column_headers.inc:17
 msgid "List"
 msgstr "Liste"
 
-#: templates/browse/search.inc:101
+#: config/sources.php.dist:251 config/sources.php.dist:948
+msgid "Location"
+msgstr "Sted"
+
+#: config/attributes.php.dist:324
+msgid "Logo"
+msgstr "Logo"
+
+#: config/attributes.php.dist:330
+msgid "Logo MIME Type"
+msgstr "Logo MIME type"
+
+#: config/attributes.php.dist:453
+msgid "Longitude"
+msgstr "Længdegrad"
+
+#: lib/api.php:657
+msgid "Malformed request."
+msgstr "Fejlagtig anmodning."
+
+#: templates/addressbook_list.php:2 addressbooks/index.php:46
+msgid "Manage Address Books"
+msgstr "Mine adressekartoteker"
+
+#: config/attributes.php.dist:424
+#, fuzzy
+msgid "Manager"
+msgstr "Filhåndtering"
+
+#: contact.php:109
+msgid "Mark this as your own contact"
+msgstr "Marker som dig selv"
+
+#: templates/browse/search.inc:109
 msgid "Matching"
 msgstr "Matcher"
 
-#: lib/api.php:206
+#: lib/api.php:334
 msgid "Maximum Number of Contacts"
 msgstr "Maksimalt antal kontakter"
 
@@ -688,20 +821,28 @@ msgstr "Maksimalt antal sider"
 msgid "Menu List"
 msgstr "Menu-liste"
 
-#: lib/Driver/ldap.php:309
+#: config/attributes.php.dist:65
+msgid "Middle Names"
+msgstr "Mellemnavne"
+
+#: lib/Driver/ldap.php:347
 msgid "Missing DN in LDAP source configuration."
 msgstr "Mangler DN i LDAP-kilde-konfiguration."
 
-#: config/attributes.php.dist:162
+#: config/attributes.php.dist:271
 msgid "Mobile Phone"
 msgstr "Mobil (hjemme)"
 
-#: lib/Driver/ldap.php:339 lib/Driver/ldap.php:355
+#: lib/Driver/ldap.php:376 lib/Driver/ldap.php:392
 #, php-format
 msgid "Modify failed: (%s) %s"
 msgstr "Modifikation fejlede: (%s) %s"
 
-#: lib/api.php:1246
+#: templates/browse/header.inc:8
+msgid "More Options..."
+msgstr "Flere valg..."
+
+#: lib/api.php:1958
 msgid "More than 1 entry found"
 msgstr "Fandt mere end 1 opslag"
 
@@ -709,36 +850,31 @@ msgstr "Fandt mere end 1 opslag"
 msgid "Move"
 msgstr "Flyt"
 
-#: templates/prefs/columnselect.inc:247
 #: templates/prefs/addressbookselect.inc:184
 msgid "Move left"
 msgstr "Flyt til venstre"
 
-#: templates/prefs/columnselect.inc:249
 #: templates/prefs/addressbookselect.inc:186
 msgid "Move right"
 msgstr "Flyt til højre"
 
-#: data.php:61 templates/data/import.inc:16
+#: data.php:104 templates/data/import.inc:16
 msgid "Mulberry Address Book"
 msgstr "Adressekartoteket Mulberry"
 
-#: lib/api.php:1165
+#: lib/api.php:1866
 #, php-format
 msgid ""
 "Multiple persons with address [%s], but none with name [%s] already exist"
 msgstr ""
 "Flere person med adresse [%s], men ingen med navn [%s], eksisterer allerede"
 
-#: config/sources.php.dist:109 config/sources.php.dist:244
+#: config/sources.php.dist:167
 msgid "My Address Book"
 msgstr "Importér mit adressekartotek"
 
-#: addressbooks.php:125
-msgid "My Address Books"
-msgstr "Mine adressekartoteker"
-
-#: templates/addressbooks.inc:109 config/attributes.php.dist:42
+#: lib/Forms/CreateAddressBook.php:36 lib/Forms/EditAddressBook.php:43
+#: config/attributes.php.dist:47
 msgid "Name"
 msgstr "Navn"
 
@@ -746,68 +882,87 @@ msgstr "Navn"
 msgid "Name Format"
 msgstr "Navneformat"
 
-#: config/sources.php.dist:316
-msgid "Netcenter Member Directory"
-msgstr "Netcenter Member Directory"
+#: config/attributes.php.dist:71
+#, fuzzy
+msgid "Name Prefixes"
+msgstr "Forhåndsvisning af e-mail"
+
+#: config/attributes.php.dist:77
+msgid "Name Suffixes"
+msgstr ""
 
-#: add.php:36 add.php:124 lib/Block/tree_menu.php:27
+#: templates/browse/search_vbook.inc:6
+msgid "Name:"
+msgstr "Navn:"
+
+#: add.php:70 lib/Block/tree_menu.php:28
 msgid "New Contact"
 msgstr "Ny kontakt"
 
-#: edit.php:94 edit.php:101 edit.php:207 templates/data/import.inc:45
+#: templates/data/import.inc:46 lib/Forms/EditContact.php:119
+#: lib/Forms/EditContact.php:126 lib/Forms/EditContact.php:181
 msgid "Next"
 msgstr "Næste"
 
-#: config/attributes.php.dist:218
+#: config/attributes.php.dist:89
 msgid "Nickname"
 msgstr "Kaldenavn"
 
-#: lib/api.php:1248 lib/api.php:1297
+#: lib/api.php:1961 lib/api.php:2021
 #, php-format
 msgid "No %s entry found for %s"
 msgstr "Ingen %s post fundet for %s"
 
-#: data.php:50
+#: data.php:93
 msgid ""
 "No Address Books are currently available. Import and Export is disabled."
 msgstr ""
 "Ingen adressekartoteker tilgængelige. Importering og eksportering er slået "
 "fra."
 
-#: search.php:42
+#: search.php:92
 msgid "No Address Books are currently available. Searching is disabled."
 msgstr "Ingen adressekartoteker tilgængelige. Søgning er slået fra."
 
-#: lib/api.php:1216
-msgid "No address books found."
-msgstr "Intet adressekartoteket fundet."
+#: lib/api.php:731 lib/api.php:786 lib/api.php:846 lib/api.php:1031
+#: lib/api.php:1164 lib/api.php:1230
+msgid "No address book specified"
+msgstr "Intet adressekartoteket angivet."
 
-#: minisearch.php:81
+#: minisearch.php:80
 msgid "No contacts found"
 msgstr "Ingen kontakter fundet"
 
-#: templates/browse/column_headers.inc:53
+#: templates/browse/column_headers.inc:44
 msgid "No contacts match the current filter."
 msgstr "Ingen kontakter passer til de aktuelle filter."
 
-#: lib/Driver/favourites.php:91
+#: lib/ListView.php:255
+msgid "No matching contacts"
+msgstr "Ingent kontakter passer"
+
+#: lib/Driver/favourites.php:124
 msgid "No source for favourite recipients exists."
 msgstr "Der eksisterer ingen kilder af foretrukne modtagere."
 
-#: lib/api.php:534 lib/api.php:805
+#: lib/api.php:934 lib/api.php:1276
 msgid "No vCard data was found."
 msgstr "Ingen vCard-data fundet."
 
-#: templates/browse/footer.inc:7
+#: templates/list/numPager.inc:8
 msgid "None"
 msgstr "Ingen"
 
-#: lib/Views/Contact.php:26 lib/Views/DeleteContact.php:26
-#: lib/Views/EditContact.php:26
+#: lib/Views/Contact.php:49 lib/Views/DeleteContact.php:26
+#: lib/Views/EditContact.php:33
 msgid "Not Found"
 msgstr "Ikke fundet"
 
-#: config/attributes.php.dist:184
+#: deletefile.php:22 edit.php:48
+msgid "Not found"
+msgstr "Ikke fundet"
+
+#: config/attributes.php.dist:338
 msgid "Notes"
 msgstr "Noter"
 
@@ -815,11 +970,20 @@ msgstr "Noter"
 msgid "Number of items per page"
 msgstr "Antal opslag per side"
 
-#: lib/api.php:653 lib/api.php:786
+#: lib/api.php:1082 lib/api.php:1301
 msgid "Object not found"
 msgstr "Objekt ikke fundet"
 
-#: config/attributes.php.dist:223
+#: lib/Driver/kolab.php:1207
+#, php-format
+msgid "Object with UID %s does not exist!"
+msgstr "Objekt %s eksisterer ikke"
+
+#: config/attributes.php.dist:294
+msgid "Occupation"
+msgstr "Beskæftigelse"
+
+#: config/attributes.php.dist:318
 msgid "Office"
 msgstr "Kontor"
 
@@ -832,86 +996,102 @@ msgstr ""
 "Idet du gemmer denne side vil adressekartoteket bliver slettet permanent. "
 "Hvis dette ikke er, hvad du ønsker, så skal du ændre dit valg til \"Ingen\"."
 
-#: lib/api.php:813
+#: lib/api.php:1284
 msgid "Only one vcard supported."
 msgstr "Kun ét vCard er understøttet."
 
-#: config/prefs.php.dist:37
-msgid "Other Options"
-msgstr "Andre indstillinger"
+#: config/sources.php.dist:258 config/sources.php.dist:954
+msgid "Organization"
+msgstr "Organisation"
+
+#: config/sources.php.dist:259 config/sources.php.dist:956
+msgid "Other"
+msgstr "Andet"
 
-#: config/attributes.php.dist:190
+#: config/attributes.php.dist:356
 msgid "PGP Public Key"
 msgstr "Offentlig PGP-nøgle"
 
+#: config/attributes.php.dist:523
+msgid "PTT"
+msgstr ""
+
+#: config/attributes.php.dist:281
+msgid "Pager"
+msgstr "Personsøger"
+
 #: lib/Views/DeleteContact.php:57
 msgid "Permanently delete this contact?"
 msgstr "Slet denne kontakt uigenkaldeligt?"
 
-#: lib/api.php:518 lib/api.php:644 lib/api.php:731 lib/api.php:986
-#: lib/api.php:1150
-msgid "Permission Denied"
-msgstr "Tilladelse nægtet"
-
-#: lib/Driver.php:571
+#: deletefile.php:36 lib/Driver.php:809 lib/api.php:911 lib/api.php:1851
+#: lib/Driver/sql.php:517
 msgid "Permission denied"
 msgstr "Tilladelse nægtet"
 
-#: templates/addressbooks.inc:101
-msgid "Permissions"
-msgstr "Tilladelser"
+#: config/sources.php.dist:248 config/sources.php.dist:944
+msgid "Personal"
+msgstr "Personlig"
+
+#: config/attributes.php.dist:121
+msgid "Photo"
+msgstr "Foto"
+
+#: config/attributes.php.dist:127
+msgid "Photo MIME Type"
+msgstr "Foto MIME type"
 
-#: data.php:62 templates/data/import.inc:17
+#: data.php:105 templates/data/import.inc:17
 msgid "Pine Address Book"
 msgstr "Importér adressekartotek fra Pine"
 
-#: templates/browse/javascript.inc:28
+#: templates/browse/javascript.inc:27
 msgid "Please name the new contact list:"
 msgstr "Navngiv venligst den nye kontaktliste:"
 
-#: edit.php:97 edit.php:100 edit.php:199
+#: lib/Forms/EditContact.php:122 lib/Forms/EditContact.php:125
+#: lib/Forms/EditContact.php:174
 msgid "Previous"
 msgstr "Foregående"
 
-#: config/sources.php.dist:417
-msgid "Private Address Book"
-msgstr "Privat adressekartotek"
-
-#: lib/Driver/ldap.php:154
+#: lib/Driver/ldap.php:197
 #, php-format
 msgid "Query failed: (%s) %s"
 msgstr "Forespørgsel fejlede: (%s) %s"
 
-#: templates/browse/header.inc:6
-msgid "Quick Filter: "
-msgstr "Kvik-filter: "
-
-#: lib/Driver/ldap.php:198 lib/Driver/ldap.php:206 lib/Driver/ldap.php:436
+#: lib/Driver/ldap.php:242 lib/Driver/ldap.php:250 lib/Driver/ldap.php:486
 #, php-format
 msgid "Read failed: (%s) %s"
 msgstr "Læsefejl: (%s) %s"
 
-#: lib/Driver.php:1129
+#: lib/Driver.php:2111 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr "Læsning af kontakter er ikke tilgængelig."
 
-#: templates/browse/footer.inc:2
-msgid "Records displayed:"
-msgstr "Poster vist:"
+#: lib/Forms/DeleteAddressBook.php:43
+#, php-format
+msgid ""
+"Really delete the address book \"%s\"? This cannot be undone and all "
+"contacts in this address book will be permanently removed."
+msgstr ""
+"Vil du virkelig slette adressekartoteket \"%s\"? Dette kan ikke fortrydes og "
+"alle kontaktoplysninger vil blive slettet."
 
-#: templates/prefs/addressbookselect.inc:176
+#: templates/prefs/addressbookselect.inc:175
 msgid "Remove address book"
 msgstr "Fjern adressekartotek"
 
-#: templates/prefs/columnselect.inc:239
-msgid "Remove column"
-msgstr "Fjern kolonne"
-
 #: templates/browse/actions.inc:3
 msgid "Remove from this list"
 msgstr "Fejl fra denne liste"
 
-#: templates/data/import.inc:21
+#: lib/Driver.php:2149
+msgid ""
+"Removing user data is not supported in the current address book storage "
+"driver."
+msgstr "Sletning af brugerdata understøttes ikke af denne type adressebog."
+
+#: templates/data/import.inc:22
 msgid ""
 "Replace existing address book with the imported one? <strong>Warning: This "
 "deletes all entries in your current address book.</strong>"
@@ -919,47 +1099,50 @@ msgstr ""
 "Erstat eksisterende adressekartotek med den importerede? <strong>Advarsel: "
 "Dette sletter alle poster i dit nuværende adressekartotek.</strong>"
 
-#: lib/Driver.php:459
+#: lib/Driver.php:703
 msgid "Requested object not found."
 msgstr "Forespurgte objekt ikke fundet."
 
-#: add.php:37 templates/browse/search.inc:139
+#: templates/browse/search.inc:120
 msgid "Reset to Defaults"
 msgstr "Tilbage til standardindstillinger"
 
-#: config/attributes.php.dist:196
+#: config/attributes.php.dist:362
 msgid "S/MIME Public Certificate"
 msgstr "Offentlig S/MIME certifikat"
 
-#: lib/Driver/ldap.php:76
+#: config/attributes.php.dist:517
+msgid "SIP"
+msgstr "SIP"
+
+#: lib/Driver/ldap.php:84
 #, php-format
 msgid "STARTTLS failed: (%s) %s"
 msgstr "STARTTLS fejlede: (%s) %s"
 
-#: add.php:37 edit.php:105 templates/addressbooks.inc:126
-#: templates/browse/search.inc:120 templates/browse/search.inc:138
+#: lib/Forms/EditAddressBook.php:46 lib/Forms/EditContact.php:26
 msgid "Save"
 msgstr "Gem"
 
-#: templates/browse/search_vbook.inc:20
-msgid "Save search as a virtual addressbook?"
+#: templates/browse/search_vbook.inc:4
+msgid "Save search as a virtual address book?"
 msgstr "Gem søgning som et virtuelt adressekartotek?"
 
-#: lib/Driver.php:1153
+#: lib/Driver.php:2137 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr "Lagring af kontakter er ikke tilgængelig."
 
-#: templates/browse/search.inc:120 templates/browse/search.inc:138
-#: templates/block/minisearch.inc:25 lib/Block/tree_menu.php:72
-#: config/prefs.php.dist:116
+#: templates/browse/header.inc:3 templates/browse/search.inc:111
+#: templates/browse/search.inc:119 templates/block/minisearch.inc:25
+#: lib/Block/tree_menu.php:62 config/prefs.php.dist:116
 msgid "Search"
 msgstr "Søg"
 
-#: lib/api.php:1063
+#: lib/api.php:1614
 msgid "Search failed"
 msgstr "Søgning fejlede"
 
-#: lib/api.php:1155 lib/api.php:1161 lib/api.php:1170 lib/api.php:1183
+#: lib/api.php:1856 lib/api.php:1862 lib/api.php:1871 lib/api.php:1884
 #, php-format
 msgid "Search failed: %s"
 msgstr "Søgning fejlede: %s"
@@ -968,31 +1151,29 @@ msgstr "S
 msgid "Search for: "
 msgstr "Søg efter: "
 
-#: lib/Driver.php:1121
+#: lib/Driver.php:2096 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr "Søgning er ikke tilgængelig."
 
-#: templates/block/minisearch.inc:27
-msgid "Searching..."
-msgstr "Søger..."
-
-#: templates/addressbooks.inc:68
-msgid "Select an address book to delete"
-msgstr "Vælg det adressekartotek, der skal slettes"
-
-#: templates/addressbooks.inc:92
-msgid "Select an address book to edit"
-msgstr "Vælg det adressekartotek, der skal ændres"
+#: templates/browse/row.inc:52
+msgid "Select contact"
+msgstr "Vælg kontakt"
 
-#: templates/data/export.inc:32
+#: templates/data/export.inc:33
 msgid "Select the address book to export from:"
 msgstr "Vælg adressekartoteker, der skal eksporteres fra:"
 
-#: templates/data/import.inc:26
+#: templates/data/import.inc:27
 msgid "Select the address book to import to:"
 msgstr "Vælg adressekartoteket, der skal importeres til:"
 
-#: templates/data/import.inc:35
+#: config/prefs.php.dist:61
+msgid ""
+"Select the address books that should be used for synchronization with "
+"external devices:"
+msgstr ""
+
+#: templates/data/import.inc:36
 msgid "Select the charset of the source file:"
 msgstr "Vælg kildefilens tegnsæt:"
 
@@ -1000,7 +1181,7 @@ msgstr "V
 msgid "Select the export format:"
 msgstr "Vælg formatet, der skal eksporteres i:"
 
-#: templates/data/import.inc:43
+#: templates/data/import.inc:44
 msgid "Select the file to import:"
 msgstr "Vælg filen, som skal importeres:"
 
@@ -1013,8 +1194,8 @@ msgid "Select the format used to display names:"
 msgstr "Vælg formatet, som navne skal vises i:"
 
 #: config/prefs.php.dist:25
-msgid "Select view to display by default, sort options, and paging options."
-msgstr "Vælg standard visning, sortering og sideopsætning."
+msgid "Select view to display by default and paging options."
+msgstr "Vælg standard visning og sideopsætning."
 
 #: config/prefs.php.dist:18
 msgid "Select which fields to display in the address lists."
@@ -1024,81 +1205,90 @@ msgstr "V
 msgid "Select which format to display names."
 msgstr "Vælg formatet, som navne skal vises i."
 
-#: add.php:54
+#: lib/Forms/AddContact.php:42
 #, php-format
 msgid "Selected address book \"%s\"."
 msgstr "Valgt adressekartotek \"%s\"."
 
-#: config/sources.php.dist:175
-msgid "Shared Directory"
-msgstr "Delt fortegnelse"
-
-#: templates/browse/actions.inc:46
+#: templates/browse/actions.inc:49
 #, php-format
 msgid "Show %s"
 msgstr "Vis %s"
 
-#: templates/browse/actions.inc:48
-msgid "Show All"
-msgstr "Vis alle"
+#: templates/browse/actions.inc:51
+msgid "Show Both"
+msgstr "Vis begge"
 
-#: templates/browse/actions.inc:47
+#: templates/browse/actions.inc:50
 msgid "Show Contacts"
 msgstr "Vis kontakter"
 
-#: templates/browse/actions.inc:46
+#: templates/browse/actions.inc:49
 msgid "Show Lists"
 msgstr "Vis lister"
 
-#: templates/browse/column_headers.inc:21
-#: templates/browse/column_headers.inc:36
+#: lib/ListView.php:323 lib/ListView.php:329
 msgid "Sort Direction"
 msgstr "Sorteringsretning"
 
-#: lib/api.php:199
+#: templates/browse/column_headers.inc:32
+#, php-format
+msgid "Sort by %s"
+msgstr "Sortér efter %s"
+
+#: templates/browse/column_headers.inc:27
+#, php-format
+msgid "Sort by %s only"
+msgstr "Sorter kun efter %s"
+
+#: templates/browse/column_headers.inc:30
+#, php-format
+msgid "Sort by %s, then by %s"
+msgstr "Sorter efter %s, dernæst efter %s"
+
+#: templates/menu.inc:6
+msgid "Source:"
+msgstr "Kilde:"
+
+#: lib/api.php:327
 msgid "Sources"
 msgstr "Kilder"
 
-#: config/prefs.php.dist:148
-msgid "Specify where you want advanced search results to appear."
-msgstr "Angiv hvor du ønsker at avancerede søgeresultater skal dukke op."
+#: config/attributes.php.dist:109
+msgid "Spouse"
+msgstr "Ægtefælle"
 
-#: browse.php:214 browse.php:262
+#: lib/Views/Browse.php:268 lib/Views/Browse.php:308
 #, php-format
 msgid "Successfully added %d contact(s) to list."
 msgstr "%d kontakt(er) tilføjet til liste."
 
-#: browse.php:160
+#: lib/Views/Browse.php:215
 #, php-format
 msgid "Successfully added %s to %s"
 msgstr "Har tilføjet %s til %s"
 
-#: search.php:100
-#, php-format
-msgid "Successfully changed virtual address book \"%s\""
-msgstr "Virtuelt adressekartotek \"%s\" ændret."
-
-#: browse.php:248
+#: lib/Views/Browse.php:298
 #, php-format
 msgid "Successfully created the contact list \"%s\"."
 msgstr "Kontaktliste \"%s\" oprettet."
 
-#: search.php:166
+#: search.php:150
 #, php-format
 msgid "Successfully created virtual address book \"%s\""
 msgstr "Virtuelt adressekartotek \"%s\" oprettet."
 
-#: browse.php:84
+#: lib/Views/Browse.php:132
 #, php-format
 msgid "Successfully deleted %d contact(s)."
 msgstr "%d kontakt(er) slettet."
 
-#: browse.php:64
+#: lib/Views/Browse.php:115
 #, php-format
 msgid "Successfully removed %d contact(s) from list."
 msgstr "%d kontakt(er) fjernet fra liste."
 
-#: data.php:59
+#: data.php:102
 msgid "TSV"
 msgstr "TSV"
 
@@ -1106,58 +1296,80 @@ msgstr "TSV"
 msgid "Tab separated values"
 msgstr "Tabulator-separerede værdier"
 
-#: view.php:15
+#: templates/browse/actions.inc:20
+msgid "Target Address Book"
+msgstr "Mål adressekartotek"
+
+#: templates/browse/actions.inc:31
+msgid "Target Contact List"
+msgstr "Mål kontaktliste"
+
+#: data.php:426
+#, php-format
+msgid "The %s file didn't contain any contacts."
+msgstr "Filen %s indeholdt ingen kontakter."
+
+#: view.php:17
 msgid "The VFS backend needs to be configured to enable attachment uploads."
 msgstr "VFS motoren skal sættes op for at slå opsendelse af bilag til."
 
-#: lib/Driver.php:1099
+#: lib/Driver.php:2067
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr "Adressekartotek \"%s\" eksisterer ikke."
 
-#: addressbooks.php:52
+#: addressbooks/create.php:32
 #, php-format
-msgid "The address book \"%s\" was created successfully."
+msgid "The address book \"%s\" has been created."
 msgstr "Adressekartoteket \"%s\" er oprettet."
 
-#: addressbooks.php:77
+#: data.php:433
 #, php-format
-msgid "The address book \"%s\" was removed successfully."
-msgstr "Adressekartoteket \"%s\" er slettet."
+msgid "The address book could not be purged: %s"
+msgstr "Adressekartoteket kunne ikke tømmes: %s"
+
+#: lib/api.php:1102
+msgid "The address book with your own contact doesn't exist anymore."
+msgstr "Adressekartoteket med dine egne oplysninger findes ikke længere."
 
-#: addressbooks.php:94
+#: addressbooks/delete.php:50
 #, php-format
-msgid "The address book \"%s\" was successfully updated."
-msgstr "Adressekartoteket \"%s\" er opdateret."
+msgid "The addressbook \"%s\" has been deleted."
+msgstr "Adressekartoteket \"%s\" er blevet slettet."
 
-#: data.php:312
+#: addressbooks/edit.php:44
 #, php-format
-msgid "The address book could not be purged: %s"
-msgstr "Adressekartoteket kunne ikke tømmes: %s"
+msgid "The addressbook \"%s\" has been renamed to \"%s\"."
+msgstr "Adressekartoteket \"%s\" er omdøbt til \"%s\"."
+
+#: addressbooks/edit.php:46
+#, php-format
+msgid "The addressbook \"%s\" has been saved."
+msgstr "Adressekartoteket \"%s\" er gemt."
 
-#: edit.php:50 vcard.php:17 view.php:26 contact.php:22
+#: contact.php:23 vcard.php:19 view.php:28
 msgid "The contact you requested does not exist."
 msgstr "Den forespurgte kontakt findes ikke."
 
-#: edit.php:121
+#: deletefile.php:46
 #, php-format
-msgid "The file \"%s\" has successfully been deleted."
+msgid "The file \"%s\" has been deleted."
 msgstr "Filen \"%s\" er slettet."
 
-#: data.php:293
+#: data.php:406
 msgid "The import can be finished despite the warnings."
 msgstr "Importen kan gennemføres uanset advarslerne."
 
-#: lib/Views/Contact.php:36 lib/Views/DeleteContact.php:36
-#: lib/Views/EditContact.php:36
+#: lib/Views/Contact.php:59 lib/Views/DeleteContact.php:36
+#: lib/Views/EditContact.php:43
 msgid "The requested contact was not found."
 msgstr "Den anmodede kontakt kunne ikke findes."
 
-#: browse.php:31
+#: lib/Views/Browse.php:80
 msgid "There are no browseable address books."
 msgstr "Der findes ingen adressekartoteker, der kan skimmes."
 
-#: add.php:29
+#: add.php:32
 msgid ""
 "There are no writeable address books. None of the available address books "
 "are configured to allow you to add new entries to them. If you believe this "
@@ -1167,13 +1379,20 @@ msgstr ""
 "adressekartoteker er konfigureret til at tillade dig at tilføje nye poster. "
 "Hvis du mener dette er en fejl, så kontakt venligst din systemadministrator."
 
-#: search.php:162
+#: lib/Views/Browse.php:356
+#, php-format
+msgid "There is %d contact in this list that is not viewable to you"
+msgid_plural "There are %d contacts in this list that are not viewable to you"
+msgstr[0] ""
+msgstr[1] ""
+
+#: search.php:146
 #, php-format
 msgid "There was a problem creating the virtual address book: %s"
 msgstr ""
 "Der opstod en fejl under oprettelsen af det virtuelle adressekartotek: %s"
 
-#: add.php:121
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
@@ -1181,71 +1400,69 @@ msgstr ""
 "Der opstod en fejl ved tilføjelse af den nye kontakt. Kontakt din "
 "systemadministrator for yderligere hjælp."
 
-#: browse.php:271
+#: lib/Views/Browse.php:318
 msgid "There was an error creating a new list."
 msgstr "Der opstod en fejl under oprettelsen af en ny liste."
 
-#: addressbooks.php:39 addressbooks.php:42
-#, php-format
-msgid "There was an error creating this address book: %s"
-msgstr "Der opstod en fejl under oprettelsen af dette adressekartotek: %s"
-
-#: browse.php:166
+#: lib/Views/Browse.php:221
 #, php-format
 msgid "There was an error deleting \"%s\" from the source address book."
 msgstr ""
 "Der opstod en fejl under sletning af \"%s\" fra kilde-adressekartoteket."
 
-#: delete.php:37
+#: delete.php:39
 #, php-format
 msgid "There was an error deleting this contact: %s"
 msgstr "Der opstod en fejl ved fjernelse af denne kontakt: %s"
 
-#: browse.php:318
+#: lib/Views/Browse.php:362
 msgid "There was an error displaying the list"
 msgstr "Der opstod en fejl under visning af listen"
 
-#: data.php:344
+#: data.php:469
 #, php-format
 msgid "There was an error importing the data: %s"
 msgstr "Der opstod en fejl under importeringen af data: %s"
 
-#: lib/api.php:530 lib/api.php:800
+#: lib/api.php:930 lib/api.php:1271
 msgid "There was an error importing the iCalendar data."
 msgstr "Der opstod en fejl under importeringen af iCalendar data."
 
-#: addressbooks.php:64 addressbooks.php:69 addressbooks.php:75
-#, php-format
-msgid "There was an error removing this address book: %s"
-msgstr "Der opstod en fejl under sletning af dette adressekartotek: %s"
-
-#: addressbooks.php:92
+#: lib/api.php:263
 #, php-format
-msgid "There was an error updating this address book: %s"
-msgstr "Der opstod en fejl under opdatering af dette adressekatalog: %s"
+msgid "There was an error removing an address book for %s"
+msgstr "Der opstod en fejl ved sletning af adressekartoteket %s"
 
-#: edit.php:163
-#, php-format
-msgid "There was an error updating this entry: %s"
-msgstr "Der opstod en fejl under opdatering af denne post: %s"
+#: lib/Forms/EditContact.php:93
+msgid ""
+"There was an error saving the contact. Contact your system administrator for "
+"further help."
+msgstr ""
+"Der opstod en fejl ved tilføjelse af den nye kontakt. Kontakt din "
+"systemadministrator for yderligere hjælp."
 
-#: data.php:188
+#: data.php:292
 msgid "There were no addresses to export."
 msgstr "Der findes ingen adresser at eksportere."
 
+#: templates/prefs/addressbookselect.inc:178
 #: templates/prefs/addressbookselect.inc:180
 msgid "These address books will display in this order:"
 msgstr "Disse adressekartoteker vil vises i denne rækkefølge:"
 
-#: templates/prefs/columnselect.inc:243
-msgid "These columns will display in this order:"
-msgstr "Disse kolonner vil vises i denne rækkefølge:"
+#: addressbooks/delete.php:26
+msgid "This addressbook cannot be deleted"
+msgstr "Adressekartoteket kan ikke slettes."
+
+#: contact.php:57
+msgid "This contact has been marked as your own."
+msgstr "Denne adresse er markeret som din egen."
 
-#: data.php:278
+#: data.php:391
 msgid "This file format is not supported."
 msgstr "Dette filformat er ikke understøttet."
 
-#: lib/api.php:1174 lib/api.php:1187
+#: lib/api.php:1875 lib/api.php:1888
 #, php-format
 msgid "This person already has a %s entry in the address book"
 msgstr "Denne person har allerede en %s post i adressekartoteket"
@@ -1257,39 +1474,43 @@ msgstr ""
 "Dette vil være standard adressekartoteket ved tilføjelse eller import af "
 "kontakter."
 
-#: config/attributes.php.dist:70
-msgid "Title"
-msgstr "Titel"
+#: config/attributes.php.dist:241
+msgid "Time Zone"
+msgstr "Tidszone"
 
-#: lib/Turba.php:492
-#, php-format
-msgid "Unable to create new share. Missing source type."
-msgstr "Kan ikke oprette ny deling.  Mangler kildetype."
+#: lib/Driver/share.php:77
+msgid "Unable to find contact owner."
+msgstr "Kunne ikke finde kontakt-ejeren."
 
-#: lib/Driver.php:1021
+#: lib/Driver.php:1987 lib/Turba.php:662
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr "Kan ikke indlæse definitionen af %s."
 
-#: edit.php:94 edit.php:97 edit.php:100 edit.php:105 edit.php:201
-msgid "Undo Changes"
-msgstr "Fortryd ændringer"
+#: lib/Forms/EditAddressBook.php:55
+#, php-format
+msgid "Unable to save address book \"%s\": %s"
+msgstr "Kan ikke gemme adressekartoteket \"%s\": %s"
+
+#: lib/Driver/kolab.php:490
+msgid "Unable to search."
+msgstr "Kan ikke søge."
 
-#: lib/api.php:563 lib/api.php:682 lib/api.php:818
+#: config/attributes.php.dist:391
+msgid "Unfiled"
+msgstr "Ikke anbragt"
+
+#: lib/api.php:968 lib/api.php:1079 lib/api.php:1289
 #, php-format
 msgid "Unsupported Content-Type: %s"
 msgstr "Ikke-understøttet Content-Type: %s"
 
-#: config/sources.php.dist:377
-msgid "Verisign Directory"
-msgstr "Verisign-fortegnelse"
-
-#: templates/browse/row.inc:19
+#: templates/browse/contactrow.inc:27
 #, php-format
 msgid "View \"%s\""
 msgstr "Se \"%s\""
 
-#: minisearch.php:76
+#: minisearch.php:72 minisearch.php:73
 msgid "View Contact"
 msgstr "Se kontakt"
 
@@ -1297,127 +1518,181 @@ msgstr "Se kontakt"
 msgid "View to display by default:"
 msgstr "Vælg hvad du først vi se:"
 
-#: lib/Block/tree_menu.php:51
-msgid "Virtual Address Books"
-msgstr "Virtuelle adressekartoteker"
-
-#: templates/browse/search_vbook.inc:15
-msgid "Virtual Addressbooks"
-msgstr "Virtuelle adressekartoteker"
-
-#: search.php:131
-#, php-format
-msgid "Virtual address book \"%s\" deleted."
-msgstr "Virtuelt adressekartotek \"%s\" slettet."
+#: config/attributes.php.dist:512
+msgid "VoIP"
+msgstr "VoIP"
 
-#: templates/browse/search_vbook.inc:37
-msgid "Virtual address book description"
-msgstr "Beskrivelse af virtuelt adressekartotek"
-
-#: templates/browse/search_vbook.inc:29
-msgid "Virtual address book name"
-msgstr "Navn på virtuelt adressekartotek"
-
-#: config/attributes.php.dist:208
+#: config/attributes.php.dist:344
 msgid "Website URL"
 msgstr "Website URL"
 
-#: config/attributes.php.dist:113
+#: config/attributes.php.dist:185
 msgid "Work Address"
-msgstr "Adresse (arbejde)"
+msgstr "Arbejdsadresse"
+
+#: config/attributes.php.dist:576
+msgid "Work Address Extended"
+msgstr "Arbejdsadresse (udvidet)"
 
-#: config/attributes.php.dist:124
+#: config/attributes.php.dist:203
 msgid "Work City"
 msgstr "By (arbejde)"
 
-#: config/attributes.php.dist:139
+#: config/attributes.php.dist:221
 msgid "Work Country"
 msgstr "Land (arbejde)"
 
-#: config/attributes.php.dist:156
+#: config/attributes.php.dist:460
+msgid "Work Email"
+msgstr "E-post (arbejde)"
+
+#: config/attributes.php.dist:477
+msgid "Work Fax"
+msgstr "Fax (arbejde)"
+
+#: config/attributes.php.dist:582
+msgid "Work Latitude"
+msgstr "Breddegrad (arbejde)"
+
+#: config/attributes.php.dist:587
+msgid "Work Longitude"
+msgstr "Længdegrad (arbejde)"
+
+#: config/attributes.php.dist:487
+msgid "Work Mobile Phone"
+msgstr "Mobil (arbejde)"
+
+#: config/attributes.php.dist:266
 msgid "Work Phone"
 msgstr "Telefon (arbejde)"
 
-#: config/attributes.php.dist:134
+#: config/attributes.php.dist:197
+msgid "Work Post Office Box"
+msgstr "Postboks (arbejde)"
+
+#: config/attributes.php.dist:215
 msgid "Work Postal Code"
 msgstr "Postnummer (arbejde)"
 
-#: config/attributes.php.dist:129
+#: config/attributes.php.dist:209
 msgid "Work State/Province"
 msgstr "Region (arbejde)"
 
-#: config/attributes.php.dist:119
+#: config/attributes.php.dist:191
 msgid "Work Street Address"
 msgstr "Adresse (arbejde)"
 
-#: add.php:73 browse.php:106 browse.php:227 data.php:246
+#: config/attributes.php.dist:502
+msgid "Work Video Call"
+msgstr "Arbejdsvideokald"
+
+#: config/attributes.php.dist:570
+msgid "Work Website URL"
+msgstr "Hjemmeside (arbejde)"
+
+#: addressbooks/edit.php:30
+msgid "You are not allowed to change this addressbook."
+msgstr "Du har ikke tilladelse til at ændre dette adressekartotek."
+
+#: add.php:48 data.php:355 lib/Views/Browse.php:159 lib/Views/Browse.php:281
 #, php-format
 msgid "You are not allowed to create more than %d contacts in \"%s\"."
 msgstr "Du har ikke tilladelse til at danne flere end %d kontakter i \"%s\"."
 
-#: lib/Driver/vbook.php:116
+#: addressbooks/delete.php:37
+msgid "You are not allowed to delete this addressbook."
+msgstr "Du har ikke tilladelse til at slette dette adressekartotek."
+
+#: lib/api.php:209
+msgid "You are not allowed to remove user data."
+msgstr "Du har ikke tilladelse til at fjerne brugeroplysninger."
+
+#: lib/Driver/vbook.php:137
 msgid "You cannot add an entry to a virtual address book."
 msgstr "Du kan ikke tilføje en indgang til et virtuelt adressekartotek."
 
-#: lib/Driver/vbook.php:100
+#: lib/Driver/vbook.php:121
 msgid "You cannot add new contacts to a virtual address book"
 msgstr "Du kan ikke tilføje nye kontakter til et virtuelt adressekartoteket"
 
-#: lib/Driver/vbook.php:108
+#: lib/Driver/vbook.php:129
 msgid "You cannot delete contacts from a virtual address book"
 msgstr "Du kan ikke slette kontakter fra et virtuelt adressekartotek"
 
-#: edit.php:72 view.php:36 lib/Views/DeleteContact.php:42
-#: lib/Views/EditContact.php:42
+#: lib/api.php:1097
+msgid "You didn't mark a contact as your own yet."
+msgstr "Du har ikke markeret en kontakt som dig selv endnu."
+
+#: edit.php:66 view.php:38 lib/Views/DeleteContact.php:42
+#: lib/Views/EditContact.php:49
 msgid "You do not have permission to view this contact."
 msgstr "Du har ikke tilladelse til at se denne kontaktliste."
 
-#: vcard.php:35
+#: vcard.php:37
 msgid "You do not have permission to view this object."
 msgstr "Du har ikke tilladelse til at se dette objekt."
 
-#: lib/Turba.php:579
-msgid "You do not have permissions to delete this source."
-msgstr "Du har ikke tilladelse til at slette denne kilde."
+#: lib/Forms/DeleteAddressBook.php:59
+msgid "You do not have permissions to delete this address book."
+msgstr "Du har ikke tilladelse til at slette denne adressebog."
+
+#: lib/api.php:1111
+msgid ""
+"You don't have sufficient permissions to read the address book that contains "
+"your own contact."
+msgstr ""
+"Du har ikke tilladelse til at se adressekartoteket med dine egne "
+"kontaktoplysninger."
+
+#: lib/Driver/ldap.php:741
+msgid ""
+"You must have the Net_LDAP PEAR library installed to use the schema check "
+"function."
+msgstr ""
 
-#: search.php:148
+#: search.php:133
 msgid "You must provide a name for virtual address books."
 msgstr "Du skal angive et navn til virtuelle adressekartoteker."
 
-#: templates/browse/javascript.inc:55
+#: templates/browse/javascript.inc:54
 msgid "You must select a target address book."
 msgstr "Du skal vælge destinations-adressekartoteket."
 
-#: templates/browse/javascript.inc:23
-msgid "You must select a target list."
+#: templates/browse/javascript.inc:22
+msgid "You must select a target contact list."
 msgstr "Du skal vælge destinationslisten."
 
-#: edit.php:31
+#: edit.php:31 templates/browse/javascript.inc:16
+#: templates/browse/javascript.inc:48 templates/browse/javascript.inc:71
 msgid "You must select at least one contact first."
 msgstr "Først skal du vælge mindst en kontakt."
 
-#: templates/browse/javascript.inc:17 templates/browse/javascript.inc:49
-#: templates/browse/javascript.inc:72
-msgid "You must select at least one entry first."
-msgstr "Først skal du vælge mindst én post."
-
-#: edit.php:76 lib/Views/DeleteContact.php:45 lib/Views/EditContact.php:45
+#: edit.php:70 lib/Views/DeleteContact.php:45 lib/Views/EditContact.php:52
 msgid "You only have permission to view this contact."
 msgstr "Du har kun tilladelse til at se denne kontakt."
 
-#: browse.php:325
+#: lib/Views/Browse.php:369
 msgid "Your default address book is not browseable."
 msgstr "Dit standard adressekartotek er ikke skimbar."
 
-#: templates/browse/row.inc:6
+#: contact.php:101 contact.php:102 templates/browse/row.inc:14
+#: templates/browse/row.inc:15
+msgid "Your own contact"
+msgstr "Din egen adresse"
+
+#: lib/api.php:1116
+msgid "Your own contact cannot be found in the address book."
+msgstr "Dine egne kontaktoplysninger findes ikke i kartoteket."
+
+#: templates/browse/contactrow.inc:12
 msgid "[no value]"
 msgstr "[ingen værdi]"
 
-#: lib/Turba.php:602
+#: lib/Turba.php:604
 msgid "_Browse"
 msgstr "Skim"
 
-#: templates/browse/actions.inc:47
+#: templates/browse/actions.inc:50
 msgid "_Contacts"
 msgstr "Kontakter"
 
@@ -1425,50 +1700,92 @@ msgstr "Kontakter"
 msgid "_Delete"
 msgstr "Slet"
 
-#: contact.php:79
+#: contact.php:91
 msgid "_Edit"
 msgstr "Redigér"
 
-#: lib/Turba.php:611
+#: lib/Turba.php:613
 msgid "_Import/Export"
 msgstr "Import/Eksport"
 
-#: templates/browse/actions.inc:46
+#: templates/browse/actions.inc:49
 msgid "_Lists"
 msgstr "Lister"
 
-#: lib/Turba.php:599
+#: lib/Turba.php:601
 msgid "_My Address Books"
 msgstr "Mine adressekartoteker"
 
-#: lib/Turba.php:605
+#: lib/Turba.php:607
 msgid "_New Contact"
 msgstr "Ny kontakt"
 
+#: lib/Turba.php:618
+msgid "_Print"
+msgstr "Udskriv"
+
 #: templates/browse/actions.inc:3
 msgid "_Remove from this list"
 msgstr "Fjern fra denne liste"
 
-#: lib/Turba.php:607
+#: lib/Turba.php:609
 msgid "_Search"
 msgstr "Søg"
 
-#: vcard.php:43
+#: contact.php:88
+msgid "_View"
+msgstr "_Se"
+
+#: templates/browse/column_headers.inc:25
+msgid "ascending"
+msgstr "Stigende"
+
+#: lib/Views/Contact.php:76 lib/Views/Contact.php:87
+#, php-format
+msgid "by %s"
+msgstr "af %s"
+
+#: lib/Views/Contact.php:78 lib/Views/Contact.php:89
+msgid "by me"
+msgstr "af mig"
+
+#: vcard.php:45
 msgid "contact"
 msgstr "kontakt"
 
-#: data.php:208 data.php:213 templates/data/export.inc:1
+#: data.php:312 data.php:317 templates/data/export.inc:1
 msgid "contacts.csv"
 msgstr "contacts.csv"
 
-#: data.php:218
+#: data.php:337
+msgid "contacts.ldif"
+msgstr "contacts.ldif"
+
+#: data.php:322
 msgid "contacts.tsv"
 msgstr "contacts.tsv"
 
-#: data.php:228
+#: data.php:332
 msgid "contacts.vcf"
 msgstr "contacts.vcf"
 
+#: templates/browse/column_headers.inc:25
+msgid "descending"
+msgstr "Faldende"
+
+#: config/attributes.php.dist:439
+msgid "female"
+msgstr "kvinde"
+
+#: lib/Block/tree_menu.php:38
+#, php-format
+msgid "in %s"
+msgstr "i %s"
+
+#: config/attributes.php.dist:439
+msgid "male"
+msgstr "mand"
+
 #: config/prefs.php.dist:128
 msgid "no formatting"
 msgstr "ingen formattering"
@@ -1477,15 +1794,15 @@ msgstr "ingen formattering"
 msgid "none"
 msgstr "ingen"
 
-#: templates/browse/actions.inc:31
+#: templates/browse/actions.inc:33
 msgid "to a Contact List"
 msgstr "til en kontaktliste"
 
-#: templates/browse/actions.inc:21
+#: templates/browse/actions.inc:22
 msgid "to a different Address Book"
 msgstr "til et andet adressekartotek"
 
-#: data.php:60 templates/data/export.inc:15 templates/data/import.inc:15
-#: templates/browse/column_headers.inc:13
+#: data.php:103 templates/browse/column_headers.inc:14
+#: templates/data/export.inc:15 templates/data/import.inc:15
 msgid "vCard"
 msgstr "vCard"
diff --git a/po/de_DE.po b/po/de_DE.po
index 126ac3f..3d5d14f 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -1,14 +1,14 @@
 # German translations for Turba.
-# Copyright (C) 2001-2008 Horde Project
+# Copyright 2001-2009 The Horde Project
 # This file is distributed under the same license as the Turba package.
-# Jan Schneider <jan at horde.org>, 2001-2008.
+# Jan Schneider <jan at horde.org>, 2001-2009.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Turba 2.2-cvs\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2008-09-25 12:32+0200\n"
-"PO-Revision-Date: 2008-09-06 12:20+0200\n"
+"POT-Creation-Date: 2009-09-12 10:09+0200\n"
+"PO-Revision-Date: 2009-03-19 11:16+0100\n"
 "Last-Translator: Jan Schneider <jan at horde.org>\n"
 "Language-Team: German <i18n at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
@@ -59,12 +59,12 @@ msgstr "\"Vorname Nachname\" (z.B. Max Mustermann)"
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr "\"Nachname, Vorname\" (z.B. Mustermann, Max)"
 
-#: lib/Driver.php:619
+#: lib/Driver.php:632
 #, php-format
 msgid "%d. %s of %s"
 msgstr "%d. %s von %s"
 
-#: lib/Forms/AddContact.php:88
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr "%s hinzugefügt."
@@ -79,7 +79,7 @@ msgstr "Die %s-Datei wurde erfolgreich importiert."
 msgid "%s to %s of %s"
 msgstr "%s bis %s von %s"
 
-#: lib/Turba.php:541
+#: lib/Turba.php:542
 #, php-format
 msgid "%s's Address Book"
 msgstr "Adressbuch von %s"
@@ -113,11 +113,11 @@ msgstr "Datei hinzuf
 msgid "Add to"
 msgstr "Hinzufügen zu"
 
-#: lib/Driver.php:2113 lib/Driver/null.php:57
+#: lib/Driver.php:2135 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr "Hinzufügen von Kontakten nicht unterstützt."
 
-#: templates/addressbook_list.php:16
+#: templates/addressbook_list.php:16 templates/browse/search.inc:125
 msgid "Address Book"
 msgstr "Adressbuch"
 
@@ -154,7 +154,7 @@ msgstr "Spitzname"
 msgid "All"
 msgstr "Alle"
 
-#: lib/api.php:941
+#: lib/api.php:983
 msgid "Already Exists"
 msgstr "Existiert bereits"
 
@@ -175,7 +175,7 @@ msgstr "Sind Sie sicher, dass Sie %s l
 msgid "Are you sure that you want to delete the selected contacts?"
 msgstr "Sind Sie sicher, dass Sie die ausgewählten Kontakte löschen möchten?"
 
-#: config/attributes.php.dist:424
+#: config/attributes.php.dist:430
 msgid "Assistant"
 msgstr "Assistent"
 
@@ -183,7 +183,7 @@ msgstr "Assistent"
 msgid "Basic Search"
 msgstr "Einfache Suche"
 
-#: lib/Driver/ldap.php:92 lib/Driver/ldap.php:95
+#: lib/Driver/ldap.php:97 lib/Driver/ldap.php:100
 #, php-format
 msgid "Bind failed: (%s) %s"
 msgstr "Verbindung fehlgeschlagen: (%s) %s"
@@ -298,43 +298,43 @@ msgstr "Kommagetrennte Werte"
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr "Kommagetrennte Werte (Microsoft Outlook)"
 
-#: config/attributes.php.dist:522
+#: config/attributes.php.dist:528
 msgid "Common Address Extended"
 msgstr "Erweiterte Adresse allgemein"
 
-#: config/attributes.php.dist:540
+#: config/attributes.php.dist:546
 msgid "Common City"
 msgstr "Stadt allgemein"
 
-#: config/attributes.php.dist:558
+#: config/attributes.php.dist:564
 msgid "Common Country"
 msgstr "Land allgemein"
 
-#: config/attributes.php.dist:466
+#: config/attributes.php.dist:472
 msgid "Common Phone"
 msgstr "Telefon allgemein"
 
-#: config/attributes.php.dist:534
+#: config/attributes.php.dist:540
 msgid "Common Post Office Box"
 msgstr "Postfach allgemein"
 
-#: config/attributes.php.dist:552
+#: config/attributes.php.dist:558
 msgid "Common Postal Code"
 msgstr "Postleitzahl allgemein"
 
-#: config/attributes.php.dist:546
+#: config/attributes.php.dist:552
 msgid "Common State/Province"
 msgstr "Bundesstaat oder Provinz allgemein"
 
-#: config/attributes.php.dist:528
+#: config/attributes.php.dist:534
 msgid "Common Street"
 msgstr "Straße allgemein"
 
-#: config/attributes.php.dist:491
+#: config/attributes.php.dist:497
 msgid "Common Video Call"
 msgstr "Bildtelefon allgemein"
 
-#: config/sources.php.dist:256 config/sources.php.dist:948
+#: config/sources.php.dist:286 config/sources.php.dist:1013
 msgid "Communications"
 msgstr "Kommunikation"
 
@@ -346,11 +346,12 @@ msgstr "Firma"
 msgid "Company Address"
 msgstr "Firmenadresse"
 
-#: scripts/import_squirrelmail_abook.php:112 lib/api.php:546 lib/api.php:600
-#: lib/api.php:653 lib/api.php:701 lib/api.php:756 lib/api.php:815
-#: lib/api.php:866 lib/api.php:1004 lib/api.php:1066 lib/api.php:1137
-#: lib/api.php:1204 lib/api.php:1324 lib/api.php:1563 lib/api.php:1640
-#: lib/api.php:1791
+#: scripts/import_squirrelmail_sql_abook.php:125
+#: scripts/import_squirrelmail_file_abook.php:114 lib/api.php:587
+#: lib/api.php:641 lib/api.php:694 lib/api.php:742 lib/api.php:797
+#: lib/api.php:857 lib/api.php:908 lib/api.php:1046 lib/api.php:1108
+#: lib/api.php:1179 lib/api.php:1246 lib/api.php:1366 lib/api.php:1610
+#: lib/api.php:1696 lib/api.php:1848
 #, php-format
 msgid "Connection failed: %s"
 msgstr "Verbindung fehlgeschlagen: %s"
@@ -363,7 +364,7 @@ msgstr "Verbindung fehlgeschlagen"
 msgid "Contact Search"
 msgstr "Kontaktsuche"
 
-#: config/sources.php.dist:866
+#: config/sources.php.dist:929
 msgid "Contacts"
 msgstr "Kontakte"
 
@@ -415,16 +416,16 @@ msgstr "L
 msgid "Delete %s"
 msgstr "%s löschen"
 
-#: lib/api.php:644
+#: lib/api.php:685
 msgid "Delete denied."
 msgstr "Löschen nicht erlaubt."
 
-#: lib/Driver/ldap.php:321
+#: lib/Driver/ldap.php:326
 #, php-format
 msgid "Delete failed: (%s) %s"
 msgstr "Löschen fehlgeschlagen: (%s) %s"
 
-#: lib/Driver.php:2121 lib/Driver/null.php:62
+#: lib/Driver.php:2143 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr "Löschen von Kontakten nicht unterstützt."
 
@@ -440,10 +441,6 @@ msgstr "Abteilung"
 msgid "Description"
 msgstr "Beschreibung"
 
-#: templates/browse/search.inc:125
-msgid "Directory"
-msgstr "Verzeichnis"
-
 #: config/prefs.php.dist:24
 msgid "Display"
 msgstr "Anzeige"
@@ -453,7 +450,7 @@ msgstr "Anzeige"
 msgid "Display Options"
 msgstr "Anzeige-Einstellungen"
 
-#: lib/Object.php:354
+#: lib/Object.php:360
 msgid "Download"
 msgstr "Herunterladen"
 
@@ -517,7 +514,7 @@ msgstr "Fehler beim Entfernen von %d Kontakten aus der Liste."
 msgid "Error removing %d of %d requested contact(s) from list."
 msgstr "Fehler beim Entfernen von %d von %d Kontakten aus der Liste."
 
-#: lib/api.php:707
+#: lib/api.php:748
 #, php-format
 msgid "Error searching the address book: %s"
 msgstr "Das Adressbuch konnte nicht durchsucht werden: %s"
@@ -557,7 +554,7 @@ msgstr "Die Liste konnte nicht angezeigt werden"
 msgid "Failed to browse the directory"
 msgstr "Das Verzeichnis konnte nicht angezeigt werden"
 
-#: lib/Driver/ldap.php:354
+#: lib/Driver/ldap.php:359
 #, php-format
 msgid "Failed to change name: (%s) %s; Old DN = %s, New DN = %s, Root = %s"
 msgstr ""
@@ -579,7 +576,7 @@ msgstr "Das Adressbuch konnte nicht durchsucht werden"
 msgid "Failed to search the directory: %s"
 msgstr "Das Verzeichnis %s konnte nicht durchsucht werden."
 
-#: config/sources.php.dist:565
+#: config/sources.php.dist:626
 msgid "Favourite Recipients"
 msgstr "Häufigste Empfänger"
 
@@ -611,11 +608,11 @@ msgstr "Frei-/Gebucht-URL"
 msgid "From"
 msgstr "Von"
 
-#: config/attributes.php.dist:430
+#: config/attributes.php.dist:436
 msgid "Gender"
 msgstr "Geschlecht"
 
-#: config/sources.php.dist:791
+#: config/sources.php.dist:852
 msgid "Global Address Book"
 msgstr "Allgemeines Adressbuch"
 
@@ -627,7 +624,7 @@ msgstr "Gruppe"
 msgid "Home Address"
 msgstr "Adresse privat"
 
-#: config/attributes.php.dist:592
+#: config/attributes.php.dist:598
 msgid "Home Address Extended"
 msgstr "Erweiterte Adresse privat"
 
@@ -639,23 +636,23 @@ msgstr "Stadt privat"
 msgid "Home Country"
 msgstr "Land privat"
 
-#: config/attributes.php.dist:460
+#: config/attributes.php.dist:466
 msgid "Home Email"
 msgstr "E-Mail-Adresse privat"
 
-#: config/attributes.php.dist:476
+#: config/attributes.php.dist:482
 msgid "Home Fax"
 msgstr "Fax privat"
 
-#: config/attributes.php.dist:598
+#: config/attributes.php.dist:604
 msgid "Home Latitude"
 msgstr "Breitengrad privat"
 
-#: config/attributes.php.dist:603
+#: config/attributes.php.dist:609
 msgid "Home Longitude"
 msgstr "Längengrad privat"
 
-#: config/attributes.php.dist:486
+#: config/attributes.php.dist:492
 msgid "Home Mobile Phone"
 msgstr "Telefon mobil privat"
 
@@ -679,15 +676,15 @@ msgstr "Bundesstaat oder Provinz privat"
 msgid "Home Street Address"
 msgstr "Straße privat"
 
-#: config/attributes.php.dist:501
+#: config/attributes.php.dist:507
 msgid "Home Video Call"
 msgstr "Bildtelefon privat"
 
-#: config/attributes.php.dist:586
+#: config/attributes.php.dist:592
 msgid "Home Website URL"
 msgstr "Website-URL privat"
 
-#: config/sources.php.dist:682
+#: config/sources.php.dist:743
 msgid "IMSP"
 msgstr "IMSP"
 
@@ -700,42 +697,43 @@ msgstr "Adressbuch importieren, Schritt %d"
 msgid "Import/Export Address Books"
 msgstr "Adressbücher Import/Export"
 
-#: config/attributes.php.dist:406
+#: config/attributes.php.dist:412
 msgid "Initials"
 msgstr "Initialien"
 
-#: config/attributes.php.dist:412
+#: config/attributes.php.dist:418
 msgid "Instant Messenger"
 msgstr "Instant Messenger"
 
-#: lib/api.php:999 lib/api.php:1132
+#: lib/api.php:1041 lib/api.php:1174
 msgid "Invalid ID"
 msgstr "Ungültige ID"
 
-#: scripts/import_squirrelmail_abook.php:105 lib/api.php:368 lib/api.php:696
-#: lib/api.php:751 lib/api.php:810 lib/api.php:859 lib/api.php:995
-#: lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
+#: scripts/import_squirrelmail_sql_abook.php:118
+#: scripts/import_squirrelmail_file_abook.php:107 lib/api.php:373
+#: lib/api.php:737 lib/api.php:792 lib/api.php:852 lib/api.php:901
+#: lib/api.php:1037 lib/api.php:1170 lib/api.php:1236 lib/api.php:1831
 #, php-format
 msgid "Invalid address book: %s"
 msgstr "Ungültiges Adressbuch: %s"
 
-#: lib/api.php:1198
+#: lib/api.php:1240
 msgid "Invalid contact unique ID"
 msgstr "Ungültige eindeutige Kontakt-ID"
 
-#: lib/api.php:1778 lib/api.php:1864 lib/api.php:1925
+#: lib/api.php:1835 lib/api.php:1921 lib/api.php:1982
 msgid "Invalid email"
 msgstr "Ungültige E-Mail-Adresse"
 
-#: lib/api.php:1786
+#: lib/api.php:1843
 msgid "Invalid entry"
 msgstr "Ungültiger Eintrag"
 
-#: lib/Driver/ldap.php:317
+#: lib/Driver/ldap.php:322
 msgid "Invalid key specified."
 msgstr "Ungültiger Schlüssel angegeben."
 
-#: lib/api.php:1782
+#: lib/api.php:1839
 msgid "Invalid name"
 msgstr "Ungültiger Name"
 
@@ -743,10 +741,9 @@ msgstr "Ung
 msgid "Job Title"
 msgstr "Position"
 
-#: lib/Driver/kolab.php:1129 lib/Driver/kolab.php:1195
-#, php-format
-msgid "Key for saving must be a UID not %s!"
-msgstr "Der Schlüssel fürs Speichern muss eine UID sein, kein(e) %s!"
+#: config/attributes.php.dist:406
+msgid "Kolab Home Server"
+msgstr "Kolab-Home-Server"
 
 #: lib/Driver/ldap.php:64
 msgid ""
@@ -759,7 +756,7 @@ msgstr ""
 msgid "LDIF Address Book"
 msgstr "LDIF-Adressbuch"
 
-#: config/attributes.php.dist:436
+#: config/attributes.php.dist:442
 msgid "Language"
 msgstr "Sprache"
 
@@ -771,7 +768,7 @@ msgstr "Letzte 
 msgid "Last Name"
 msgstr "Nachname"
 
-#: config/attributes.php.dist:442
+#: config/attributes.php.dist:448
 msgid "Latitude"
 msgstr "Breitengrad"
 
@@ -779,7 +776,7 @@ msgstr "Breitengrad"
 msgid "List"
 msgstr "Liste"
 
-#: config/sources.php.dist:251 config/sources.php.dist:944
+#: config/sources.php.dist:281 config/sources.php.dist:1009
 msgid "Location"
 msgstr "Ort"
 
@@ -791,11 +788,11 @@ msgstr "Logo"
 msgid "Logo MIME Type"
 msgstr "Logo-Dateityp"
 
-#: config/attributes.php.dist:447
+#: config/attributes.php.dist:453
 msgid "Longitude"
 msgstr "Längengrad"
 
-#: lib/api.php:616
+#: lib/api.php:657
 msgid "Malformed request."
 msgstr "Ungültige Anfrage."
 
@@ -803,7 +800,7 @@ msgstr "Ung
 msgid "Manage Address Books"
 msgstr "Adressbücher-Verwaltung"
 
-#: config/attributes.php.dist:418
+#: config/attributes.php.dist:424
 msgid "Manager"
 msgstr "Vorgesetzter"
 
@@ -815,7 +812,7 @@ msgstr "Diesen Kontakt als Ihre Visitenkarte markieren"
 msgid "Matching"
 msgstr "nach"
 
-#: lib/api.php:329
+#: lib/api.php:334
 msgid "Maximum Number of Contacts"
 msgstr "Maximale Anzahl an Kontakten"
 
@@ -831,7 +828,7 @@ msgstr "Men
 msgid "Middle Names"
 msgstr "Weitere Namen"
 
-#: lib/Driver/ldap.php:347
+#: lib/Driver/ldap.php:352
 msgid "Missing DN in LDAP source configuration."
 msgstr "DN fehlt in der LDAP-Konfiguration."
 
@@ -839,7 +836,7 @@ msgstr "DN fehlt in der LDAP-Konfiguration."
 msgid "Mobile Phone"
 msgstr "Telefon mobil"
 
-#: lib/Driver/ldap.php:376 lib/Driver/ldap.php:392
+#: lib/Driver/ldap.php:381 lib/Driver/ldap.php:397
 #, php-format
 msgid "Modify failed: (%s) %s"
 msgstr "Änderung fehlgeschlagen: (%s) %s"
@@ -848,7 +845,7 @@ msgstr "
 msgid "More Options..."
 msgstr "Weitere Optionen..."
 
-#: lib/api.php:1902
+#: lib/api.php:1959
 msgid "More than 1 entry found"
 msgstr "Mehr als 1 Eintrag zurückgeliefert"
 
@@ -868,7 +865,7 @@ msgstr "Nach rechts"
 msgid "Mulberry Address Book"
 msgstr "Mulberry-Adressbuch"
 
-#: lib/api.php:1810
+#: lib/api.php:1867
 #, php-format
 msgid ""
 "Multiple persons with address [%s], but none with name [%s] already exist"
@@ -876,7 +873,7 @@ msgstr ""
 "Mehrere Personen mit der Adresse [%s], aber keine mit dem Namen [%s] im "
 "Adressbuch"
 
-#: config/sources.php.dist:167
+#: config/sources.php.dist:197
 msgid "My Address Book"
 msgstr "Mein Adressbuch"
 
@@ -914,7 +911,7 @@ msgstr "Weiter"
 msgid "Nickname"
 msgstr "Spitzname"
 
-#: lib/api.php:1905 lib/api.php:1965
+#: lib/api.php:1962 lib/api.php:2022
 #, php-format
 msgid "No %s entry found for %s"
 msgstr "Es wurde kein %s Eintrag für %s gefunden"
@@ -932,8 +929,8 @@ msgstr ""
 "Zur Zeit sind keine Adressbücher verfügbar. Die Suche steht nicht zur "
 "Verfügung."
 
-#: lib/api.php:690 lib/api.php:745 lib/api.php:805 lib/api.php:990
-#: lib/api.php:1123 lib/api.php:1189
+#: lib/api.php:731 lib/api.php:786 lib/api.php:846 lib/api.php:1032
+#: lib/api.php:1165 lib/api.php:1231
 msgid "No address book specified"
 msgstr "Kein Adressbuch angegeben"
 
@@ -953,7 +950,7 @@ msgstr "Keine passende Kontakte"
 msgid "No source for favourite recipients exists."
 msgstr "Es existiert keine Quelle für häufigste Empfänger."
 
-#: lib/api.php:893 lib/api.php:1235
+#: lib/api.php:935 lib/api.php:1277
 msgid "No vCard data was found."
 msgstr "Es wurden keine vCard-Daten gefunden."
 
@@ -978,11 +975,11 @@ msgstr "Bemerkungen"
 msgid "Number of items per page"
 msgstr "Anzahl der Einträge pro Seite"
 
-#: lib/api.php:1041 lib/api.php:1260
+#: lib/api.php:1083 lib/api.php:1302
 msgid "Object not found"
 msgstr "Objekt nicht gefunden"
 
-#: lib/Driver/kolab.php:1199
+#: lib/Driver/kolab.php:1207
 #, php-format
 msgid "Object with UID %s does not exist!"
 msgstr "Objekt mit der UID %s existiert nicht!"
@@ -1005,15 +1002,15 @@ msgstr ""
 "endgültig gelöscht. Wenn Sie das nicht möchten, ändern Sie Ihre Auswahl auf "
 "\"kein\"."
 
-#: lib/api.php:1243
+#: lib/api.php:1285
 msgid "Only one vcard supported."
 msgstr "Nur einzelne vCards werden unterstützt."
 
-#: config/sources.php.dist:258 config/sources.php.dist:950
+#: config/sources.php.dist:288 config/sources.php.dist:1015
 msgid "Organization"
 msgstr "Firma"
 
-#: config/sources.php.dist:259 config/sources.php.dist:952
+#: config/sources.php.dist:289 config/sources.php.dist:1017
 msgid "Other"
 msgstr "Sonstige"
 
@@ -1021,7 +1018,7 @@ msgstr "Sonstige"
 msgid "PGP Public Key"
 msgstr "Öffentlicher PGP-Schlüssel"
 
-#: config/attributes.php.dist:517
+#: config/attributes.php.dist:523
 msgid "PTT"
 msgstr "PTT"
 
@@ -1033,12 +1030,12 @@ msgstr "Pager"
 msgid "Permanently delete this contact?"
 msgstr "Diesen Kontakt unwiederbringlich löschen?"
 
-#: deletefile.php:36 lib/Driver.php:804 lib/api.php:870 lib/api.php:1795
-#: lib/Driver/sql.php:515
+#: deletefile.php:36 lib/Driver.php:817 lib/api.php:912 lib/api.php:1852
+#: lib/Driver/sql.php:521
 msgid "Permission denied"
 msgstr "Zugriff verweigert"
 
-#: config/sources.php.dist:248 config/sources.php.dist:940
+#: config/sources.php.dist:278 config/sources.php.dist:1005
 msgid "Personal"
 msgstr "Persönlich"
 
@@ -1063,17 +1060,17 @@ msgstr "Bitte einen Namen f
 msgid "Previous"
 msgstr "Zurück"
 
-#: lib/Driver/ldap.php:197
+#: lib/Driver/ldap.php:202
 #, php-format
 msgid "Query failed: (%s) %s"
 msgstr "Abfrage fehlgeschlagen: (%s) %s"
 
-#: lib/Driver/ldap.php:242 lib/Driver/ldap.php:250 lib/Driver/ldap.php:486
+#: lib/Driver/ldap.php:247 lib/Driver/ldap.php:255 lib/Driver/ldap.php:491
 #, php-format
 msgid "Read failed: (%s) %s"
 msgstr "Lesen fehlgeschlagen: (%s) %s"
 
-#: lib/Driver.php:2105 lib/Driver/null.php:52
+#: lib/Driver.php:2127 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr "Anzeigen von Kontakten nicht unterstützt."
 
@@ -1095,7 +1092,7 @@ msgstr "Adressbuch entfernen"
 msgid "Remove from this list"
 msgstr "Aus dieser Liste entfernen"
 
-#: lib/Driver.php:2143
+#: lib/Driver.php:2165
 msgid ""
 "Removing user data is not supported in the current address book storage "
 "driver."
@@ -1111,7 +1108,7 @@ msgstr ""
 "Existierendes Adressbuch mit dem importierten ersetzen? <strong>Warnung: "
 "Damit werden alle aktuellen Einträge in dem Adressbuch gelöscht.</strong>"
 
-#: lib/Driver.php:698
+#: lib/Driver.php:711
 msgid "Requested object not found."
 msgstr "Gewünschtes Objekt nicht gefunden."
 
@@ -1123,11 +1120,11 @@ msgstr "Zur
 msgid "S/MIME Public Certificate"
 msgstr "Öffentliches S/MIME-Zertifikat"
 
-#: config/attributes.php.dist:511
+#: config/attributes.php.dist:517
 msgid "SIP"
 msgstr "SIP"
 
-#: lib/Driver/ldap.php:84
+#: lib/Driver/ldap.php:89
 #, php-format
 msgid "STARTTLS failed: (%s) %s"
 msgstr "STARTTLS fehlgeschlagen: (%s) %s"
@@ -1140,7 +1137,7 @@ msgstr "Speichern"
 msgid "Save search as a virtual address book?"
 msgstr "Suche als Virtuelles Adressbuch speichern?"
 
-#: lib/Driver.php:2131 lib/Driver/null.php:67
+#: lib/Driver.php:2153 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr "Speichern von Kontakten nicht unterstützt."
 
@@ -1150,11 +1147,11 @@ msgstr "Speichern von Kontakten nicht unterst
 msgid "Search"
 msgstr "Suche"
 
-#: lib/api.php:1568
+#: lib/api.php:1615
 msgid "Search failed"
 msgstr "Suche fehlgeschlagen"
 
-#: lib/api.php:1800 lib/api.php:1806 lib/api.php:1815 lib/api.php:1828
+#: lib/api.php:1857 lib/api.php:1863 lib/api.php:1872 lib/api.php:1885
 #, php-format
 msgid "Search failed: %s"
 msgstr "Suche fehlgeschlagen: %s"
@@ -1163,7 +1160,7 @@ msgstr "Suche fehlgeschlagen: %s"
 msgid "Search for: "
 msgstr "Suchen nach: "
 
-#: lib/Driver.php:2090 lib/Driver/null.php:47
+#: lib/Driver.php:2112 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr "Suchen von Kontakten nicht unterstützt."
 
@@ -1265,7 +1262,7 @@ msgstr "Sortieren nach %s, dann nach %s"
 msgid "Source:"
 msgstr "Quelle:"
 
-#: lib/api.php:322
+#: lib/api.php:327
 msgid "Sources"
 msgstr "Quellen"
 
@@ -1330,7 +1327,7 @@ msgstr ""
 "Das VFS-Backend muss konfiguriert sein, um das Hochladen von Dateien zu "
 "erlauben."
 
-#: lib/Driver.php:2061
+#: lib/Driver.php:2083
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr "Das Adressbuch \"%s\" existiert nicht."
@@ -1345,7 +1342,7 @@ msgstr "Das Adressbuch \"%s\" wurde erzeugt."
 msgid "The address book could not be purged: %s"
 msgstr "Das Adressbuch konnte nicht geleert werden: %s"
 
-#: lib/api.php:1061
+#: lib/api.php:1103
 msgid "The address book with your own contact doesn't exist anymore."
 msgstr "Das Adressbuch mit Ihrer Visitenkarte existiert nicht mehr."
 
@@ -1412,7 +1409,7 @@ msgid "There was a problem creating the virtual address book: %s"
 msgstr ""
 "Beim Erstellen des Virtuellen Adressbuchs ist ein Fehler aufgetreten: %s"
 
-#: lib/Forms/AddContact.php:95
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
@@ -1443,11 +1440,11 @@ msgstr "Beim Anzeigen der Liste ist ein Fehler aufgetreten"
 msgid "There was an error importing the data: %s"
 msgstr "Beim Importieren der Daten ist ein Fehler aufgetreten: %s"
 
-#: lib/api.php:889 lib/api.php:1230
+#: lib/api.php:931 lib/api.php:1272
 msgid "There was an error importing the iCalendar data."
 msgstr "Beim Importieren der iCalendar Daten ist ein Fehler aufgetreten."
 
-#: lib/api.php:258
+#: lib/api.php:263
 #, php-format
 msgid "There was an error removing an address book for %s"
 msgstr "Beim Löschen eines Adressbuchs von %s ist ein Fehler aufgetreten"
@@ -1481,7 +1478,7 @@ msgstr "Der Kontakt wurde als Ihre Visitenkarte markiert."
 msgid "This file format is not supported."
 msgstr "Dieses Dateiformat wird nicht unterstützt."
 
-#: lib/api.php:1819 lib/api.php:1832
+#: lib/api.php:1876 lib/api.php:1889
 #, php-format
 msgid "This person already has a %s entry in the address book"
 msgstr "Diese Person hat bereits einen %s-Eintrag in Ihrem Adressbuch"
@@ -1501,7 +1498,7 @@ msgstr "Zeitzone"
 msgid "Unable to find contact owner."
 msgstr "Kontaktbesitzer konnte nicht gefunden werden."
 
-#: lib/Driver.php:1981 lib/Turba.php:659
+#: lib/Driver.php:2003 lib/Turba.php:663
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr "Der %s-Treiber konnte nicht geladen werden."
@@ -1519,7 +1516,7 @@ msgstr "Suche nicht m
 msgid "Unfiled"
 msgstr "Nicht zugeordnet"
 
-#: lib/api.php:927 lib/api.php:1038 lib/api.php:1248
+#: lib/api.php:969 lib/api.php:1080 lib/api.php:1290
 #, php-format
 msgid "Unsupported Content-Type: %s"
 msgstr "Nicht unterstützter Inhaltstyp: %s"
@@ -1537,7 +1534,7 @@ msgstr "Kontakt anzeigen"
 msgid "View to display by default:"
 msgstr "Standardansicht:"
 
-#: config/attributes.php.dist:506
+#: config/attributes.php.dist:512
 msgid "VoIP"
 msgstr "VoIP"
 
@@ -1549,7 +1546,7 @@ msgstr "Website-URL"
 msgid "Work Address"
 msgstr "Adresse geschäftlich"
 
-#: config/attributes.php.dist:570
+#: config/attributes.php.dist:576
 msgid "Work Address Extended"
 msgstr "Erweiterte Adresse geschäftlich"
 
@@ -1561,23 +1558,23 @@ msgstr "Stadt gesch
 msgid "Work Country"
 msgstr "Land geschäftlich"
 
-#: config/attributes.php.dist:454
+#: config/attributes.php.dist:460
 msgid "Work Email"
 msgstr "E-Mail-Adresse geschäftlich"
 
-#: config/attributes.php.dist:471
+#: config/attributes.php.dist:477
 msgid "Work Fax"
 msgstr "Fax geschäftlich"
 
-#: config/attributes.php.dist:576
+#: config/attributes.php.dist:582
 msgid "Work Latitude"
 msgstr "Breitengrad geschäftlich"
 
-#: config/attributes.php.dist:581
+#: config/attributes.php.dist:587
 msgid "Work Longitude"
 msgstr "Längengrad geschäftlich"
 
-#: config/attributes.php.dist:481
+#: config/attributes.php.dist:487
 msgid "Work Mobile Phone"
 msgstr "Telefon mobil geschäftlich"
 
@@ -1601,11 +1598,11 @@ msgstr "Bundesstaat oder Provinz gesch
 msgid "Work Street Address"
 msgstr "Straße geschäftlich"
 
-#: config/attributes.php.dist:496
+#: config/attributes.php.dist:502
 msgid "Work Video Call"
 msgstr "Bildtelefon geschäftlich"
 
-#: config/attributes.php.dist:564
+#: config/attributes.php.dist:570
 msgid "Work Website URL"
 msgstr "Website-URL geschäftlich"
 
@@ -1622,7 +1619,7 @@ msgstr "Sie d
 msgid "You are not allowed to delete this addressbook."
 msgstr "Sie dürfen dieses Adressbuch nicht löschen."
 
-#: lib/api.php:204
+#: lib/api.php:209
 msgid "You are not allowed to remove user data."
 msgstr "Sie dürfen keine Benutzerdaten löschen."
 
@@ -1638,7 +1635,7 @@ msgstr "Sie k
 msgid "You cannot delete contacts from a virtual address book"
 msgstr "Sie können keine Kontakte aus Virtuellen Adressbüchern löschen"
 
-#: lib/api.php:1056
+#: lib/api.php:1098
 msgid "You didn't mark a contact as your own yet."
 msgstr "Sie haben noch keinen Kontakt als Ihre Visitenkarte markiert."
 
@@ -1655,7 +1652,7 @@ msgstr "Sie haben nicht gen
 msgid "You do not have permissions to delete this address book."
 msgstr "Sie haben nicht genügend Rechte, um dieses Adressbuch zu löschen."
 
-#: lib/api.php:1070
+#: lib/api.php:1112
 msgid ""
 "You don't have sufficient permissions to read the address book that contains "
 "your own contact."
@@ -1663,7 +1660,7 @@ msgstr ""
 "Sie haben nicht genügend Rechte, um das Adressbuch zu lesen, das Ihre "
 "Visitenkarte enthält."
 
-#: lib/Driver/ldap.php:741
+#: lib/Driver/ldap.php:749
 msgid ""
 "You must have the Net_LDAP PEAR library installed to use the schema check "
 "function."
@@ -1701,7 +1698,7 @@ msgstr "Ihr Standard-Adressbuch kann nicht angezeigt werden."
 msgid "Your own contact"
 msgstr "Ihre Visitenkarte"
 
-#: lib/api.php:1075
+#: lib/api.php:1117
 msgid "Your own contact cannot be found in the address book."
 msgstr "Ihre Visitenkarte konnte in dem Adressbuch nicht gefunden werden."
 
@@ -1709,7 +1706,7 @@ msgstr "Ihre Visitenkarte konnte in dem Adressbuch nicht gefunden werden."
 msgid "[no value]"
 msgstr "[kein Wert]"
 
-#: lib/Turba.php:601
+#: lib/Turba.php:605
 msgid "_Browse"
 msgstr "_Liste"
 
@@ -1725,7 +1722,7 @@ msgstr "L
 msgid "_Edit"
 msgstr "_Bearbeiten"
 
-#: lib/Turba.php:610
+#: lib/Turba.php:614
 msgid "_Import/Export"
 msgstr "_Import/Export"
 
@@ -1733,15 +1730,15 @@ msgstr "_Import/Export"
 msgid "_Lists"
 msgstr "_Listen"
 
-#: lib/Turba.php:598
+#: lib/Turba.php:602
 msgid "_My Address Books"
 msgstr "_Meine Adressbücher"
 
-#: lib/Turba.php:604
+#: lib/Turba.php:608
 msgid "_New Contact"
 msgstr "_Neuer Kontakt"
 
-#: lib/Turba.php:615
+#: lib/Turba.php:619
 msgid "_Print"
 msgstr "_Drucken"
 
@@ -1749,7 +1746,7 @@ msgstr "_Drucken"
 msgid "_Remove from this list"
 msgstr "_Aus dieser Liste entfernen"
 
-#: lib/Turba.php:606
+#: lib/Turba.php:610
 msgid "_Search"
 msgstr "_Suche"
 
@@ -1794,7 +1791,7 @@ msgstr "adressen.vcf"
 msgid "descending"
 msgstr "absteigend"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "female"
 msgstr "weiblich"
 
@@ -1803,7 +1800,7 @@ msgstr "weiblich"
 msgid "in %s"
 msgstr "in %s"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "male"
 msgstr "männlich"
 
diff --git a/po/el_GR.po b/po/el_GR.po
index f601006..eb6cec3 100644
--- a/po/el_GR.po
+++ b/po/el_GR.po
@@ -1,5 +1,5 @@
 # Turba Greek translation.
-# Copyright (C) 2002 Stefanos I. Dimitriou.
+# Copyright 2002 Stefanos I. Dimitriou.
 # Stefanos I. Dimitriou <support_webmail at teiath.gr>, 2002.
 # Silligardos Xristoforos, 2002.
 # Anagnostopoulos Apostolis, 2002.
diff --git a/po/es_ES.po b/po/es_ES.po
index d2302ca..8258685 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -1,6 +1,6 @@
 # Spanish translations for turba package
 # Traducciones al español para el paquete turba.
-# Copyright (C) 2008 Horde Project
+# Copyright 2008-2009 The Horde Project
 # This file is distributed under the same license as the turba package.
 # Automatically generated, 2008.
 #
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Turba 2.2-rc4\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2008-05-24 09:49+0200\n"
-"PO-Revision-Date: 2008-05-24 09:49+0200\n"
+"POT-Creation-Date: 2009-02-20 17:15+0100\n"
+"PO-Revision-Date: 2009-02-20 17:15+0100\n"
 "Last-Translator: Manuel P. Ayala <mayala at unex.es>\n"
 "Language-Team: i18n at lists.horde.org\n"
 "MIME-Version: 1.0\n"
@@ -25,19 +25,19 @@ msgstr "A
 msgid " Delete IMSP Address Book"
 msgstr "Eliminar Libreta de direcciones de IMSP"
 
-#: data.php:376
+#: data.php:455
 #, php-format
 msgid "\"%s\" already exists and was not imported."
 msgstr "\"%s\" ya existe y no se importó."
 
-#: lib/Forms/EditContact.php:76
+#: lib/Forms/EditContact.php:83
 #, php-format
 msgid "\"%s\" updated, but saving the uploaded file failed: %s"
 msgstr ""
 "Se ha actualizado \"%s\", pero se ha producido un error al guardar el "
 "archivo cargado: %s"
 
-#: lib/Forms/EditContact.php:78 lib/Forms/EditContact.php:81
+#: lib/Forms/EditContact.php:85 lib/Forms/EditContact.php:88
 #, php-format
 msgid "\"%s\" updated."
 msgstr "Se ha actualizado \"%s\"."
@@ -60,27 +60,27 @@ msgstr "\"Nombre Apellidos\"  (p.e. Juan Nadie)"
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr "\"Apellidos, Nombre\" (p.e. Nadie, Juan)"
 
-#: lib/Forms/AddContact.php:83
+#: lib/Driver.php:620
+#, php-format
+msgid "%d. %s of %s"
+msgstr "%d. %s de %s"
+
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr "Se ha añadido %s."
 
-#: data.php:401
+#: data.php:483
 #, php-format
 msgid "%s file successfully imported."
 msgstr "El archivo %s se ha importado satisfactoriamente."
 
-#: lib/Driver.php:555
-#, php-format
-msgid "%s of %s"
-msgstr "%s de %s"
-
 #: templates/list/numPager.inc:6
 #, php-format
 msgid "%s to %s of %s"
 msgstr "%s al %s de %s"
 
-#: lib/Turba.php:560
+#: lib/Turba.php:541
 #, php-format
 msgid "%s's Address Book"
 msgstr "Direcciones de %s"
@@ -94,7 +94,7 @@ msgstr "Hace falta un navegador con soporte de iFrames"
 msgid "Access denied to %s"
 msgstr "Acceso denegado a %s"
 
-#: templates/browse/actions.inc:30 lib/Forms/AddContact.php:25
+#: lib/Forms/AddContact.php:25 templates/browse/actions.inc:30
 msgid "Add"
 msgstr "Añadir"
 
@@ -114,11 +114,11 @@ msgstr "A
 msgid "Add to"
 msgstr "Añadir a"
 
-#: lib/Driver.php:1876 lib/Driver/null.php:57
+#: lib/Driver.php:2115 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr "La adición de contactos no está disponible."
 
-#: templates/addressbook_list.php:16
+#: templates/addressbook_list.php:16 templates/browse/search.inc:125
 msgid "Address Book"
 msgstr "Direcciones"
 
@@ -134,7 +134,7 @@ msgstr "Listado de libreta de direcciones"
 msgid "Address Books"
 msgstr "Libretas de direcciones"
 
-#: data.php:356
+#: data.php:435
 msgid "Address book successfully purged."
 msgstr "Se ha vaciado correctamente la libreta de direcciones."
 
@@ -143,7 +143,7 @@ msgstr "Se ha vaciado correctamente la libreta de direcciones."
 msgid "Address books that will not be displayed:"
 msgstr "Libretas de direcciones que no se mostrarán:"
 
-#: search.php:199 templates/browse/search.inc:47
+#: search.php:184 templates/browse/search.inc:47
 msgid "Advanced Search"
 msgstr "Búsqueda avanzada"
 
@@ -155,7 +155,7 @@ msgstr "Apodo"
 msgid "All"
 msgstr "Todo"
 
-#: lib/api.php:916
+#: lib/api.php:941
 msgid "Already Exists"
 msgstr "Ya existe"
 
@@ -176,11 +176,11 @@ msgstr "
 msgid "Are you sure that you want to delete the selected contacts?"
 msgstr "¿Seguro que desea eliminar los contactos seleccionados?"
 
-#: config/.bak/attributes.php.dist:378
+#: config/.bak/attributes.php.dist:430
 msgid "Assistant"
 msgstr "Asistente"
 
-#: search.php:196 templates/browse/search.inc:46
+#: search.php:181 templates/browse/search.inc:46
 msgid "Basic Search"
 msgstr "Búsqueda simple"
 
@@ -197,7 +197,7 @@ msgstr "Cumplea
 msgid "Birthdays"
 msgstr "Cumpleaños"
 
-#: contact.php:106 templates/browse/row.inc:6
+#: contact.php:128 templates/browse/row.inc:10
 msgid "Blank name"
 msgstr "Sin nombre"
 
@@ -205,16 +205,16 @@ msgstr "Sin nombre"
 msgid "Both"
 msgstr "Ambas"
 
-#: addressbooks/index.php:39 templates/addressbook_list.php:29
-#: templates/menu.inc:8
+#: templates/addressbook_list.php:29 templates/menu.inc:8
+#: addressbooks/index.php:39
 msgid "Browse"
 msgstr "Examinar"
 
-#: config/.bak/attributes.php.dist:288
+#: config/.bak/attributes.php.dist:300
 msgid "Business Category"
 msgstr "Categoría de negocio"
 
-#: data.php:86
+#: data.php:101
 msgid "CSV"
 msgstr "CSV"
 
@@ -232,24 +232,24 @@ msgid "Cannot delete all address book entries for %s"
 msgstr ""
 "No se pueden borrar todas las entradas de Libretas de direcciones de %s"
 
-#: config/.bak/attributes.php.dist:350
+#: config/.bak/attributes.php.dist:388
 msgid "Category"
 msgstr "Categoría"
 
-#: templates/browse/column_headers.inc:24
+#: templates/browse/column_headers.inc:25
 #, php-format
 msgid "Change %s sort to %s"
 msgstr "Cambiar la ordenación de %s a %s"
 
-#: addressbooks/index.php:41 templates/addressbook_list.php:33
+#: templates/addressbook_list.php:33 addressbooks/index.php:41
 msgid "Change Permissions"
 msgstr "Cambiar permisos"
 
-#: templates/browse/column_headers.inc:7
+#: templates/browse/column_headers.inc:8
 msgid "Check All/None"
 msgstr "Comprobar Todas/Ninguna"
 
-#: templates/browse/column_headers.inc:7
+#: templates/browse/column_headers.inc:8
 msgid "Check _All/None"
 msgstr "Comprobar _Todas/Ninguna"
 
@@ -270,8 +270,12 @@ msgid "Choose which address books to use."
 msgstr "Elija las Libretas de direcciones a utilizar."
 
 #: templates/prefs/columnselect.inc:41
-msgid "Click an address book to sort its columns:"
-msgstr "Seleccione una libreta de direcciones para ordenar sus columnas:"
+msgid ""
+"Click an address book to sort its columns. Drag columns to re-arrange them. "
+"Check a column to enable it."
+msgstr ""
+"Pulse una libreta de direcciones para ordenar sus columnas. Arrastre las "
+"columnas para reorganizarlas. Pulse una columna para activarla."
 
 #: templates/block/minisearch.inc:26
 msgid "Close"
@@ -293,58 +297,60 @@ msgstr "Valores separados por comas"
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr "Valores separados por comas (Outlook de Microsoft)"
 
-#: config/.bak/attributes.php.dist:476
+#: config/.bak/attributes.php.dist:528
 msgid "Common Address Extended"
 msgstr "Dirección habitual extendida"
 
-#: config/.bak/attributes.php.dist:494
+#: config/.bak/attributes.php.dist:546
 msgid "Common City"
 msgstr "Localidad habitual"
 
-#: config/.bak/attributes.php.dist:512
+#: config/.bak/attributes.php.dist:564
 msgid "Common Country"
 msgstr "Pais habitual"
 
-#: config/.bak/attributes.php.dist:420
+#: config/.bak/attributes.php.dist:472
 msgid "Common Phone"
 msgstr "Teléfono habitual"
 
-#: config/.bak/attributes.php.dist:488
+#: config/.bak/attributes.php.dist:540
 msgid "Common Post Office Box"
 msgstr "Buzón postal habitual"
 
-#: config/.bak/attributes.php.dist:506
+#: config/.bak/attributes.php.dist:558
 msgid "Common Postal Code"
 msgstr "Código postal habitual"
 
-#: config/.bak/attributes.php.dist:500
+#: config/.bak/attributes.php.dist:552
 msgid "Common State/Province"
 msgstr "Estado/Provincia habitual"
 
-#: config/.bak/attributes.php.dist:482
+#: config/.bak/attributes.php.dist:534
 msgid "Common Street"
 msgstr "Calle habitual"
 
-#: config/.bak/attributes.php.dist:445
+#: config/.bak/attributes.php.dist:497
 msgid "Common Video Call"
 msgstr "Videollamada habitual"
 
-#: config/.bak/sources.php.dist:243 config/.bak/sources.php.dist:922
+#: config/.bak/sources.php.dist:256 config/.bak/sources.php.dist:952
 msgid "Communications"
 msgstr "Comunicaciones"
 
-#: config/.bak/attributes.php.dist:294
+#: config/.bak/attributes.php.dist:306
 msgid "Company"
 msgstr "Compañía"
 
-#: config/.bak/attributes.php.dist:223
+#: config/.bak/attributes.php.dist:235
 msgid "Company Address"
 msgstr "Domicilio laboral"
 
-#: scripts/import_squirrelmail_abook.php:112 lib/api.php:523 lib/api.php:577
-#: lib/api.php:630 lib/api.php:678 lib/api.php:733 lib/api.php:792
-#: lib/api.php:842 lib/api.php:978 lib/api.php:1070 lib/api.php:1136
-#: lib/api.php:1242 lib/api.php:1475 lib/api.php:1552 lib/api.php:1701
+#: lib/api.php:546 lib/api.php:600 lib/api.php:653 lib/api.php:701
+#: lib/api.php:756 lib/api.php:815 lib/api.php:866 lib/api.php:1004
+#: lib/api.php:1066 lib/api.php:1137 lib/api.php:1204 lib/api.php:1324
+#: lib/api.php:1568 lib/api.php:1654 lib/api.php:1806
+#: scripts/import_squirrelmail_sql_abook.php:125
+#: scripts/import_squirrelmail_file_abook.php:114
 #, php-format
 msgid "Connection failed: %s"
 msgstr "Ha fallado la conexión: %s"
@@ -357,7 +363,7 @@ msgstr "Fallo de conexi
 msgid "Contact Search"
 msgstr "Búsqueda de contactos"
 
-#: config/.bak/sources.php.dist:851
+#: config/.bak/sources.php.dist:868
 msgid "Contacts"
 msgstr "Contactos"
 
@@ -365,7 +371,7 @@ msgstr "Contactos"
 msgid "Contacts displayed:"
 msgstr "Contactos mostrados:"
 
-#: lib/Views/Browse.php:339
+#: lib/Views/Browse.php:346
 #, php-format
 msgid "Contacts in list: %s"
 msgstr "Contactos en la lista: %s"
@@ -386,7 +392,7 @@ msgstr "Crear Libreta de direcciones"
 msgid "Create a new Address Book"
 msgstr "Crear Libreta de direcciones"
 
-#: lib/ListView.php:447
+#: lib/ListView.php:448
 msgid "Create a new Contact List in:"
 msgstr "Crear una lista de contactos en:"
 
@@ -394,22 +400,22 @@ msgstr "Crear una lista de contactos en:"
 msgid "Created"
 msgstr "Creado"
 
-#: contact.php:89
+#: contact.php:95
 msgid "De_lete"
 msgstr "E_liminar"
 
-#: addressbooks/index.php:42 templates/addressbook_list.php:35
-#: templates/browse/actions.inc:3 lib/Forms/DeleteAddressBook.php:45
-#: lib/Views/DeleteContact.php:58
+#: lib/Views/DeleteContact.php:58 lib/Forms/DeleteAddressBook.php:45
+#: templates/addressbook_list.php:35 templates/browse/actions.inc:3
+#: addressbooks/index.php:42
 msgid "Delete"
 msgstr "Eliminar"
 
-#: lib/Forms/DeleteAddressBook.php:40 lib/Views/DeleteContact.php:28
+#: lib/Views/DeleteContact.php:28 lib/Forms/DeleteAddressBook.php:40
 #, php-format
 msgid "Delete %s"
 msgstr "Eliminar %s"
 
-#: lib/api.php:621
+#: lib/api.php:644
 msgid "Delete denied."
 msgstr "Eliminación denegada."
 
@@ -418,7 +424,7 @@ msgstr "Eliminaci
 msgid "Delete failed: (%s) %s"
 msgstr "Se ha producido un error al eliminar: (%s) %s"
 
-#: lib/Driver.php:1884 lib/Driver/null.php:62
+#: lib/Driver.php:2123 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr "La eliminación de contactos no está disponible."
 
@@ -426,18 +432,14 @@ msgstr "La eliminaci
 msgid "Deletion failed"
 msgstr "Se ha producido un error al eliminar"
 
-#: config/.bak/attributes.php.dist:300
+#: config/.bak/attributes.php.dist:312
 msgid "Department"
 msgstr "Departamento"
 
-#: lib/Forms/CreateAddressBook.php:37 lib/Forms/EditAddressBook.php:44
+#: lib/Forms/EditAddressBook.php:44 lib/Forms/CreateAddressBook.php:37
 msgid "Description"
 msgstr "Descripción"
 
-#: templates/browse/search.inc:125
-msgid "Directory"
-msgstr "Directorio"
-
 #: config/.bak/prefs.php.dist:24
 msgid "Display"
 msgstr "Mostrar"
@@ -447,24 +449,19 @@ msgstr "Mostrar"
 msgid "Display Options"
 msgstr "Opciones de Visualización"
 
-#: lib/Object.php:348
+#: lib/Object.php:360
 msgid "Download"
 msgstr "Descargar"
 
-#: templates/browse/row.inc:15 templates/browse/row.inc:16
-#: templates/browse/contactrow.inc:25
+#: templates/browse/contactrow.inc:25 templates/browse/row.inc:27
+#: templates/browse/row.inc:28
 msgid "Download vCard"
 msgstr "Descargar vCard"
 
-#: templates/prefs/columnselect.inc:41
-msgid "Drag columns to re-arrange them. Check a column to enable it."
-msgstr ""
-"Arrastre las columnas para reorganizarlas. Pulse una columna para activarla."
-
-#: addressbooks/index.php:40 templates/addressbook_list.php:31
-#: templates/browse/actions.inc:6 templates/browse/column_headers.inc:10
-#: templates/browse/row.inc:28 templates/browse/row.inc:29
-#: templates/browse/contactrow.inc:33
+#: templates/addressbook_list.php:31 templates/browse/actions.inc:6
+#: templates/browse/contactrow.inc:33 templates/browse/row.inc:40
+#: templates/browse/row.inc:41 templates/browse/column_headers.inc:11
+#: addressbooks/index.php:40
 msgid "Edit"
 msgstr "Modificar"
 
@@ -473,25 +470,25 @@ msgstr "Modificar"
 msgid "Edit \"%s\""
 msgstr "Modificar \"%s\""
 
-#: lib/Forms/EditAddressBook.php:40 lib/Views/EditContact.php:35
+#: lib/Views/EditContact.php:35 lib/Forms/EditAddressBook.php:40
 #, php-format
 msgid "Edit %s"
 msgstr "Modificar %s"
 
-#: config/.bak/attributes.php.dist:237
+#: config/.bak/attributes.php.dist:249
 msgid "Email"
 msgstr "Correo"
 
-#: config/.bak/attributes.php.dist:243
+#: config/.bak/attributes.php.dist:255
 msgid "Emails"
 msgstr "Correos"
 
-#: lib/Views/Browse.php:263 lib/Views/Browse.php:303
+#: lib/Views/Browse.php:270 lib/Views/Browse.php:310
 #, php-format
 msgid "Error adding %d contact(s) to list."
 msgstr "Error añadiendo %d contacto(s) a la lista."
 
-#: lib/Views/Browse.php:265 lib/Views/Browse.php:305
+#: lib/Views/Browse.php:272 lib/Views/Browse.php:312
 #, php-format
 msgid "Error adding %d of %d requested contact(s) to list."
 msgstr "Error añadiendo %d de %d contacto(s) solicitado(s) a la lista."
@@ -516,12 +513,12 @@ msgstr "Error eliminando %d contacto(s) de la lista."
 msgid "Error removing %d of %d requested contact(s) from list."
 msgstr "Error eliminando %d de %d contacto(s) solicitado(s) de la lista."
 
-#: lib/api.php:684
+#: lib/api.php:707
 #, php-format
 msgid "Error searching the address book: %s"
 msgstr "Fallo buscando en la libreta de direcciones: %s"
 
-#: templates/browse/actions.inc:10 templates/data/export.inc:42
+#: templates/data/export.inc:42 templates/browse/actions.inc:10
 msgid "Export"
 msgstr "Exportar"
 
@@ -537,7 +534,7 @@ msgstr "Exportar s
 msgid "Export the following address book completely."
 msgstr "Exportar las siguientes libretas de direcciones completas."
 
-#: data.php:168 data.php:267 data.php:345 add.php:42 search.php:121
+#: search.php:106 data.php:247 data.php:346 data.php:424 add.php:42
 #: lib/Views/Browse.php:84 lib/Views/Browse.php:152 lib/Views/Browse.php:180
 #, php-format
 msgid "Failed to access the address book: %s"
@@ -548,11 +545,11 @@ msgstr "Fallo al acceder a la libreta de direcciones: %s"
 msgid "Failed to add %s to %s: %s"
 msgstr "Fallo al añadir %s a %s: %s"
 
-#: lib/Views/Browse.php:345
+#: lib/Views/Browse.php:352
 msgid "Failed to browse list"
 msgstr "Fallo al visualizar el listado"
 
-#: lib/Views/Browse.php:376
+#: lib/Views/Browse.php:383
 msgid "Failed to browse the directory"
 msgstr "Fallo al visualizar el directorio"
 
@@ -568,20 +565,20 @@ msgstr ""
 msgid "Failed to find object to be added: %s"
 msgstr "Fallo al localizar el objecto a añadir: %s"
 
-#: search.php:190
+#: search.php:175
 msgid "Failed to search the address book"
 msgstr "No se pudo buscar en la libreta de direcciones"
 
-#: data.php:183
+#: data.php:262
 #, php-format
 msgid "Failed to search the directory: %s"
 msgstr "Fallo al buscar en el directorio: %s"
 
-#: config/.bak/sources.php.dist:550
+#: config/.bak/sources.php.dist:565
 msgid "Favourite Recipients"
 msgstr "Destinatarios preferidos"
 
-#: config/.bak/attributes.php.dist:264
+#: config/.bak/attributes.php.dist:276
 msgid "Fax"
 msgstr "Fax"
 
@@ -593,7 +590,7 @@ msgstr "Archivos"
 msgid "Find"
 msgstr "Encontrar"
 
-#: lib/Forms/EditContact.php:121 lib/Forms/EditContact.php:160
+#: lib/Forms/EditContact.php:128 lib/Forms/EditContact.php:167
 msgid "Finish"
 msgstr "Terminar"
 
@@ -601,7 +598,7 @@ msgstr "Terminar"
 msgid "First Name"
 msgstr "Nombre"
 
-#: config/.bak/attributes.php.dist:326
+#: config/.bak/attributes.php.dist:350
 msgid "Freebusy URL"
 msgstr "URL de disponibilidad temporal"
 
@@ -609,83 +606,83 @@ msgstr "URL de disponibilidad temporal"
 msgid "From"
 msgstr "En"
 
-#: config/.bak/attributes.php.dist:384
+#: config/.bak/attributes.php.dist:436
 msgid "Gender"
 msgstr "Género"
 
-#: config/.bak/sources.php.dist:776
+#: config/.bak/sources.php.dist:791
 msgid "Global Address Book"
 msgstr "Libreta de direcciones global"
 
-#: templates/browse/row.inc:49 templates/browse/contactrow.inc:44
+#: templates/browse/contactrow.inc:44 templates/browse/row.inc:61
 msgid "Group"
 msgstr "Grupo"
 
-#: config/.bak/attributes.php.dist:123
+#: config/.bak/attributes.php.dist:135
 msgid "Home Address"
 msgstr "Dirección personal"
 
-#: config/.bak/attributes.php.dist:546
+#: config/.bak/attributes.php.dist:598
 msgid "Home Address Extended"
 msgstr "Dirección personal extendida"
 
-#: config/.bak/attributes.php.dist:141
+#: config/.bak/attributes.php.dist:153
 msgid "Home City"
 msgstr "Localidad personal"
 
-#: config/.bak/attributes.php.dist:159
+#: config/.bak/attributes.php.dist:171
 msgid "Home Country"
 msgstr "Pais personal"
 
-#: config/.bak/attributes.php.dist:414
+#: config/.bak/attributes.php.dist:466
 msgid "Home Email"
 msgstr "Correo personal"
 
-#: config/.bak/attributes.php.dist:430
+#: config/.bak/attributes.php.dist:482
 msgid "Home Fax"
 msgstr "Fax personal"
 
-#: config/.bak/attributes.php.dist:552
+#: config/.bak/attributes.php.dist:604
 msgid "Home Latitude"
 msgstr "Latitud personal"
 
-#: config/.bak/attributes.php.dist:557
+#: config/.bak/attributes.php.dist:609
 msgid "Home Longitude"
 msgstr "Longitud personal"
 
-#: config/.bak/attributes.php.dist:440
+#: config/.bak/attributes.php.dist:492
 msgid "Home Mobile Phone"
 msgstr "Teléfono móvil personal"
 
-#: config/.bak/attributes.php.dist:249
+#: config/.bak/attributes.php.dist:261
 msgid "Home Phone"
 msgstr "Teléfono personal"
 
-#: config/.bak/attributes.php.dist:135
+#: config/.bak/attributes.php.dist:147
 msgid "Home Post Office Box"
 msgstr "Buzón postal personal"
 
-#: config/.bak/attributes.php.dist:153
+#: config/.bak/attributes.php.dist:165
 msgid "Home Postal Code"
 msgstr "Código postal personal"
 
-#: config/.bak/attributes.php.dist:147
+#: config/.bak/attributes.php.dist:159
 msgid "Home State/Province"
 msgstr "Estado/Provincia personal"
 
-#: config/.bak/attributes.php.dist:129
+#: config/.bak/attributes.php.dist:141
 msgid "Home Street Address"
 msgstr "Calle personal"
 
-#: config/.bak/attributes.php.dist:455
+#: config/.bak/attributes.php.dist:507
 msgid "Home Video Call"
 msgstr "Videollamada personal"
 
-#: config/.bak/attributes.php.dist:540
+#: config/.bak/attributes.php.dist:592
 msgid "Home Website URL"
 msgstr "URL de sede Web personal"
 
-#: config/.bak/sources.php.dist:667
+#: config/.bak/sources.php.dist:682
 msgid "IMSP"
 msgstr "IMSP"
 
@@ -694,38 +691,39 @@ msgstr "IMSP"
 msgid "Import Address Book, Step %d"
 msgstr "Importar libreta de direcciones. Paso %d"
 
-#: data.php:419
+#: data.php:501
 msgid "Import/Export Address Books"
 msgstr "Importar/Exportar libretas de direcciones"
 
-#: config/.bak/attributes.php.dist:360
+#: config/.bak/attributes.php.dist:412
 msgid "Initials"
 msgstr "Iniciales"
 
-#: config/.bak/attributes.php.dist:366
+#: config/.bak/attributes.php.dist:418
 msgid "Instant Messenger"
 msgstr "Mensajería instantánea"
 
-#: lib/api.php:973 lib/api.php:1065
+#: lib/api.php:999 lib/api.php:1132
 msgid "Invalid ID"
 msgstr "ID no válido"
 
-#: scripts/import_squirrelmail_abook.php:105 lib/api.php:345 lib/api.php:673
-#: lib/api.php:728 lib/api.php:787 lib/api.php:835 lib/api.php:969
-#: lib/api.php:1061 lib/api.php:1126 lib/api.php:1684
+#: lib/api.php:368 lib/api.php:696 lib/api.php:751 lib/api.php:810
+#: lib/api.php:859 lib/api.php:995 lib/api.php:1128 lib/api.php:1194
+#: lib/api.php:1789 scripts/import_squirrelmail_sql_abook.php:118
+#: scripts/import_squirrelmail_file_abook.php:107
 #, php-format
 msgid "Invalid address book: %s"
 msgstr "Libreta de direcciones no válida: %s"
 
-#: lib/api.php:1130
+#: lib/api.php:1198
 msgid "Invalid contact unique ID"
 msgstr "ID único de contacto no válido"
 
-#: lib/api.php:1688 lib/api.php:1774 lib/api.php:1835
+#: lib/api.php:1793 lib/api.php:1879 lib/api.php:1940
 msgid "Invalid email"
 msgstr "La dirección de correo no es válida."
 
-#: lib/api.php:1696
+#: lib/api.php:1801
 msgid "Invalid entry"
 msgstr "Entrada no válida."
 
@@ -733,18 +731,27 @@ msgstr "Entrada no v
 msgid "Invalid key specified."
 msgstr "Se ha indicado una clave no válida."
 
-#: lib/api.php:1692
+#: lib/api.php:1797
 msgid "Invalid name"
 msgstr "Nombre no válido"
 
-#: config/.bak/attributes.php.dist:276
+#: config/.bak/attributes.php.dist:288
 msgid "Job Title"
 msgstr "Cargo"
 
-#: lib/Driver/kolab.php:1114 lib/Driver/kolab.php:1180
+#: lib/Driver/kolab.php:1119
+#, php-format
+msgid "Key for saving must be \\'uid\\' not %s!"
+msgstr "¡La clave de almacenamiento tiene que ser \\'uid\\' no %s!"
+
+#: lib/Driver/kolab.php:1203
 #, php-format
 msgid "Key for saving must be a UID not %s!"
-msgstr "'La clave de almacenamiento tiene que se un UID no %s!"
+msgstr "¡La clave de almacenamiento tiene que ser un UID no %s!"
+
+#: config/.bak/attributes.php.dist:406
+msgid "Kolab Home Server"
+msgstr "Servidor Kolab principal"
 
 #: lib/Driver/ldap.php:64
 msgid ""
@@ -752,11 +759,11 @@ msgid ""
 msgstr ""
 "Se precisa soporte LDAP pero el módulo LDAP no está disponible o cargado."
 
-#: data.php:91 templates/data/import.inc:18 templates/data/export.inc:16
+#: data.php:106 templates/data/import.inc:18 templates/data/export.inc:16
 msgid "LDIF Address Book"
 msgstr "Libreta de direcciones LDIF"
 
-#: config/.bak/attributes.php.dist:390
+#: config/.bak/attributes.php.dist:442
 msgid "Language"
 msgstr "Idioma"
 
@@ -768,39 +775,51 @@ msgstr "
 msgid "Last Name"
 msgstr "Apellidos"
 
-#: config/.bak/attributes.php.dist:396
+#: config/.bak/attributes.php.dist:448
 msgid "Latitude"
 msgstr "Latitud"
 
-#: templates/browse/column_headers.inc:16
+#: templates/browse/column_headers.inc:17
 msgid "List"
 msgstr "Lista"
 
-#: config/.bak/sources.php.dist:238 config/.bak/sources.php.dist:918
+#: config/.bak/sources.php.dist:251 config/.bak/sources.php.dist:948
 msgid "Location"
 msgstr "Ubicación"
 
-#: config/.bak/attributes.php.dist:401
+#: config/.bak/attributes.php.dist:324
+msgid "Logo"
+msgstr "Logotipo"
+
+#: config/.bak/attributes.php.dist:330
+msgid "Logo MIME Type"
+msgstr "Tipo MIME del logotipo"
+
+#: config/.bak/attributes.php.dist:453
 msgid "Longitude"
 msgstr "Longitud"
 
-#: lib/api.php:593
+#: lib/api.php:616
 msgid "Malformed request."
 msgstr "Solicitud malformada."
 
-#: addressbooks/index.php:46 templates/addressbook_list.php:2
+#: templates/addressbook_list.php:2 addressbooks/index.php:46
 msgid "Manage Address Books"
 msgstr "Gestionar Libretas de direcciones"
 
-#: config/.bak/attributes.php.dist:372
+#: config/.bak/attributes.php.dist:424
 msgid "Manager"
 msgstr "Gestor"
 
+#: contact.php:109
+msgid "Mark this as your own contact"
+msgstr "Marcar como contacto propio"
+
 #: templates/browse/search.inc:109
 msgid "Matching"
 msgstr "Coincidente"
 
-#: lib/api.php:306
+#: lib/api.php:329
 msgid "Maximum Number of Contacts"
 msgstr "Número máximo de contactos"
 
@@ -820,7 +839,7 @@ msgstr "N. adicionales"
 msgid "Missing DN in LDAP source configuration."
 msgstr "Falta DN en la configuración origen de LDAP."
 
-#: config/.bak/attributes.php.dist:259
+#: config/.bak/attributes.php.dist:271
 msgid "Mobile Phone"
 msgstr "Teléfono móvil"
 
@@ -833,7 +852,7 @@ msgstr "Ha fallado la modificaci
 msgid "More Options..."
 msgstr "Mas opciones..."
 
-#: lib/api.php:1812
+#: lib/api.php:1917
 msgid "More than 1 entry found"
 msgstr "Se ha encontrado más de 1 entrada"
 
@@ -849,11 +868,11 @@ msgstr "Desplazar a la izquierda"
 msgid "Move right"
 msgstr "Desplazar a la derecha"
 
-#: data.php:89 templates/data/import.inc:16
+#: data.php:104 templates/data/import.inc:16
 msgid "Mulberry Address Book"
 msgstr "Libreta de direcciones Mulberry"
 
-#: lib/api.php:1720
+#: lib/api.php:1825
 #, php-format
 msgid ""
 "Multiple persons with address [%s], but none with name [%s] already exist"
@@ -861,11 +880,11 @@ msgstr ""
 "Varias personas con la dirección [%s] pero todavía no existe ninguna con el "
 "nombre [%s]"
 
-#: config/.bak/sources.php.dist:162
+#: config/.bak/sources.php.dist:167
 msgid "My Address Book"
 msgstr "Mi libreta de direcciones"
 
-#: lib/Forms/CreateAddressBook.php:36 lib/Forms/EditAddressBook.php:43
+#: lib/Forms/EditAddressBook.php:43 lib/Forms/CreateAddressBook.php:36
 #: config/.bak/attributes.php.dist:47
 msgid "Name"
 msgstr "Nombre"
@@ -886,12 +905,12 @@ msgstr "Sufijos del nombre"
 msgid "Name:"
 msgstr "Nombre:"
 
-#: add.php:70 lib/Block/tree_menu.php:27
+#: add.php:70 lib/Block/tree_menu.php:28
 msgid "New Contact"
 msgstr "Añadir"
 
-#: templates/data/import.inc:46 lib/Forms/EditContact.php:112
-#: lib/Forms/EditContact.php:119 lib/Forms/EditContact.php:174
+#: lib/Forms/EditContact.php:119 lib/Forms/EditContact.php:126
+#: lib/Forms/EditContact.php:181 templates/data/import.inc:46
 msgid "Next"
 msgstr "Siguiente"
 
@@ -899,26 +918,26 @@ msgstr "Siguiente"
 msgid "Nickname"
 msgstr "Apodo"
 
-#: lib/api.php:1815 lib/api.php:1875
+#: lib/api.php:1920 lib/api.php:1980
 #, php-format
 msgid "No %s entry found for %s"
 msgstr "No se ha encontrado una entrada %s para %s"
 
-#: data.php:78
+#: data.php:93
 msgid ""
 "No Address Books are currently available. Import and Export is disabled."
 msgstr ""
 "Actualmente no hay Libretas de direcciones disponibles. La importación y la "
 "exportación están deshabilitadas."
 
-#: search.php:107
+#: search.php:92
 msgid "No Address Books are currently available. Searching is disabled."
 msgstr ""
 "Actualmente no hay Libretas de direcciones disponibles. La búsqueda está "
 "deshabilitada."
 
-#: lib/api.php:667 lib/api.php:722 lib/api.php:782 lib/api.php:964
-#: lib/api.php:1056 lib/api.php:1121
+#: lib/api.php:690 lib/api.php:745 lib/api.php:805 lib/api.php:990
+#: lib/api.php:1123 lib/api.php:1189
 msgid "No address book specified"
 msgstr "No se ha indicado una libreta de direcciones"
 
@@ -926,7 +945,7 @@ msgstr "No se ha indicado una libreta de direcciones"
 msgid "No contacts found"
 msgstr "No se han encontrado contactos"
 
-#: templates/browse/column_headers.inc:43
+#: templates/browse/column_headers.inc:44
 msgid "No contacts match the current filter."
 msgstr "No hay contactos coincidentes con el filtro actual."
 
@@ -938,7 +957,7 @@ msgstr "No hay contactos coincidentes"
 msgid "No source for favourite recipients exists."
 msgstr "No existe un origen para destinatarios preferidos."
 
-#: lib/api.php:868 lib/api.php:1166
+#: lib/api.php:893 lib/api.php:1235
 msgid "No vCard data was found."
 msgstr "No se encontraron datos vCard."
 
@@ -946,16 +965,16 @@ msgstr "No se encontraron datos vCard."
 msgid "None"
 msgstr "Ninguna"
 
-#: lib/Views/EditContact.php:33 lib/Views/Contact.php:49
-#: lib/Views/DeleteContact.php:26
+#: lib/Views/DeleteContact.php:26 lib/Views/Contact.php:49
+#: lib/Views/EditContact.php:33
 msgid "Not Found"
 msgstr "No encontrado"
 
-#: edit.php:48 deletefile.php:22
+#: deletefile.php:22 edit.php:48
 msgid "Not found"
 msgstr "No encontrado"
 
-#: config/.bak/attributes.php.dist:314
+#: config/.bak/attributes.php.dist:338
 msgid "Notes"
 msgstr "Notas"
 
@@ -963,20 +982,20 @@ msgstr "Notas"
 msgid "Number of items per page"
 msgstr "Número de artículos por página"
 
-#: lib/api.php:1015 lib/api.php:1191
+#: lib/api.php:1041 lib/api.php:1260
 msgid "Object not found"
 msgstr "No se ha encontrado el objeto."
 
-#: lib/Driver/kolab.php:1184
+#: lib/Driver/kolab.php:1207
 #, php-format
 msgid "Object with UID %s does not exist!"
 msgstr "¡El objeto con UID %s no existe!"
 
-#: config/.bak/attributes.php.dist:282
+#: config/.bak/attributes.php.dist:294
 msgid "Occupation"
 msgstr "Ocupación"
 
-#: config/.bak/attributes.php.dist:306
+#: config/.bak/attributes.php.dist:318
 msgid "Office"
 msgstr "Oficina"
 
@@ -990,27 +1009,27 @@ msgstr ""
 "eliminará definitivamente. Si ésto no es lo que quiere, tiene que cambiar su "
 "selección a \"Ninguna\"."
 
-#: lib/api.php:1174
+#: lib/api.php:1243
 msgid "Only one vcard supported."
 msgstr "Sólo se soporta una vcard."
 
-#: config/.bak/sources.php.dist:245 config/.bak/sources.php.dist:924
+#: config/.bak/sources.php.dist:258 config/.bak/sources.php.dist:954
 msgid "Organization"
 msgstr "Organización"
 
-#: config/.bak/sources.php.dist:246 config/.bak/sources.php.dist:926
+#: config/.bak/sources.php.dist:259 config/.bak/sources.php.dist:956
 msgid "Other"
 msgstr "Otro"
 
-#: config/.bak/attributes.php.dist:332
+#: config/.bak/attributes.php.dist:356
 msgid "PGP Public Key"
 msgstr "Clave PGP pública"
 
-#: config/.bak/attributes.php.dist:471
+#: config/.bak/attributes.php.dist:523
 msgid "PTT"
 msgstr "PTT"
 
-#: config/.bak/attributes.php.dist:269
+#: config/.bak/attributes.php.dist:281
 msgid "Pager"
 msgstr "Busca"
 
@@ -1018,16 +1037,24 @@ msgstr "Busca"
 msgid "Permanently delete this contact?"
 msgstr "¿Eliminar definitivamente este contacto?"
 
-#: deletefile.php:36 lib/Driver.php:721 lib/api.php:846 lib/api.php:1705
-#: lib/Driver/sql.php:486
+#: deletefile.php:36 lib/Driver.php:805 lib/api.php:870 lib/api.php:1810
+#: lib/Driver/sql.php:515
 msgid "Permission denied"
 msgstr "Permiso denegado"
 
-#: config/.bak/sources.php.dist:235 config/.bak/sources.php.dist:914
+#: config/.bak/sources.php.dist:248 config/.bak/sources.php.dist:944
 msgid "Personal"
 msgstr "Personal"
 
-#: data.php:90 templates/data/import.inc:17
+#: config/.bak/attributes.php.dist:121
+msgid "Photo"
+msgstr "Fotografía"
+
+#: config/.bak/attributes.php.dist:127
+msgid "Photo MIME Type"
+msgstr "Tipo MIME de la fotografía"
+
+#: data.php:105 templates/data/import.inc:17
 msgid "Pine Address Book"
 msgstr "Libreta de direcciones de Pine"
 
@@ -1035,8 +1062,8 @@ msgstr "Libreta de direcciones de Pine"
 msgid "Please name the new contact list:"
 msgstr "Introduzca el nombre de la nueva lista:"
 
-#: lib/Forms/EditContact.php:115 lib/Forms/EditContact.php:118
-#: lib/Forms/EditContact.php:167
+#: lib/Forms/EditContact.php:122 lib/Forms/EditContact.php:125
+#: lib/Forms/EditContact.php:174
 msgid "Previous"
 msgstr "Anterior"
 
@@ -1050,7 +1077,7 @@ msgstr "Ha fallado la consulta: (%s) %s"
 msgid "Read failed: (%s) %s"
 msgstr "Ha fallado la lectura: (%s) %s"
 
-#: lib/Driver.php:1868 lib/Driver/null.php:52
+#: lib/Driver.php:2107 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr "No está disponible la consulta de contactos."
 
@@ -1072,7 +1099,7 @@ msgstr "Eliminar Libreta de direcciones"
 msgid "Remove from this list"
 msgstr "Eliminar de esta lista"
 
-#: lib/Driver.php:1906
+#: lib/Driver.php:2145
 msgid ""
 "Removing user data is not supported in the current address book storage "
 "driver."
@@ -1088,7 +1115,7 @@ msgstr ""
 "¿Sustituir la libreta existente por la importada? <strong>Advertencia: Ésto "
 "eliminará todas las entradas de su Libreta de direcciones actual.</strong>"
 
-#: lib/Driver.php:615
+#: lib/Driver.php:699
 msgid "Requested object not found."
 msgstr "No se encontró el objeto solicitado."
 
@@ -1096,11 +1123,11 @@ msgstr "No se encontr
 msgid "Reset to Defaults"
 msgstr "Restaurar valores por omisión"
 
-#: config/.bak/attributes.php.dist:338
+#: config/.bak/attributes.php.dist:362
 msgid "S/MIME Public Certificate"
 msgstr "Certificado S/MIME público"
 
-#: config/.bak/attributes.php.dist:465
+#: config/.bak/attributes.php.dist:517
 msgid "SIP"
 msgstr "SIP"
 
@@ -1109,7 +1136,7 @@ msgstr "SIP"
 msgid "STARTTLS failed: (%s) %s"
 msgstr "Ha fallado STARTTLS: (%s) %s"
 
-#: lib/Forms/EditContact.php:26 lib/Forms/EditAddressBook.php:46
+#: lib/Forms/EditAddressBook.php:46 lib/Forms/EditContact.php:26
 msgid "Save"
 msgstr "Guardar"
 
@@ -1117,21 +1144,21 @@ msgstr "Guardar"
 msgid "Save search as a virtual address book?"
 msgstr "¿Guardar búsqueda como Libreta de direcciones virtual?"
 
-#: lib/Driver.php:1894 lib/Driver/null.php:67
+#: lib/Driver.php:2133 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr "Guardar los contactos no está disponible."
 
+#: lib/Block/tree_menu.php:62 templates/block/minisearch.inc:25
 #: templates/browse/search.inc:111 templates/browse/search.inc:119
-#: templates/browse/header.inc:3 templates/block/minisearch.inc:25
-#: lib/Block/tree_menu.php:58 config/.bak/prefs.php.dist:116
+#: templates/browse/header.inc:3 config/.bak/prefs.php.dist:116
 msgid "Search"
 msgstr "Buscar"
 
-#: lib/api.php:1480
+#: lib/api.php:1573
 msgid "Search failed"
 msgstr "Ha fallado la búsqueda"
 
-#: lib/api.php:1710 lib/api.php:1716 lib/api.php:1725 lib/api.php:1738
+#: lib/api.php:1815 lib/api.php:1821 lib/api.php:1830 lib/api.php:1843
 #, php-format
 msgid "Search failed: %s"
 msgstr "Ha fallado la búsqueda: %s"
@@ -1140,11 +1167,11 @@ msgstr "Ha fallado la b
 msgid "Search for: "
 msgstr "Buscar: %s"
 
-#: lib/Driver.php:1853 lib/Driver/null.php:47
+#: lib/Driver.php:2092 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr "La búsqueda no está disponible."
 
-#: templates/browse/row.inc:40
+#: templates/browse/row.inc:52
 msgid "Select contact"
 msgstr "Seleccionar contacto"
 
@@ -1222,17 +1249,17 @@ msgstr "Mostrar listas"
 msgid "Sort Direction"
 msgstr "Sentido de clasificación"
 
-#: templates/browse/column_headers.inc:31
+#: templates/browse/column_headers.inc:32
 #, php-format
 msgid "Sort by %s"
 msgstr "Ordenar por %s"
 
-#: templates/browse/column_headers.inc:26
+#: templates/browse/column_headers.inc:27
 #, php-format
 msgid "Sort by %s only"
 msgstr "Ordenar sólo por %s"
 
-#: templates/browse/column_headers.inc:29
+#: templates/browse/column_headers.inc:30
 #, php-format
 msgid "Sort by %s, then by %s"
 msgstr "Ordenar por %s y por %s"
@@ -1241,7 +1268,7 @@ msgstr "Ordenar por %s y por %s"
 msgid "Source:"
 msgstr "Origen:"
 
-#: lib/api.php:299
+#: lib/api.php:322
 msgid "Sources"
 msgstr "Orígenes"
 
@@ -1249,7 +1276,7 @@ msgstr "Or
 msgid "Spouse"
 msgstr "Esposa"
 
-#: lib/Views/Browse.php:261 lib/Views/Browse.php:301
+#: lib/Views/Browse.php:268 lib/Views/Browse.php:308
 #, php-format
 msgid "Successfully added %d contact(s) to list."
 msgstr "Se ha(n) añadido correctamente %d contacto(s) a la lista."
@@ -1259,12 +1286,12 @@ msgstr "Se ha(n) a
 msgid "Successfully added %s to %s"
 msgstr "Se ha añadido correctamente %s a %s."
 
-#: lib/Views/Browse.php:291
+#: lib/Views/Browse.php:298
 #, php-format
 msgid "Successfully created the contact list \"%s\"."
 msgstr "Se ha creado correctamente la lista de contactos \"%s\"."
 
-#: search.php:165
+#: search.php:150
 #, php-format
 msgid "Successfully created virtual address book \"%s\""
 msgstr "Se ha creado correctamente la libreta de direcciones virtual \"%s\"."
@@ -1279,7 +1306,7 @@ msgstr "Se ha(n) eliminado correctamente %d contacto(s)."
 msgid "Successfully removed %d contact(s) from list."
 msgstr "Se ha(n) eliminado correctamente %d contacto(s) de la lista."
 
-#: data.php:87
+#: data.php:102
 msgid "TSV"
 msgstr "TSV"
 
@@ -1295,7 +1322,7 @@ msgstr "Libreta de direcciones de destino"
 msgid "Target Contact List"
 msgstr "Lista de contactos de destino"
 
-#: data.php:347
+#: data.php:426
 #, php-format
 msgid "The %s file didn't contain any contacts."
 msgstr "El archivo %s no contenía ningún contacto."
@@ -1304,7 +1331,7 @@ msgstr "El archivo %s no conten
 msgid "The VFS backend needs to be configured to enable attachment uploads."
 msgstr "Hay que configurar el motor VFS para permitir la carga de adjuntos."
 
-#: lib/Driver.php:1824
+#: lib/Driver.php:2063
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr "La Libreta de direcciones \"%s\" no existe."
@@ -1314,11 +1341,15 @@ msgstr "La Libreta de direcciones \"%s\" no existe."
 msgid "The address book \"%s\" has been created."
 msgstr "Se ha creado la Libreta de direcciones \"%s\"."
 
-#: data.php:354
+#: data.php:433
 #, php-format
 msgid "The address book could not be purged: %s"
 msgstr "No se pudo vaciar la libreta de direcciones: %s"
 
+#: lib/api.php:1061
+msgid "The address book with your own contact doesn't exist anymore."
+msgstr "La Libreta de direcciones con su contacto ya no existe."
+
 #: addressbooks/delete.php:50
 #, php-format
 msgid "The addressbook \"%s\" has been deleted."
@@ -1334,7 +1365,7 @@ msgstr "Se ha renombrado la Libreta de direcciones \"%s\" como \"%s\"."
 msgid "The addressbook \"%s\" has been saved."
 msgstr "Se ha guardado la Libreta de direcciones \"%s\"."
 
-#: view.php:28 vcard.php:19 contact.php:23
+#: contact.php:23 vcard.php:19 view.php:28
 msgid "The contact you requested does not exist."
 msgstr "El contacto solicitado no existe."
 
@@ -1343,12 +1374,12 @@ msgstr "El contacto solicitado no existe."
 msgid "The file \"%s\" has been deleted."
 msgstr "Se ha eliminado el archivo \"%s\"."
 
-#: data.php:327
+#: data.php:406
 msgid "The import can be finished despite the warnings."
 msgstr "La importación se puede terminar a pesar de las advertencias."
 
-#: lib/Views/EditContact.php:43 lib/Views/Contact.php:59
-#: lib/Views/DeleteContact.php:36
+#: lib/Views/DeleteContact.php:36 lib/Views/Contact.php:59
+#: lib/Views/EditContact.php:43
 msgid "The requested contact was not found."
 msgstr "No se encontró el contacto solicitado."
 
@@ -1366,19 +1397,19 @@ msgstr ""
 "disponibles está configurada para permitirle añadir entradas en ellas. Si "
 "considera que esto es un error, contacte con el administrador de sistemas."
 
-#: lib/Views/Browse.php:349
+#: lib/Views/Browse.php:356
 #, php-format
 msgid "There is %d contact in this list that is not viewable to you"
 msgid_plural "There are %d contacts in this list that are not viewable to you"
 msgstr[0] "En esta lista hay %d contacto que no puede ver"
 msgstr[1] "En esta lista hay %d contactos que no puede ver"
 
-#: search.php:161
+#: search.php:146
 #, php-format
 msgid "There was a problem creating the virtual address book: %s"
 msgstr "Se produjo un error al crear la Libreta de direcciones virtual: %s"
 
-#: lib/Forms/AddContact.php:90
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
@@ -1386,7 +1417,7 @@ msgstr ""
 "Se produjo un error al añadir el contacto. Contacte al administrador de "
 "sistemas para más información."
 
-#: lib/Views/Browse.php:311
+#: lib/Views/Browse.php:318
 msgid "There was an error creating a new list."
 msgstr "Se produjo un error al crear una lista."
 
@@ -1401,25 +1432,25 @@ msgstr ""
 msgid "There was an error deleting this contact: %s"
 msgstr "Se produjo un error al eliminar este contacto: %s"
 
-#: lib/Views/Browse.php:355
+#: lib/Views/Browse.php:362
 msgid "There was an error displaying the list"
 msgstr "Se produjo un error al mostrar la lista"
 
-#: data.php:387
+#: data.php:469
 #, php-format
 msgid "There was an error importing the data: %s"
 msgstr "Se produjo un error al importar los datos: %s"
 
-#: lib/api.php:864 lib/api.php:1161
+#: lib/api.php:889 lib/api.php:1230
 msgid "There was an error importing the iCalendar data."
 msgstr "Se produjo un error al importar los datos iCalendar."
 
-#: lib/api.php:235
+#: lib/api.php:258
 #, php-format
 msgid "There was an error removing an address book for %s"
 msgstr "Se produjo un error al eliminar una Libreta de direcciones para %s"
 
-#: lib/Forms/EditContact.php:86
+#: lib/Forms/EditContact.php:93
 msgid ""
 "There was an error saving the contact. Contact your system administrator for "
 "further help."
@@ -1427,7 +1458,7 @@ msgstr ""
 "Se produjo un error al guardar el contacto. Consulte a su administrador de "
 "sistemas para más información."
 
-#: data.php:213
+#: data.php:292
 msgid "There were no addresses to export."
 msgstr "No hubo direcciones a exportar."
 
@@ -1440,11 +1471,15 @@ msgstr "Estas Libretas de direcciones se mostrar
 msgid "This addressbook cannot be deleted"
 msgstr "Esta Libreta de direcciones no se puede eliminar"
 
-#: data.php:312
+#: contact.php:57
+msgid "This contact has been marked as your own."
+msgstr "Este contacto se ha marcado como propio."
+
+#: data.php:391
 msgid "This file format is not supported."
 msgstr "Este formato de archivo no está soportado."
 
-#: lib/api.php:1729 lib/api.php:1742
+#: lib/api.php:1834 lib/api.php:1847
 #, php-format
 msgid "This person already has a %s entry in the address book"
 msgstr "Esta persona ya tiene una entrada %s en la libreta de direcciones."
@@ -1456,7 +1491,7 @@ msgstr ""
 "Ésta será la Libreta de direcciones por omisión al añadir o importar "
 "contactos."
 
-#: config/.bak/attributes.php.dist:229
+#: config/.bak/attributes.php.dist:241
 msgid "Time Zone"
 msgstr "Zona horaria"
 
@@ -1464,7 +1499,7 @@ msgstr "Zona horaria"
 msgid "Unable to find contact owner."
 msgstr "Incapaz de localizar el propietario del contacto."
 
-#: lib/Driver.php:1746 lib/Turba.php:672
+#: lib/Driver.php:1983 lib/Turba.php:662
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr "Incapaz de cargar la definición de %s."
@@ -1478,11 +1513,11 @@ msgstr "Incapaz de guardar la Libreta de direcciones \"%s\": %s"
 msgid "Unable to search."
 msgstr "Incapaz de buscar."
 
-#: config/.bak/attributes.php.dist:353
+#: config/.bak/attributes.php.dist:391
 msgid "Unfiled"
 msgstr "Sin categoría"
 
-#: lib/api.php:902 lib/api.php:1012 lib/api.php:1179
+#: lib/api.php:927 lib/api.php:1038 lib/api.php:1248
 #, php-format
 msgid "Unsupported Content-Type: %s"
 msgstr "Tipo de contenido no soportado: %s"
@@ -1500,75 +1535,75 @@ msgstr "Ver contacto"
 msgid "View to display by default:"
 msgstr "Vista mostrada por omisión:"
 
-#: config/.bak/attributes.php.dist:460
+#: config/.bak/attributes.php.dist:512
 msgid "VoIP"
 msgstr "VoIP"
 
-#: config/.bak/attributes.php.dist:320
+#: config/.bak/attributes.php.dist:344
 msgid "Website URL"
 msgstr "URL de sede Web"
 
-#: config/.bak/attributes.php.dist:173
+#: config/.bak/attributes.php.dist:185
 msgid "Work Address"
 msgstr "Dirección del trabajo"
 
-#: config/.bak/attributes.php.dist:524
+#: config/.bak/attributes.php.dist:576
 msgid "Work Address Extended"
 msgstr "Dirección del trabajo extendida"
 
-#: config/.bak/attributes.php.dist:191
+#: config/.bak/attributes.php.dist:203
 msgid "Work City"
 msgstr "Localidad del trabajo"
 
-#: config/.bak/attributes.php.dist:209
+#: config/.bak/attributes.php.dist:221
 msgid "Work Country"
 msgstr "País del trabajo"
 
-#: config/.bak/attributes.php.dist:408
+#: config/.bak/attributes.php.dist:460
 msgid "Work Email"
 msgstr "Correo del trabajo"
 
-#: config/.bak/attributes.php.dist:425
+#: config/.bak/attributes.php.dist:477
 msgid "Work Fax"
 msgstr "Fax del trabajo"
 
-#: config/.bak/attributes.php.dist:530
+#: config/.bak/attributes.php.dist:582
 msgid "Work Latitude"
 msgstr "Latitud del trabajo"
 
-#: config/.bak/attributes.php.dist:535
+#: config/.bak/attributes.php.dist:587
 msgid "Work Longitude"
 msgstr "Longitud del trabajo"
 
-#: config/.bak/attributes.php.dist:435
+#: config/.bak/attributes.php.dist:487
 msgid "Work Mobile Phone"
 msgstr "Teléfono móvil del trabajo"
 
-#: config/.bak/attributes.php.dist:254
+#: config/.bak/attributes.php.dist:266
 msgid "Work Phone"
 msgstr "Teléfono del trabajo"
 
-#: config/.bak/attributes.php.dist:185
+#: config/.bak/attributes.php.dist:197
 msgid "Work Post Office Box"
 msgstr "Buzón postal del trabajo"
 
-#: config/.bak/attributes.php.dist:203
+#: config/.bak/attributes.php.dist:215
 msgid "Work Postal Code"
 msgstr "Código postal del trabajo"
 
-#: config/.bak/attributes.php.dist:197
+#: config/.bak/attributes.php.dist:209
 msgid "Work State/Province"
 msgstr "Estado/provincia del trabajo"
 
-#: config/.bak/attributes.php.dist:179
+#: config/.bak/attributes.php.dist:191
 msgid "Work Street Address"
 msgstr "Calle del trabajo"
 
-#: config/.bak/attributes.php.dist:450
+#: config/.bak/attributes.php.dist:502
 msgid "Work Video Call"
 msgstr "Videollamada del trabajo"
 
-#: config/.bak/attributes.php.dist:518
+#: config/.bak/attributes.php.dist:570
 msgid "Work Website URL"
 msgstr "URL de sede Web del trabajo"
 
@@ -1576,7 +1611,7 @@ msgstr "URL de sede Web del trabajo"
 msgid "You are not allowed to change this addressbook."
 msgstr "Carece de permiso para modificar esta Libreta de direcciones."
 
-#: data.php:276 add.php:48 lib/Views/Browse.php:159 lib/Views/Browse.php:274
+#: data.php:355 add.php:48 lib/Views/Browse.php:159 lib/Views/Browse.php:281
 #, php-format
 msgid "You are not allowed to create more than %d contacts in \"%s\"."
 msgstr "Carece de permiso para crear más de %d contactos en \"%s\"."
@@ -1585,7 +1620,7 @@ msgstr "Carece de permiso para crear m
 msgid "You are not allowed to delete this addressbook."
 msgstr "Carece de permiso para eliminar esta Libreta de direcciones."
 
-#: lib/api.php:198
+#: lib/api.php:204
 msgid "You are not allowed to remove user data."
 msgstr "Carece de permiso para eliminar datos de usuario."
 
@@ -1601,8 +1636,12 @@ msgstr "No se pueden a
 msgid "You cannot delete contacts from a virtual address book"
 msgstr "No se pueden eliminar contactos de una Libreta de direcciones virtual."
 
-#: view.php:38 edit.php:66 lib/Views/EditContact.php:49
-#: lib/Views/DeleteContact.php:42
+#: lib/api.php:1056
+msgid "You didn't mark a contact as your own yet."
+msgstr "Aún no ha marcado un contacto como el suyo propio."
+
+#: edit.php:66 view.php:38 lib/Views/DeleteContact.php:42
+#: lib/Views/EditContact.php:49
 msgid "You do not have permission to view this contact."
 msgstr "Carece de permiso para ver este contacto."
 
@@ -1614,6 +1653,14 @@ msgstr "Carece de permiso para ver este objeto."
 msgid "You do not have permissions to delete this address book."
 msgstr "Carece de permisos para eliminar esta Libreta de direcciones."
 
+#: lib/api.php:1070
+msgid ""
+"You don't have sufficient permissions to read the address book that contains "
+"your own contact."
+msgstr ""
+"Carece de permisos suficientes para leer la Libreta de direcciones que "
+"contiene su propio contacto."
+
 #: lib/Driver/ldap.php:741
 msgid ""
 "You must have the Net_LDAP PEAR library installed to use the schema check "
@@ -1622,7 +1669,7 @@ msgstr ""
 "Tiene que haber instalado la librería PEAR Ner_LDAP para usar la función de "
 "comprobación de esquema."
 
-#: search.php:148
+#: search.php:133
 msgid "You must provide a name for virtual address books."
 msgstr ""
 "Tiene que indicar un nombre para las Libretas de direcciones virtuales."
@@ -1640,19 +1687,28 @@ msgstr "Tiene que seleccionar una lista de contactos de destino."
 msgid "You must select at least one contact first."
 msgstr "Primero tiene que seleccionar al menos un contacto."
 
-#: edit.php:70 lib/Views/EditContact.php:52 lib/Views/DeleteContact.php:45
+#: edit.php:70 lib/Views/DeleteContact.php:45 lib/Views/EditContact.php:52
 msgid "You only have permission to view this contact."
 msgstr "Sólo tiene permiso para ver este contacto."
 
-#: lib/Views/Browse.php:362
+#: lib/Views/Browse.php:369
 msgid "Your default address book is not browseable."
 msgstr "Su Libreta de direcciones por omisión no se puede examinar."
 
+#: contact.php:101 contact.php:102 templates/browse/row.inc:14
+#: templates/browse/row.inc:15
+msgid "Your own contact"
+msgstr "Su propio contacto"
+
+#: lib/api.php:1075
+msgid "Your own contact cannot be found in the address book."
+msgstr "Su propio contacto no se puede encontrar en la libreta de direcciones."
+
 #: templates/browse/contactrow.inc:12
 msgid "[no value]"
 msgstr "[sin valor]"
 
-#: lib/Turba.php:614
+#: lib/Turba.php:604
 msgid "_Browse"
 msgstr "_Examinar"
 
@@ -1664,11 +1720,11 @@ msgstr "_Contactos"
 msgid "_Delete"
 msgstr "Eli_minar"
 
-#: contact.php:85
+#: contact.php:91
 msgid "_Edit"
 msgstr "Mo_dificar"
 
-#: lib/Turba.php:623
+#: lib/Turba.php:613
 msgid "_Import/Export"
 msgstr "_Importar/Exportar"
 
@@ -1676,15 +1732,15 @@ msgstr "_Importar/Exportar"
 msgid "_Lists"
 msgstr "_Listas"
 
-#: lib/Turba.php:611
+#: lib/Turba.php:601
 msgid "_My Address Books"
 msgstr "_Mis libretas"
 
-#: lib/Turba.php:617
+#: lib/Turba.php:607
 msgid "_New Contact"
 msgstr "_Añadir"
 
-#: lib/Turba.php:628
+#: lib/Turba.php:618
 msgid "_Print"
 msgstr "I_mprimir"
 
@@ -1692,15 +1748,15 @@ msgstr "I_mprimir"
 msgid "_Remove from this list"
 msgstr "E_liminar de esta lista"
 
-#: lib/Turba.php:619
+#: lib/Turba.php:609
 msgid "_Search"
 msgstr "_Buscar"
 
-#: contact.php:82
+#: contact.php:88
 msgid "_View"
 msgstr "_Ver"
 
-#: templates/browse/column_headers.inc:24
+#: templates/browse/column_headers.inc:25
 msgid "ascending"
 msgstr "ascendente"
 
@@ -1717,36 +1773,36 @@ msgstr "por mi"
 msgid "contact"
 msgstr "contacto"
 
-#: data.php:233 data.php:238 templates/data/export.inc:1
+#: data.php:312 data.php:317 templates/data/export.inc:1
 msgid "contacts.csv"
 msgstr "contactos.csv"
 
-#: data.php:258
+#: data.php:337
 msgid "contacts.ldif"
 msgstr "contactos.ldif"
 
-#: data.php:243
+#: data.php:322
 msgid "contacts.tsv"
 msgstr "contactos.tsv"
 
-#: data.php:253
+#: data.php:332
 msgid "contacts.vcf"
 msgstr "contactos.vcf"
 
-#: templates/browse/column_headers.inc:24
+#: templates/browse/column_headers.inc:25
 msgid "descending"
 msgstr "descendente"
 
-#: config/.bak/attributes.php.dist:387
+#: config/.bak/attributes.php.dist:439
 msgid "female"
 msgstr "hembra"
 
-#: lib/Block/tree_menu.php:37
+#: lib/Block/tree_menu.php:38
 #, php-format
 msgid "in %s"
 msgstr "a %s"
 
-#: config/.bak/attributes.php.dist:387
+#: config/.bak/attributes.php.dist:439
 msgid "male"
 msgstr "macho"
 
@@ -1766,7 +1822,7 @@ msgstr "a una lista de contactos"
 msgid "to a different Address Book"
 msgstr "a una Libreta de direcciones distinta"
 
-#: data.php:88 templates/browse/column_headers.inc:13
-#: templates/data/import.inc:15 templates/data/export.inc:15
+#: data.php:103 templates/data/import.inc:15 templates/data/export.inc:15
+#: templates/browse/column_headers.inc:14
 msgid "vCard"
 msgstr "vCard"
diff --git a/po/eu_ES.po b/po/eu_ES.po
index 67a2ee3..f2ab2b8 100644
--- a/po/eu_ES.po
+++ b/po/eu_ES.po
@@ -1,5 +1,5 @@
 # Basque translations for Turba.
-# Copyright (C) 2008 Horde Project
+# Copyright 2008-2009 The Horde Project
 # This file is distributed under the same license as the Turba package.
 # Euskal Herriko Unibertsitatea EHU/UPV <xabier.arrieta at ehu.es>, 2008.
 #
diff --git a/po/fa_IR.po b/po/fa_IR.po
index d510ae9..bfe9655 100644
--- a/po/fa_IR.po
+++ b/po/fa_IR.po
@@ -1,7 +1,7 @@
 # Persian translations for Turba package.
 # This file is distributed under the same license as the Turba package.
 # 
-# Copyright (C) 2004 High Concil of Informatics (www.shci.ir)
+# Copyright 2004 High Concil of Informatics (www.shci.ir)
 # Provided by  Amirkabir Metanetworking Ltd, 2004 <persian-horde at metanetworking.com>
 # Mohsen Nader-Badr       <naderi at metanetworking.com>
 # Chakameh Mortezania     <mortezania at metanetworking.com>
diff --git a/po/fi_FI.po b/po/fi_FI.po
index de13456..e22c829 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -1,13 +1,13 @@
 # Finnish translation for Turba.
-# Copyright (C)
+# Copyright
 # Leena Heino <liinu at uta.fi>, 2001-2008.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Turba 3.0-cvs\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2008-09-16 09:23+0300\n"
-"PO-Revision-Date: 2008-09-16 12:59+0200\n"
+"POT-Creation-Date: 2009-01-29 16:00+0200\n"
+"PO-Revision-Date: 2008-12-19 12:59+0200\n"
 "Last-Translator: Leena Heino <liinu at uta.fi>\n"
 "Language-Team: Finnish <i18n at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
@@ -31,7 +31,9 @@ msgstr "\"%s\" on jo olemassa ja ei tuotu."
 #: lib/Forms/EditContact.php:83
 #, php-format
 msgid "\"%s\" updated, but saving the uploaded file failed: %s"
-msgstr "\"%s\" päivitettiin, mutta tuodun tiedoston talletus epäonnistui: %s"
+msgstr ""
+"\"%s\" päivitettiin, mutta palvelimelle tuodun tiedoston talletus "
+"epäonnistui: %s"
 
 #: lib/Forms/EditContact.php:85 lib/Forms/EditContact.php:88
 #, php-format
@@ -56,12 +58,12 @@ msgstr "\"Etunimi Sukunimi\"  (esim. Matti Meik
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr "\"Sukunimi, Etunimi\" (esim. Meikäläinen, Matti)"
 
-#: lib/Driver.php:619
+#: lib/Driver.php:620
 #, php-format
 msgid "%d. %s of %s"
 msgstr "%d. %s / %s"
 
-#: lib/Forms/AddContact.php:88
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr "%s lisätty."
@@ -110,11 +112,11 @@ msgstr "Lis
 msgid "Add to"
 msgstr "Lisää kohteeseen"
 
-#: lib/Driver.php:2113 lib/Driver/null.php:57
+#: lib/Driver.php:2115 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr "Yhteystietojen lisääminen ei ole käytettävissä."
 
-#: templates/addressbook_list.php:16
+#: templates/addressbook_list.php:16 templates/browse/search.inc:125
 msgid "Address Book"
 msgstr "Osoitekirja"
 
@@ -172,7 +174,7 @@ msgstr "Oletko varma, ett
 msgid "Are you sure that you want to delete the selected contacts?"
 msgstr "Oletko varma, että haluat poistaa valitut?"
 
-#: config/attributes.php.dist:424
+#: config/attributes.php.dist:430
 msgid "Assistant"
 msgstr "Apulainen"
 
@@ -292,45 +294,45 @@ msgstr "Pilkuilla erotetut arvot"
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr "Pilkuilla erotetut arvot (Microsoft Outlook)"
 
-#: config/attributes.php.dist:522
+#: config/attributes.php.dist:528
 msgid "Common Address Extended"
 msgstr "Laajennettu osoite (julkinen)"
 
-#: config/attributes.php.dist:540
+#: config/attributes.php.dist:546
 msgid "Common City"
 msgstr "Kaupunki (julkinen)"
 
-#: config/attributes.php.dist:558
+#: config/attributes.php.dist:564
 msgid "Common Country"
 msgstr "Maa (julkinen)"
 
-#: config/attributes.php.dist:466
+#: config/attributes.php.dist:472
 msgid "Common Phone"
 msgstr "Puhelin (julkinen)"
 
-#: config/attributes.php.dist:534
+#: config/attributes.php.dist:540
 msgid "Common Post Office Box"
 msgstr "Postilokero (julkinen)"
 
-#: config/attributes.php.dist:552
+#: config/attributes.php.dist:558
 msgid "Common Postal Code"
 msgstr "Postinumero (julkinen)"
 
-#: config/attributes.php.dist:546
+#: config/attributes.php.dist:552
 msgid "Common State/Province"
 msgstr "lääni tai alue (julkinen)"
 
-#: config/attributes.php.dist:528
+#: config/attributes.php.dist:534
 msgid "Common Street"
 msgstr "Katuosoite (julkinen)"
 
-#: config/attributes.php.dist:491
+#: config/attributes.php.dist:497
 msgid "Common Video Call"
 msgstr "Videopuhelu (julkinen)"
 
-#: config/sources.php.dist:256 config/sources.php.dist:948
+#: config/sources.php.dist:256 config/sources.php.dist:952
 msgid "Communications"
-msgstr "Kommunikaatiot"
+msgstr "Yhteystiedot"
 
 #: config/attributes.php.dist:306
 msgid "Company"
@@ -340,11 +342,12 @@ msgstr "Yritys"
 msgid "Company Address"
 msgstr "Yrityksen osoite"
 
-#: scripts/import_squirrelmail_abook.php:112 lib/api.php:546 lib/api.php:600
-#: lib/api.php:653 lib/api.php:701 lib/api.php:756 lib/api.php:815
-#: lib/api.php:866 lib/api.php:1004 lib/api.php:1066 lib/api.php:1137
-#: lib/api.php:1204 lib/api.php:1324 lib/api.php:1563 lib/api.php:1640
-#: lib/api.php:1791
+#: scripts/import_squirrelmail_file_abook.php:114
+#: scripts/import_squirrelmail_sql_abook.php:125 lib/api.php:546
+#: lib/api.php:600 lib/api.php:653 lib/api.php:701 lib/api.php:756
+#: lib/api.php:815 lib/api.php:866 lib/api.php:1004 lib/api.php:1066
+#: lib/api.php:1137 lib/api.php:1204 lib/api.php:1324 lib/api.php:1568
+#: lib/api.php:1654 lib/api.php:1806
 #, php-format
 msgid "Connection failed: %s"
 msgstr "Yhteys epäonnistui: %s"
@@ -357,7 +360,7 @@ msgstr "Yhteys ep
 msgid "Contact Search"
 msgstr "Yhteystietojen haku"
 
-#: config/sources.php.dist:866
+#: config/sources.php.dist:868
 msgid "Contacts"
 msgstr "Yhteystiedot"
 
@@ -418,7 +421,7 @@ msgstr "Poistaminen estetty."
 msgid "Delete failed: (%s) %s"
 msgstr "Poistaminen epäonnistui: (%s) %s"
 
-#: lib/Driver.php:2121 lib/Driver/null.php:62
+#: lib/Driver.php:2123 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr "Yhteystietojen poisto ei ole käytettävissä."
 
@@ -434,10 +437,6 @@ msgstr "Osasto"
 msgid "Description"
 msgstr "Kuvaus"
 
-#: templates/browse/search.inc:125
-msgid "Directory"
-msgstr "Hakemisto"
-
 #: config/prefs.php.dist:24
 msgid "Display"
 msgstr "Näkymä"
@@ -447,7 +446,7 @@ msgstr "N
 msgid "Display Options"
 msgstr "Näkymän asetukset"
 
-#: lib/Object.php:354
+#: lib/Object.php:360
 msgid "Download"
 msgstr "Tallenna"
 
@@ -604,7 +603,7 @@ msgstr "Freebusy URL"
 msgid "From"
 msgstr "Lähde"
 
-#: config/attributes.php.dist:430
+#: config/attributes.php.dist:436
 msgid "Gender"
 msgstr "Sukupuoli"
 
@@ -620,7 +619,7 @@ msgstr "Ryhm
 msgid "Home Address"
 msgstr "Osoite (koti)"
 
-#: config/attributes.php.dist:592
+#: config/attributes.php.dist:598
 msgid "Home Address Extended"
 msgstr "Laajennettu kotiosoite"
 
@@ -632,23 +631,23 @@ msgstr "Kaupunki (koti)"
 msgid "Home Country"
 msgstr "Maa (koti)"
 
-#: config/attributes.php.dist:460
+#: config/attributes.php.dist:466
 msgid "Home Email"
 msgstr "Sähköposti (koti)"
 
-#: config/attributes.php.dist:476
+#: config/attributes.php.dist:482
 msgid "Home Fax"
 msgstr "Faksi (koti)"
 
-#: config/attributes.php.dist:598
+#: config/attributes.php.dist:604
 msgid "Home Latitude"
 msgstr "Korkeuspiiri (koti)"
 
-#: config/attributes.php.dist:603
+#: config/attributes.php.dist:609
 msgid "Home Longitude"
 msgstr "Pituuspiiri (koti)"
 
-#: config/attributes.php.dist:486
+#: config/attributes.php.dist:492
 msgid "Home Mobile Phone"
 msgstr "Matkapuhelin (koti)"
 
@@ -672,11 +671,11 @@ msgstr "L
 msgid "Home Street Address"
 msgstr "Katuosoite (koti)"
 
-#: config/attributes.php.dist:501
+#: config/attributes.php.dist:507
 msgid "Home Video Call"
 msgstr "Videopuhelu (koti)"
 
-#: config/attributes.php.dist:586
+#: config/attributes.php.dist:592
 msgid "Home Website URL"
 msgstr "www-sivuston URL (koti)"
 
@@ -693,11 +692,11 @@ msgstr "Osoitekirjan tuonti, askel %d"
 msgid "Import/Export Address Books"
 msgstr "Tuo/Vie osoitekirjoja"
 
-#: config/attributes.php.dist:406
+#: config/attributes.php.dist:412
 msgid "Initials"
 msgstr "Nimikirjaimet"
 
-#: config/attributes.php.dist:412
+#: config/attributes.php.dist:418
 msgid "Instant Messenger"
 msgstr "Pikaviestin"
 
@@ -705,9 +704,10 @@ msgstr "Pikaviestin"
 msgid "Invalid ID"
 msgstr "Virheellinen ID"
 
-#: scripts/import_squirrelmail_abook.php:105 lib/api.php:368 lib/api.php:696
-#: lib/api.php:751 lib/api.php:810 lib/api.php:859 lib/api.php:995
-#: lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
+#: scripts/import_squirrelmail_file_abook.php:107
+#: scripts/import_squirrelmail_sql_abook.php:118 lib/api.php:368
+#: lib/api.php:696 lib/api.php:751 lib/api.php:810 lib/api.php:859
+#: lib/api.php:995 lib/api.php:1128 lib/api.php:1194 lib/api.php:1789
 #, php-format
 msgid "Invalid address book: %s"
 msgstr "Epäkelpo osoitekirja: %s"
@@ -716,11 +716,11 @@ msgstr "Ep
 msgid "Invalid contact unique ID"
 msgstr "Epäkelpo yhteistietojen yksikäsitteinen ID"
 
-#: lib/api.php:1778 lib/api.php:1864 lib/api.php:1925
+#: lib/api.php:1793 lib/api.php:1879 lib/api.php:1940
 msgid "Invalid email"
 msgstr "Virheellinen sähköpostiosoite"
 
-#: lib/api.php:1786
+#: lib/api.php:1801
 msgid "Invalid entry"
 msgstr "Virheellinen merkintä"
 
@@ -728,7 +728,7 @@ msgstr "Virheellinen merkint
 msgid "Invalid key specified."
 msgstr "Määritelty avain on virheellinen"
 
-#: lib/api.php:1782
+#: lib/api.php:1797
 msgid "Invalid name"
 msgstr "Virheellinen nimi"
 
@@ -736,11 +736,20 @@ msgstr "Virheellinen nimi"
 msgid "Job Title"
 msgstr "Titteli"
 
-#: lib/Driver/kolab.php:1129 lib/Driver/kolab.php:1195
+#: lib/Driver/kolab.php:1119
+#, php-format
+msgid "Key for saving must be \\'uid\\' not %s!"
+msgstr "Tallennusavain pitää olla \\'uid\\' ei %s!"
+
+#: lib/Driver/kolab.php:1203
 #, php-format
 msgid "Key for saving must be a UID not %s!"
 msgstr "Tallennusavain pitää olla UID ei %s!"
 
+#: config/attributes.php.dist:406
+msgid "Kolab Home Server"
+msgstr "Kolab kotipalvelin"
+
 #: lib/Driver/ldap.php:64
 msgid ""
 "LDAP support is required but the LDAP module is not available or not loaded."
@@ -751,7 +760,7 @@ msgstr ""
 msgid "LDIF Address Book"
 msgstr "LDIF-Osoitekirja"
 
-#: config/attributes.php.dist:436
+#: config/attributes.php.dist:442
 msgid "Language"
 msgstr "Kieli"
 
@@ -763,7 +772,7 @@ msgstr "Muokattu viimeksi"
 msgid "Last Name"
 msgstr "Sukunimi"
 
-#: config/attributes.php.dist:442
+#: config/attributes.php.dist:448
 msgid "Latitude"
 msgstr "Korkeuspiiri"
 
@@ -771,9 +780,9 @@ msgstr "Korkeuspiiri"
 msgid "List"
 msgstr "Lista"
 
-#: config/sources.php.dist:251 config/sources.php.dist:944
+#: config/sources.php.dist:251 config/sources.php.dist:948
 msgid "Location"
-msgstr "Paikka"
+msgstr "Osoitetiedot"
 
 #: config/attributes.php.dist:324
 msgid "Logo"
@@ -783,7 +792,7 @@ msgstr "Logo"
 msgid "Logo MIME Type"
 msgstr "Logon MIME-tyyppi"
 
-#: config/attributes.php.dist:447
+#: config/attributes.php.dist:453
 msgid "Longitude"
 msgstr "Pituuspiiri"
 
@@ -795,7 +804,7 @@ msgstr "Ep
 msgid "Manage Address Books"
 msgstr "Hallinnoin osoitekirjoja"
 
-#: config/attributes.php.dist:418
+#: config/attributes.php.dist:424
 msgid "Manager"
 msgstr "Johtaja"
 
@@ -840,7 +849,7 @@ msgstr "Muokkaus ep
 msgid "More Options..."
 msgstr "Muut asetukset..."
 
-#: lib/api.php:1902
+#: lib/api.php:1917
 msgid "More than 1 entry found"
 msgstr "Löytyi useampi kuin 1 merkintää"
 
@@ -860,7 +869,7 @@ msgstr "Siirr
 msgid "Mulberry Address Book"
 msgstr "Mulberry-osoitekirja"
 
-#: lib/api.php:1810
+#: lib/api.php:1825
 #, php-format
 msgid ""
 "Multiple persons with address [%s], but none with name [%s] already exist"
@@ -906,7 +915,7 @@ msgstr "Seuraava"
 msgid "Nickname"
 msgstr "Lempinimi"
 
-#: lib/api.php:1905 lib/api.php:1965
+#: lib/api.php:1920 lib/api.php:1980
 #, php-format
 msgid "No %s entry found for %s"
 msgstr "Merkintää %s ei löytynyt %s:lle"
@@ -970,7 +979,7 @@ msgstr "Tietoja lukum
 msgid "Object not found"
 msgstr "Objektia ei löytynyt"
 
-#: lib/Driver/kolab.php:1199
+#: lib/Driver/kolab.php:1207
 #, php-format
 msgid "Object with UID %s does not exist!"
 msgstr "Objektia UID:lla %s ei ole olemassa!"
@@ -997,19 +1006,19 @@ msgstr ""
 msgid "Only one vcard supported."
 msgstr "Tuettuna vain yksi vcard."
 
-#: config/sources.php.dist:258 config/sources.php.dist:950
+#: config/sources.php.dist:258 config/sources.php.dist:954
 msgid "Organization"
-msgstr "Järjestö"
+msgstr "Organisaatiotiedot"
 
-#: config/sources.php.dist:259 config/sources.php.dist:952
+#: config/sources.php.dist:259 config/sources.php.dist:956
 msgid "Other"
-msgstr "Muut"
+msgstr "Muut tiedot"
 
 #: config/attributes.php.dist:356
 msgid "PGP Public Key"
 msgstr "Julkinen PGP-avain"
 
-#: config/attributes.php.dist:517
+#: config/attributes.php.dist:523
 msgid "PTT"
 msgstr "PTT"
 
@@ -1021,14 +1030,14 @@ msgstr "Hakulaite"
 msgid "Permanently delete this contact?"
 msgstr "Haluatko lopullisesti poistaa tämän yhteystiedon?"
 
-#: deletefile.php:36 lib/Driver.php:804 lib/api.php:870 lib/api.php:1795
+#: deletefile.php:36 lib/Driver.php:805 lib/api.php:870 lib/api.php:1810
 #: lib/Driver/sql.php:515
 msgid "Permission denied"
 msgstr "Käyttö kielletty"
 
-#: config/sources.php.dist:248 config/sources.php.dist:940
+#: config/sources.php.dist:248 config/sources.php.dist:944
 msgid "Personal"
-msgstr "Yksityinen"
+msgstr "Henkilötiedot"
 
 #: config/attributes.php.dist:121
 msgid "Photo"
@@ -1061,7 +1070,7 @@ msgstr "Kysely ep
 msgid "Read failed: (%s) %s"
 msgstr "Luku epäonnistui: (%s) %s"
 
-#: lib/Driver.php:2105 lib/Driver/null.php:52
+#: lib/Driver.php:2107 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr "Yhteystietojen luku ei ole käytettävissä."
 
@@ -1082,7 +1091,7 @@ msgstr "Poista osoitekirja"
 msgid "Remove from this list"
 msgstr "Poista tältä listalta"
 
-#: lib/Driver.php:2143
+#: lib/Driver.php:2145
 msgid ""
 "Removing user data is not supported in the current address book storage "
 "driver."
@@ -1097,7 +1106,7 @@ msgstr ""
 "Korvaa olemassaoleva osoitekirja tuodulla osoitekirjalla. <strong>Varoitus: "
 "Tämä poistaa kaikki merkinnät nykyisestä osoitekirjastasi.</strong>"
 
-#: lib/Driver.php:698
+#: lib/Driver.php:699
 msgid "Requested object not found."
 msgstr "Pyydettyä objektia ei löytynyt."
 
@@ -1109,7 +1118,7 @@ msgstr "Palauta oletukset"
 msgid "S/MIME Public Certificate"
 msgstr "Julkinen S/MIME-varmenne"
 
-#: config/attributes.php.dist:511
+#: config/attributes.php.dist:517
 msgid "SIP"
 msgstr "SIP"
 
@@ -1126,7 +1135,7 @@ msgstr "Talleta"
 msgid "Save search as a virtual address book?"
 msgstr "Talleta haku virtuaaliseen osoitekirjaan?"
 
-#: lib/Driver.php:2131 lib/Driver/null.php:67
+#: lib/Driver.php:2133 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr "Yhteystietojen talletus ei ole käytettävissä."
 
@@ -1136,11 +1145,11 @@ msgstr "Yhteystietojen talletus ei ole k
 msgid "Search"
 msgstr "Haku"
 
-#: lib/api.php:1568
+#: lib/api.php:1573
 msgid "Search failed"
 msgstr "Haku epäonnistui"
 
-#: lib/api.php:1800 lib/api.php:1806 lib/api.php:1815 lib/api.php:1828
+#: lib/api.php:1815 lib/api.php:1821 lib/api.php:1830 lib/api.php:1843
 #, php-format
 msgid "Search failed: %s"
 msgstr "Haku epäonnistui: %s"
@@ -1149,7 +1158,7 @@ msgstr "Haku ep
 msgid "Search for: "
 msgstr "Haetaan kohdetta: "
 
-#: lib/Driver.php:2090 lib/Driver/null.php:47
+#: lib/Driver.php:2092 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr "Haku ei ole käytettävissä."
 
@@ -1312,9 +1321,10 @@ msgstr "Tiedostossa %s ei ollut ainuttakaan yhteystietoa."
 #: view.php:17
 msgid "The VFS backend needs to be configured to enable attachment uploads."
 msgstr ""
-"VFS-taustajärjestelmä pitää olla käytettävissä ennenkuin liitteitä voi tuoda."
+"VFS-taustajärjestelmä pitää olla käytettävissä ennenkuin liitteitä voi tuoda "
+"palvelimelle."
 
-#: lib/Driver.php:2061
+#: lib/Driver.php:2063
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr "Osoitekirjaa \"%s\" ei ole olemassa."
@@ -1394,7 +1404,7 @@ msgstr[1] ""
 msgid "There was a problem creating the virtual address book: %s"
 msgstr "Tapahtui virhe luotaessa virtuaalista osoitekirjaa: %s"
 
-#: lib/Forms/AddContact.php:95
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
@@ -1463,7 +1473,7 @@ msgstr "T
 msgid "This file format is not supported."
 msgstr "Tämä tiedostomuoto ei ole tuettu."
 
-#: lib/api.php:1819 lib/api.php:1832
+#: lib/api.php:1834 lib/api.php:1847
 #, php-format
 msgid "This person already has a %s entry in the address book"
 msgstr "Tällä henkilöllä on jo %s merkintä osoitekirjassa"
@@ -1481,7 +1491,7 @@ msgstr "Aikavy
 msgid "Unable to find contact owner."
 msgstr "Yhteystiedon omistajaa ei löytynyt."
 
-#: lib/Driver.php:1981 lib/Turba.php:659
+#: lib/Driver.php:1983 lib/Turba.php:662
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr "Määrityksen %s lukeminen epäonnistui."
@@ -1517,7 +1527,7 @@ msgstr "N
 msgid "View to display by default:"
 msgstr "Oletuksena käytettävä näkymä:"
 
-#: config/attributes.php.dist:506
+#: config/attributes.php.dist:512
 msgid "VoIP"
 msgstr "VoIP"
 
@@ -1529,7 +1539,7 @@ msgstr "Website URL"
 msgid "Work Address"
 msgstr "Osoite (työ)"
 
-#: config/attributes.php.dist:570
+#: config/attributes.php.dist:576
 msgid "Work Address Extended"
 msgstr "Laajennettu osoite (työ)"
 
@@ -1541,23 +1551,23 @@ msgstr "Kaupunki (ty
 msgid "Work Country"
 msgstr "Maa (työ)"
 
-#: config/attributes.php.dist:454
+#: config/attributes.php.dist:460
 msgid "Work Email"
 msgstr "Sähköposti (työ)"
 
-#: config/attributes.php.dist:471
+#: config/attributes.php.dist:477
 msgid "Work Fax"
 msgstr "Faksi (työ)"
 
-#: config/attributes.php.dist:576
+#: config/attributes.php.dist:582
 msgid "Work Latitude"
 msgstr "Korkeuspiiri (työ)"
 
-#: config/attributes.php.dist:581
+#: config/attributes.php.dist:587
 msgid "Work Longitude"
 msgstr "Pituuspiiri (työ)"
 
-#: config/attributes.php.dist:481
+#: config/attributes.php.dist:487
 msgid "Work Mobile Phone"
 msgstr "Matkapuhelin (työ)"
 
@@ -1581,11 +1591,11 @@ msgstr "L
 msgid "Work Street Address"
 msgstr "Katuosoite (työ)"
 
-#: config/attributes.php.dist:496
+#: config/attributes.php.dist:502
 msgid "Work Video Call"
 msgstr "Videopuhelu (työ)"
 
-#: config/attributes.php.dist:564
+#: config/attributes.php.dist:570
 msgid "Work Website URL"
 msgstr "Www-sivusto URL (työ)"
 
@@ -1689,7 +1699,7 @@ msgstr "Omia yhteystietoja ei l
 msgid "[no value]"
 msgstr "[ei tietoja]"
 
-#: lib/Turba.php:601
+#: lib/Turba.php:604
 msgid "_Browse"
 msgstr "_Selaa"
 
@@ -1705,7 +1715,7 @@ msgstr "_Poista"
 msgid "_Edit"
 msgstr "_Muokkaa"
 
-#: lib/Turba.php:610
+#: lib/Turba.php:613
 msgid "_Import/Export"
 msgstr "_Tuo/Vie"
 
@@ -1713,15 +1723,15 @@ msgstr "_Tuo/Vie"
 msgid "_Lists"
 msgstr "_Listat"
 
-#: lib/Turba.php:598
+#: lib/Turba.php:601
 msgid "_My Address Books"
 msgstr "O_mat osoitekirjat"
 
-#: lib/Turba.php:604
+#: lib/Turba.php:607
 msgid "_New Contact"
 msgstr "_Uusi yhteystieto"
 
-#: lib/Turba.php:615
+#: lib/Turba.php:618
 msgid "_Print"
 msgstr "_Tulosta"
 
@@ -1729,7 +1739,7 @@ msgstr "_Tulosta"
 msgid "_Remove from this list"
 msgstr "_Poista tältä listalta"
 
-#: lib/Turba.php:606
+#: lib/Turba.php:609
 msgid "_Search"
 msgstr "_Haku"
 
@@ -1774,7 +1784,7 @@ msgstr "contacts.vcf"
 msgid "descending"
 msgstr "laskeva"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "female"
 msgstr "nainen"
 
@@ -1783,7 +1793,7 @@ msgstr "nainen"
 msgid "in %s"
 msgstr "%s:ssä"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "male"
 msgstr "mies"
 
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 265d6ea..48f4617 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -1,4 +1,4 @@
-# translation of fr.po to french
+# translation of fr_FR.po to french
 # French translation of Turba 2.2-cvs
 # Turba french translation.
 # Copyright (C) 2001-2002.
@@ -9,13 +9,13 @@
 # Benoit St-André <ben at benoitst-andre.net>, 2004.
 # Thierry Thomas <thierry at pompo.net>, 2002, 2003, 2005, 2006, 2007.
 # Yannick Sebastia <yannick.sebastia at ecole-navale.fr>, 2008.
-# Yannick Sebastia, Benoit Poulet <yannick.sebastia at ecole-navale.fr, benoit.poulet at businessdecision.com>, 2008.
+# Yannick Sebastia, Benoit Poulet <yannick.sebastia at ecole-navale.fr, benoit.poulet at businessdecision.com>, 2008, 2009.
 msgid ""
 msgstr ""
-"Project-Id-Version: fr\n"
+"Project-Id-Version: fr_FR\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2008-09-25 12:32+0200\n"
-"PO-Revision-Date: 2008-11-28 15:51+0100\n"
+"POT-Creation-Date: 2009-05-22 08:31+0200\n"
+"PO-Revision-Date: 2009-05-22 08:32+0200\n"
 "Last-Translator: Yannick Sebastia <yannick.sebastia at ecole-navale.fr>\n"
 "Language-Team: Français <i18n at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
@@ -66,12 +66,12 @@ msgstr "
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr "« Nom, Prénom »  (c. à d.. Tremblay, Michel)"
 
-#: lib/Driver.php:619
+#: lib/Driver.php:620
 #, php-format
 msgid "%d. %s of %s"
 msgstr "%d. %s de %s"
 
-#: lib/Forms/AddContact.php:88
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr "%s ajouté."
@@ -100,7 +100,7 @@ msgstr "Un navigateur supportant les cadres (iFrames) est requis"
 msgid "Access denied to %s"
 msgstr "Accès à %s refusé"
 
-#: templates/browse/actions.inc:30 lib/Forms/AddContact.php:25
+#: lib/Forms/AddContact.php:25 templates/browse/actions.inc:30
 msgid "Add"
 msgstr "Ajouter"
 
@@ -120,7 +120,7 @@ msgstr "Ajouter un fichier"
 msgid "Add to"
 msgstr "Ajouter à"
 
-#: lib/Driver.php:2113 lib/Driver/null.php:57
+#: lib/Driver.php:2115 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr "L'ajout de contacts n'est pas disponible."
 
@@ -182,7 +182,7 @@ msgstr "
 msgid "Are you sure that you want to delete the selected contacts?"
 msgstr "Êtes-vous certain de vouloir supprimer les contacts sélectionnés ?"
 
-#: config/attributes.php.dist:424
+#: config/attributes.php.dist:430
 msgid "Assistant"
 msgstr "Assistant"
 
@@ -302,43 +302,43 @@ msgstr "Valeurs s
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr "Valeurs séparées par des virgules (Microsoft Outlook)"
 
-#: config/attributes.php.dist:522
+#: config/attributes.php.dist:528
 msgid "Common Address Extended"
 msgstr "Adresse"
 
-#: config/attributes.php.dist:540
+#: config/attributes.php.dist:546
 msgid "Common City"
 msgstr "Ville"
 
-#: config/attributes.php.dist:558
+#: config/attributes.php.dist:564
 msgid "Common Country"
 msgstr "Pays"
 
-#: config/attributes.php.dist:466
+#: config/attributes.php.dist:472
 msgid "Common Phone"
 msgstr "Téléphone"
 
-#: config/attributes.php.dist:534
+#: config/attributes.php.dist:540
 msgid "Common Post Office Box"
 msgstr "Boite postale"
 
-#: config/attributes.php.dist:552
+#: config/attributes.php.dist:558
 msgid "Common Postal Code"
 msgstr "Code postal"
 
-#: config/attributes.php.dist:546
+#: config/attributes.php.dist:552
 msgid "Common State/Province"
 msgstr "État/Province"
 
-#: config/attributes.php.dist:528
+#: config/attributes.php.dist:534
 msgid "Common Street"
 msgstr "Rue commune"
 
-#: config/attributes.php.dist:491
+#: config/attributes.php.dist:497
 msgid "Common Video Call"
 msgstr "Cisiophone commun"
 
-#: config/sources.php.dist:256 config/sources.php.dist:948
+#: config/sources.php.dist:256 config/sources.php.dist:952
 msgid "Communications"
 msgstr "Communications"
 
@@ -350,11 +350,12 @@ msgstr "Soci
 msgid "Company Address"
 msgstr "Adresse professionnelle"
 
-#: scripts/import_squirrelmail_abook.php:112 lib/api.php:546 lib/api.php:600
-#: lib/api.php:653 lib/api.php:701 lib/api.php:756 lib/api.php:815
-#: lib/api.php:866 lib/api.php:1004 lib/api.php:1066 lib/api.php:1137
-#: lib/api.php:1204 lib/api.php:1324 lib/api.php:1563 lib/api.php:1640
-#: lib/api.php:1791
+#: scripts/import_squirrelmail_sql_abook.php:125
+#: scripts/import_squirrelmail_file_abook.php:114 lib/api.php:546
+#: lib/api.php:600 lib/api.php:653 lib/api.php:701 lib/api.php:756
+#: lib/api.php:815 lib/api.php:866 lib/api.php:1004 lib/api.php:1066
+#: lib/api.php:1137 lib/api.php:1204 lib/api.php:1324 lib/api.php:1563
+#: lib/api.php:1640 lib/api.php:1791
 #, php-format
 msgid "Connection failed: %s"
 msgstr "La connexion a échoué : %s"
@@ -367,7 +368,7 @@ msgstr "
 msgid "Contact Search"
 msgstr "Recherche de contacts"
 
-#: config/sources.php.dist:866
+#: config/sources.php.dist:868
 msgid "Contacts"
 msgstr "Contacts"
 
@@ -408,13 +409,13 @@ msgstr "Cr
 msgid "De_lete"
 msgstr "_Supprimer"
 
+#: lib/Forms/DeleteAddressBook.php:45 lib/Views/DeleteContact.php:58
 #: templates/addressbook_list.php:35 templates/browse/actions.inc:3
-#: addressbooks/index.php:42 lib/Views/DeleteContact.php:58
-#: lib/Forms/DeleteAddressBook.php:45
+#: addressbooks/index.php:42
 msgid "Delete"
 msgstr "Effacer"
 
-#: lib/Views/DeleteContact.php:28 lib/Forms/DeleteAddressBook.php:40
+#: lib/Forms/DeleteAddressBook.php:40 lib/Views/DeleteContact.php:28
 #, php-format
 msgid "Delete %s"
 msgstr "Supprimer %s"
@@ -428,7 +429,7 @@ msgstr "Suppression refus
 msgid "Delete failed: (%s) %s"
 msgstr "Échec de la suppression : (%s) %s"
 
-#: lib/Driver.php:2121 lib/Driver/null.php:62
+#: lib/Driver.php:2123 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr "La suppression des contacts n'est pas disponible."
 
@@ -440,7 +441,7 @@ msgstr "
 msgid "Department"
 msgstr "Département"
 
-#: lib/Forms/EditAddressBook.php:44 lib/Forms/CreateAddressBook.php:37
+#: lib/Forms/CreateAddressBook.php:37 lib/Forms/EditAddressBook.php:44
 msgid "Description"
 msgstr "Description"
 
@@ -457,7 +458,7 @@ msgstr "Affichage"
 msgid "Display Options"
 msgstr "Options d'affichage"
 
-#: lib/Object.php:354
+#: lib/Object.php:357
 msgid "Download"
 msgstr "Télécharger"
 
@@ -467,8 +468,8 @@ msgid "Download vCard"
 msgstr "Télécharger vCard"
 
 #: templates/addressbook_list.php:31 templates/browse/row.inc:40
-#: templates/browse/row.inc:41 templates/browse/column_headers.inc:11
-#: templates/browse/actions.inc:6 templates/browse/contactrow.inc:33
+#: templates/browse/row.inc:41 templates/browse/contactrow.inc:33
+#: templates/browse/column_headers.inc:11 templates/browse/actions.inc:6
 #: addressbooks/index.php:40
 msgid "Edit"
 msgstr "Éditer"
@@ -478,7 +479,7 @@ msgstr "
 msgid "Edit \"%s\""
 msgstr "Éditer « %s »"
 
-#: lib/Views/EditContact.php:35 lib/Forms/EditAddressBook.php:40
+#: lib/Forms/EditAddressBook.php:40 lib/Views/EditContact.php:35
 #, php-format
 msgid "Edit %s"
 msgstr "Éditer %s"
@@ -526,7 +527,7 @@ msgstr "Erreur lors du retrait de la liste de %d contact(s) sur %d."
 msgid "Error searching the address book: %s"
 msgstr "Erreur lors de la recherche dans le carnet d'adresse : %s"
 
-#: templates/browse/actions.inc:10 templates/data/export.inc:42
+#: templates/data/export.inc:42 templates/browse/actions.inc:10
 msgid "Export"
 msgstr "Exporter"
 
@@ -542,7 +543,7 @@ msgstr "N'exporter que les contacts s
 msgid "Export the following address book completely."
 msgstr "Exporter en totalité le carnet d'adresses suivant."
 
-#: data.php:247 data.php:346 data.php:424 add.php:42 search.php:106
+#: search.php:106 add.php:42 data.php:247 data.php:346 data.php:424
 #: lib/Views/Browse.php:84 lib/Views/Browse.php:152 lib/Views/Browse.php:180
 #, php-format
 msgid "Failed to access the address book: %s"
@@ -614,7 +615,7 @@ msgstr "URL des disponibilit
 msgid "From"
 msgstr "Dans"
 
-#: config/attributes.php.dist:430
+#: config/attributes.php.dist:436
 msgid "Gender"
 msgstr "Genre"
 
@@ -630,7 +631,7 @@ msgstr "Groupe"
 msgid "Home Address"
 msgstr "Adresse domicile"
 
-#: config/attributes.php.dist:592
+#: config/attributes.php.dist:598
 msgid "Home Address Extended"
 msgstr "Adresse domicile étendue"
 
@@ -642,23 +643,23 @@ msgstr "Ville"
 msgid "Home Country"
 msgstr "Pays"
 
-#: config/attributes.php.dist:460
+#: config/attributes.php.dist:466
 msgid "Home Email"
 msgstr "Courriel"
 
-#: config/attributes.php.dist:476
+#: config/attributes.php.dist:482
 msgid "Home Fax"
 msgstr "Fax"
 
-#: config/attributes.php.dist:598
+#: config/attributes.php.dist:604
 msgid "Home Latitude"
 msgstr "Latitude"
 
-#: config/attributes.php.dist:603
+#: config/attributes.php.dist:609
 msgid "Home Longitude"
 msgstr "Longitude"
 
-#: config/attributes.php.dist:486
+#: config/attributes.php.dist:492
 msgid "Home Mobile Phone"
 msgstr "Téléphone mobile"
 
@@ -682,11 +683,11 @@ msgstr "
 msgid "Home Street Address"
 msgstr "Rue"
 
-#: config/attributes.php.dist:501
+#: config/attributes.php.dist:507
 msgid "Home Video Call"
 msgstr "Visiophone personnel"
 
-#: config/attributes.php.dist:586
+#: config/attributes.php.dist:592
 msgid "Home Website URL"
 msgstr "URL du site web"
 
@@ -703,11 +704,11 @@ msgstr "Importer un carnet d'adresses, 
 msgid "Import/Export Address Books"
 msgstr "Importer/Exporter carnet d'adresses"
 
-#: config/attributes.php.dist:406
+#: config/attributes.php.dist:412
 msgid "Initials"
 msgstr "Initiales"
 
-#: config/attributes.php.dist:412
+#: config/attributes.php.dist:418
 msgid "Instant Messenger"
 msgstr "Messagerie instantanée"
 
@@ -715,9 +716,10 @@ msgstr "Messagerie instantan
 msgid "Invalid ID"
 msgstr "Identifiant invalide"
 
-#: scripts/import_squirrelmail_abook.php:105 lib/api.php:368 lib/api.php:696
-#: lib/api.php:751 lib/api.php:810 lib/api.php:859 lib/api.php:995
-#: lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
+#: scripts/import_squirrelmail_sql_abook.php:118
+#: scripts/import_squirrelmail_file_abook.php:107 lib/api.php:368
+#: lib/api.php:696 lib/api.php:751 lib/api.php:810 lib/api.php:859
+#: lib/api.php:995 lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
 #, php-format
 msgid "Invalid address book: %s"
 msgstr "Carnet d'adresses invalide : %s"
@@ -746,11 +748,20 @@ msgstr "Nom invalide"
 msgid "Job Title"
 msgstr "Fonction"
 
-#: lib/Driver/kolab.php:1129 lib/Driver/kolab.php:1195
+#: lib/Driver/kolab.php:1119
+#, php-format
+msgid "Key for saving must be \\'uid\\' not %s!"
+msgstr "La clé de sauvegarde doit être un \\'UID\\' pas %s!"
+
+#: lib/Driver/kolab.php:1203
 #, php-format
 msgid "Key for saving must be a UID not %s!"
 msgstr "La clé de sauvegarde doit être un UID pas %s!"
 
+#: config/attributes.php.dist:406
+msgid "Kolab Home Server"
+msgstr "Serveur Kolab"
+
 #: lib/Driver/ldap.php:64
 msgid ""
 "LDAP support is required but the LDAP module is not available or not loaded."
@@ -762,7 +773,7 @@ msgstr ""
 msgid "LDIF Address Book"
 msgstr "Carnet d'adresses au format LDIF"
 
-#: config/attributes.php.dist:436
+#: config/attributes.php.dist:442
 msgid "Language"
 msgstr "Langue"
 
@@ -774,7 +785,7 @@ msgstr "Derni
 msgid "Last Name"
 msgstr "Nom de famille"
 
-#: config/attributes.php.dist:442
+#: config/attributes.php.dist:448
 msgid "Latitude"
 msgstr "Latitude"
 
@@ -782,7 +793,7 @@ msgstr "Latitude"
 msgid "List"
 msgstr "Liste"
 
-#: config/sources.php.dist:251 config/sources.php.dist:944
+#: config/sources.php.dist:251 config/sources.php.dist:948
 msgid "Location"
 msgstr "Lieu"
 
@@ -794,7 +805,7 @@ msgstr "Logo"
 msgid "Logo MIME Type"
 msgstr "Type MIME du logo"
 
-#: config/attributes.php.dist:447
+#: config/attributes.php.dist:453
 msgid "Longitude"
 msgstr "Longitude"
 
@@ -806,7 +817,7 @@ msgstr "Requ
 msgid "Manage Address Books"
 msgstr "Gérer les annuaires"
 
-#: config/attributes.php.dist:418
+#: config/attributes.php.dist:424
 msgid "Manager"
 msgstr "Supérieur"
 
@@ -883,7 +894,7 @@ msgstr ""
 msgid "My Address Book"
 msgstr "Mon annuaire"
 
-#: lib/Forms/EditAddressBook.php:43 lib/Forms/CreateAddressBook.php:36
+#: lib/Forms/CreateAddressBook.php:36 lib/Forms/EditAddressBook.php:43
 #: config/attributes.php.dist:47
 msgid "Name"
 msgstr "Nom complet"
@@ -908,8 +919,8 @@ msgstr "Nom :"
 msgid "New Contact"
 msgstr "Nouveau contact"
 
-#: templates/data/import.inc:46 lib/Forms/EditContact.php:119
-#: lib/Forms/EditContact.php:126 lib/Forms/EditContact.php:181
+#: lib/Forms/EditContact.php:119 lib/Forms/EditContact.php:126
+#: lib/Forms/EditContact.php:181 templates/data/import.inc:46
 msgid "Next"
 msgstr "Suivant"
 
@@ -984,7 +995,7 @@ msgstr "Nombre d'items par page"
 msgid "Object not found"
 msgstr "Sujet non trouvé"
 
-#: lib/Driver/kolab.php:1199
+#: lib/Driver/kolab.php:1207
 #, php-format
 msgid "Object with UID %s does not exist!"
 msgstr "L'objet avec l'UID %s n'existe pas !"
@@ -1011,11 +1022,11 @@ msgstr ""
 msgid "Only one vcard supported."
 msgstr "Une seule vCard est supportée."
 
-#: config/sources.php.dist:258 config/sources.php.dist:950
+#: config/sources.php.dist:258 config/sources.php.dist:954
 msgid "Organization"
 msgstr "Organisation"
 
-#: config/sources.php.dist:259 config/sources.php.dist:952
+#: config/sources.php.dist:259 config/sources.php.dist:956
 msgid "Other"
 msgstr "Autre"
 
@@ -1023,7 +1034,7 @@ msgstr "Autre"
 msgid "PGP Public Key"
 msgstr "Clé publique PGP"
 
-#: config/attributes.php.dist:517
+#: config/attributes.php.dist:523
 msgid "PTT"
 msgstr "PTT"
 
@@ -1035,12 +1046,12 @@ msgstr "R
 msgid "Permanently delete this contact?"
 msgstr "Effacer ce contact définitivement ?"
 
-#: deletefile.php:36 lib/Driver.php:804 lib/api.php:870 lib/api.php:1795
+#: deletefile.php:36 lib/api.php:870 lib/api.php:1795 lib/Driver.php:805
 #: lib/Driver/sql.php:515
 msgid "Permission denied"
 msgstr "Permission refusée"
 
-#: config/sources.php.dist:248 config/sources.php.dist:940
+#: config/sources.php.dist:248 config/sources.php.dist:944
 msgid "Personal"
 msgstr "Petite annonce personnelle"
 
@@ -1075,7 +1086,7 @@ msgstr "
 msgid "Read failed: (%s) %s"
 msgstr "Échec de lecture : (%s) %s"
 
-#: lib/Driver.php:2105 lib/Driver/null.php:52
+#: lib/Driver.php:2107 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr "La lecture des contacts n'est pas disponible."
 
@@ -1096,7 +1107,7 @@ msgstr "Supprimer un carnet d'adresses"
 msgid "Remove from this list"
 msgstr "Retirer de la liste"
 
-#: lib/Driver.php:2143
+#: lib/Driver.php:2145
 msgid ""
 "Removing user data is not supported in the current address book storage "
 "driver."
@@ -1113,7 +1124,7 @@ msgstr ""
 "<strong>Attention : cela supprimera toutes vos entrées du présent carnet "
 "d'adresses.</strong>"
 
-#: lib/Driver.php:698
+#: lib/Driver.php:699
 msgid "Requested object not found."
 msgstr "Sujet non trouvé."
 
@@ -1125,7 +1136,7 @@ msgstr "R
 msgid "S/MIME Public Certificate"
 msgstr "Certificat public S/MIME"
 
-#: config/attributes.php.dist:511
+#: config/attributes.php.dist:517
 msgid "SIP"
 msgstr "SIP"
 
@@ -1142,13 +1153,13 @@ msgstr "Enregistrer"
 msgid "Save search as a virtual address book?"
 msgstr "Enregistrer la recherche en tant que carnet d'adresses virtuel ?"
 
-#: lib/Driver.php:2131 lib/Driver/null.php:67
+#: lib/Driver.php:2133 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr "L'enregistrement des contacts n'est pas disponible."
 
-#: templates/browse/search.inc:111 templates/browse/search.inc:119
-#: templates/browse/header.inc:3 templates/block/minisearch.inc:25
-#: lib/Block/tree_menu.php:62 config/prefs.php.dist:116
+#: lib/Block/tree_menu.php:62 templates/block/minisearch.inc:25
+#: templates/browse/header.inc:3 templates/browse/search.inc:111
+#: templates/browse/search.inc:119 config/prefs.php.dist:116
 msgid "Search"
 msgstr "Rechercher"
 
@@ -1165,7 +1176,7 @@ msgstr "
 msgid "Search for: "
 msgstr "Recherche de :"
 
-#: lib/Driver.php:2090 lib/Driver/null.php:47
+#: lib/Driver.php:2092 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr "La recherche n'est pas disponible."
 
@@ -1333,7 +1344,7 @@ msgstr ""
 "Le module VFS doit être configuré pour permettre le téléchargement des "
 "pièces jointes."
 
-#: lib/Driver.php:2061
+#: lib/Driver.php:2063
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr "Le carnet d'adresses « %s » n'existe pas."
@@ -1412,7 +1423,7 @@ msgid "There was a problem creating the virtual address book: %s"
 msgstr ""
 "Une erreur est survenue lors de la création du carnet d'adresses virtuel : %s"
 
-#: lib/Forms/AddContact.php:95
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
@@ -1504,7 +1515,7 @@ msgstr "Fuseau horaire"
 msgid "Unable to find contact owner."
 msgstr "Impossible de trouver le propriétaire du contact."
 
-#: lib/Driver.php:1981 lib/Turba.php:659
+#: lib/Driver.php:1983 lib/Turba.php:662
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr "Impossible de charger la définition de %s."
@@ -1540,7 +1551,7 @@ msgstr "Afficher le contact"
 msgid "View to display by default:"
 msgstr "Affichage par défaut :"
 
-#: config/attributes.php.dist:506
+#: config/attributes.php.dist:512
 msgid "VoIP"
 msgstr "VoIP"
 
@@ -1552,7 +1563,7 @@ msgstr "URL du site web"
 msgid "Work Address"
 msgstr "Adresse bureau"
 
-#: config/attributes.php.dist:570
+#: config/attributes.php.dist:576
 msgid "Work Address Extended"
 msgstr "Adresse bureau étendue"
 
@@ -1564,23 +1575,23 @@ msgstr "Ville du bureau"
 msgid "Work Country"
 msgstr "Pays du bureau"
 
-#: config/attributes.php.dist:454
+#: config/attributes.php.dist:460
 msgid "Work Email"
 msgstr "Courriel professionnel"
 
-#: config/attributes.php.dist:471
+#: config/attributes.php.dist:477
 msgid "Work Fax"
 msgstr "Fax professionnel"
 
-#: config/attributes.php.dist:576
+#: config/attributes.php.dist:582
 msgid "Work Latitude"
 msgstr "Latitude professionnelle"
 
-#: config/attributes.php.dist:581
+#: config/attributes.php.dist:587
 msgid "Work Longitude"
 msgstr "Longitude professionnel"
 
-#: config/attributes.php.dist:481
+#: config/attributes.php.dist:487
 msgid "Work Mobile Phone"
 msgstr "Téléphone mobile professionnel"
 
@@ -1604,11 +1615,11 @@ msgstr "
 msgid "Work Street Address"
 msgstr "Rue du bureau"
 
-#: config/attributes.php.dist:496
+#: config/attributes.php.dist:502
 msgid "Work Video Call"
 msgstr "Visiophone professionnel"
 
-#: config/attributes.php.dist:564
+#: config/attributes.php.dist:570
 msgid "Work Website URL"
 msgstr "URL du site web professionnel"
 
@@ -1616,7 +1627,7 @@ msgstr "URL du site web professionnel"
 msgid "You are not allowed to change this addressbook."
 msgstr "Vous n'êtes pas autorisé à changer ce carnet d'adresses."
 
-#: data.php:355 add.php:48 lib/Views/Browse.php:159 lib/Views/Browse.php:281
+#: add.php:48 data.php:355 lib/Views/Browse.php:159 lib/Views/Browse.php:281
 #, php-format
 msgid "You are not allowed to create more than %d contacts in \"%s\"."
 msgstr "Vous n'êtes pas autorisé à créer plus de %d contacts dans « %s »."
@@ -1716,7 +1727,7 @@ msgstr ""
 msgid "[no value]"
 msgstr "[pas de valeur]"
 
-#: lib/Turba.php:601
+#: lib/Turba.php:604
 msgid "_Browse"
 msgstr "_Lister"
 
@@ -1732,7 +1743,7 @@ msgstr "S_upprimer"
 msgid "_Edit"
 msgstr "Édit_er"
 
-#: lib/Turba.php:610
+#: lib/Turba.php:613
 msgid "_Import/Export"
 msgstr "_Importer/Exporter"
 
@@ -1740,15 +1751,15 @@ msgstr "_Importer/Exporter"
 msgid "_Lists"
 msgstr "_Listes"
 
-#: lib/Turba.php:598
+#: lib/Turba.php:601
 msgid "_My Address Books"
 msgstr "_Mes annuaires"
 
-#: lib/Turba.php:604
+#: lib/Turba.php:607
 msgid "_New Contact"
 msgstr "_Nouveau contact"
 
-#: lib/Turba.php:615
+#: lib/Turba.php:618
 msgid "_Print"
 msgstr "_Imprimer"
 
@@ -1756,7 +1767,7 @@ msgstr "_Imprimer"
 msgid "_Remove from this list"
 msgstr "_Retirer de la liste"
 
-#: lib/Turba.php:606
+#: lib/Turba.php:609
 msgid "_Search"
 msgstr "_Recherche"
 
@@ -1801,7 +1812,7 @@ msgstr "contacts.vcf"
 msgid "descending"
 msgstr "descendant"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "female"
 msgstr "Féminin"
 
@@ -1810,7 +1821,7 @@ msgstr "F
 msgid "in %s"
 msgstr "dans %s"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "male"
 msgstr "Masculin"
 
@@ -1830,7 +1841,7 @@ msgstr "vers une liste de contacts"
 msgid "to a different Address Book"
 msgstr "vers un autre carnet d'adresses"
 
-#: data.php:103 templates/browse/column_headers.inc:14
-#: templates/data/import.inc:15 templates/data/export.inc:15
+#: data.php:103 templates/data/import.inc:15 templates/data/export.inc:15
+#: templates/browse/column_headers.inc:14
 msgid "vCard"
 msgstr "vCard"
diff --git a/po/hu_HU.po b/po/hu_HU.po
index 4c11513..9dd31a8 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -1,5 +1,5 @@
 # Turba Hungarian translation file.
-# Copyright (C) 2002-2008 Laszlo L. Tornoci
+# Copyright 2002-2008 Laszlo L. Tornoci
 # This file is distributed under the same license as the Turba package.
 # Latest versions: ftp://xenia.sote.hu/pub/linux/horde/
 #
diff --git a/po/is_IS.po b/po/is_IS.po
index 0cd4f98..fcb95f5 100644
--- a/po/is_IS.po
+++ b/po/is_IS.po
@@ -1,5 +1,5 @@
 # Icelandic translations for disk package.
-# Copyright (C) 2005 Horde Project
+# Copyright 2005-2009 The Horde Project
 # This file is distributed under the same license as the disk package.
 #
 msgid ""
diff --git a/po/it_IT.po b/po/it_IT.po
index 6072758..83cd57e 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -383,7 +383,7 @@ msgstr "Crea Rubrica"
 
 #: templates/addressbook_list.php:8
 msgid "Create a new Address Book"
-msgstr "Crea una nuuova Rubrica"
+msgstr "Crea una nuova Rubrica"
 
 #: lib/ListView.php:447
 msgid "Create a new Contact List in:"
@@ -425,6 +425,10 @@ msgstr "Eliminazione Fallita"
 msgid "Department"
 msgstr "Dipartimento"
 
+#: contact.php:109
+msgid "Mark this as your own contact"
+msgstr "Seleziona come tua informazione personale"
+
 #: lib/Forms/EditAddressBook.php:44 lib/Forms/CreateAddressBook.php:37
 msgid "Description"
 msgstr "descrizione"
@@ -560,7 +564,7 @@ msgstr ""
 #: lib/Views/Browse.php:186
 #, php-format
 msgid "Failed to find object to be added: %s"
-msgstr "Ricerca di oggetti da aggiungere falita: %s"
+msgstr "Ricerca di oggetti da aggiungere fallita: %s"
 
 #: search.php:190
 msgid "Failed to search the address book"
@@ -569,7 +573,7 @@ msgstr "Ricerca nella rubrica fallita"
 #: data.php:157
 #, php-format
 msgid "Failed to search the directory: %s"
-msgstr "Ricerca nella directory falita: %s"
+msgstr "Ricerca nella directory fallita: %s"
 
 #: config/sources.php.dist:550
 msgid "Favourite Recipients"
@@ -897,8 +901,8 @@ msgstr "Nessun dato %s trovato per %s."
 msgid ""
 "No Address Books are currently available. Import and Export is disabled."
 msgstr ""
-"Nessuna rubrica è al momento disponibile. Impostazione/Esportazione è "
-"disattivato."
+"Nessuna rubrica è al momento disponibile. Importazione/Esportazione "
+"disattivata."
 
 #: search.php:107
 msgid "No Address Books are currently available. Searching is disabled."
@@ -923,7 +927,7 @@ msgstr "Nessun contatto corrispondente"
 
 #: lib/Driver/favourites.php:124
 msgid "No source for favourite recipients exists."
-msgstr "Non esiste nessun archivio per contatti favoriti."
+msgstr "Non esiste nessun archivio per contatti preferiti."
 
 #: lib/api.php:762 lib/api.php:1060
 msgid "No vCard data was found."
@@ -974,7 +978,7 @@ msgid ""
 "to \"None\"."
 msgstr ""
 "Una volta confermate queste opzioni, la rubrica verrà eliminata "
-"definitivamente. Se non è questo che si desidera modificare la selezione su "
+"definitivamente. Se non è questo che si desidera, modificare la selezione su "
 "\"Nessuna\""
 
 #: lib/api.php:1068
@@ -1047,9 +1051,9 @@ msgid ""
 "Really delete the address book \"%s\"? This cannot be undone and all "
 "contacts in this address book will be permanently removed."
 msgstr ""
-"Sei sicuro di eliminare la rubrica %s?. questa operazione non può essere "
+"Sei sicuro di eliminare la rubrica %s?. Questa operazione non può essere "
 "annullata e tutti i contatti di questa rubrica saranno eliminati "
-"permanentemente"
+"permanentemente."
 
 #: templates/prefs/addressbookselect.inc:175
 msgid "Remove address book"
@@ -1065,7 +1069,7 @@ msgid ""
 "driver."
 msgstr ""
 "L'attuale database delle rubriche non permette l'eliminazione delle "
-"informazioni dell'utnte "
+"informazioni dell'utente."
 
 #: templates/data/import.inc:22
 msgid ""
@@ -1315,7 +1319,12 @@ msgstr "la rubrica non pu
 #: addressbooks/delete.php:50
 #, php-format
 msgid "The addressbook \"%s\" has been deleted."
-msgstr "la rubrica %s è stato eliminato"
+msgstr "la rubrica %s è stato eliminata"
+
+#: contact.php:57
+msgid "This contact has been marked as your own."
+msgstr ""
+"Questo contatto è stato selezionato come propria informazione personale."
 
 #: addressbooks/edit.php:44
 #, php-format
@@ -1355,9 +1364,9 @@ msgid ""
 "are configured to allow you to add new entries to them. If you believe this "
 "is an error, please contact your system administrator."
 msgstr ""
-"Nessuna delle rubriche disponibili è configurata in modo da consertirti "
-"diaggiungere nuove entrate. Se pensi sia un errore, per favore contatta il "
-"tuo amministratore di sistema."
+"Nessuna delle rubriche disponibili è configurata in modo da consertirti di "
+"aggiungere nuove entrate. Se pensi sia un errore, per favore contatta il tuo "
+"amministratore di sistema."
 
 #: lib/Views/Browse.php:349
 #, php-format
@@ -1575,7 +1584,7 @@ msgstr "Non sei abilitato a creare pi
 
 #: addressbooks/delete.php:37
 msgid "You are not allowed to delete this addressbook."
-msgstr "Non seiautorizzato a eliminare questa rubrica."
+msgstr "Non sei autorizzato a eliminare questa rubrica."
 
 #: lib/api.php:198
 msgid "You are not allowed to remove user data."
@@ -1593,6 +1602,11 @@ msgstr "Non si possono inserire contatti in una Rubrica Virtuale."
 msgid "You cannot delete contacts from a virtual address book"
 msgstr "Non si possono eliminare contatti da una Rubrica Virtuale."
 
+#: lib/api.php:1056
+msgid "You didn't mark a contact as your own yet."
+msgstr ""
+"Non hai ancora selezionato un contatto come tua informazione personale."
+
 #: view.php:38 edit.php:66 lib/Views/EditContact.php:49
 #: lib/Views/DeleteContact.php:42
 msgid "You do not have permission to view this contact."
diff --git a/po/ja_JP.po b/po/ja_JP.po
index b11752a..5c4b9a4 100644
--- a/po/ja_JP.po
+++ b/po/ja_JP.po
@@ -1,14 +1,14 @@
 # Japanese translation for Turba.
-# Copyright (C) 2004 Horde Project
+# Copyright 2004-2009 Horde Project
 # This file is distributed under the same license as the Turba package.
 # Hiromi Kimura <hiromi at tac.tsukuba.ac.jp>
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Turba 2.3-RC1\n"
+"Project-Id-Version: Turba 2.3.1\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2008-09-11 16:59+0200\n"
-"PO-Revision-Date: 2008-09-24 20:41+0900\n"
+"POT-Creation-Date: 2009-01-30 14:23+0900\n"
+"PO-Revision-Date: 2009-02-10 20:36+0900\n"
 "Last-Translator: Hiromi Kimura <hiromi at tac.tsukuba.ac.jp>\n"
 "Language-Team: i18n at lists.horde.org\n"
 "MIME-Version: 1.0\n"
@@ -57,12 +57,12 @@ msgstr "\"
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr "\"–¼, ©\",\"Lastname, Firstname\""
 
-#: lib/Driver.php:607
+#: lib/Driver.php:620
 #, php-format
 msgid "%d. %s of %s"
-msgstr ""
+msgstr "%d. %s of %s"
 
-#: lib/Forms/AddContact.php:88
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr "%s ‚ð’ljÁ‚µ‚Ü‚µ‚½B"
@@ -111,7 +111,7 @@ msgstr "
 msgid "Add to"
 msgstr "‚±‚±‚ɒljÁ"
 
-#: lib/Driver.php:2100 lib/Driver/null.php:57
+#: lib/Driver.php:2115 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr "˜A—æ‚̒ljÁ‚Í‚Å‚«‚Ü‚¹‚ñB"
 
@@ -173,7 +173,7 @@ msgstr "
 msgid "Are you sure that you want to delete the selected contacts?"
 msgstr "‘I‘ð‚³‚ê‚½˜A—æ‚ð–{“–‚ɍ폜‚µ‚Ü‚·‚©H"
 
-#: config/attributes.php.dist:424
+#: config/attributes.php.dist:430
 msgid "Assistant"
 msgstr "•Žè"
 
@@ -293,52 +293,43 @@ msgstr "
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr "ƒRƒ“ƒ}‹æØ‚èŒ`Ž® (Microsoft Outlook)"
 
-#: config/attributes.php.dist:522
-#, fuzzy
+#: config/attributes.php.dist:528
 msgid "Common Address Extended"
-msgstr "ZŠ"
+msgstr "‹¤’ʂ̏ZŠi‘±‚«j"
 
-#: config/attributes.php.dist:540
-#, fuzzy
+#: config/attributes.php.dist:546
 msgid "Common City"
-msgstr "Žs"
+msgstr "‹¤’Ê‚ÌŽs"
 
-#: config/attributes.php.dist:558
-#, fuzzy
+#: config/attributes.php.dist:564
 msgid "Common Country"
-msgstr "‘"
+msgstr "‹¤’ʂ̍‘"
 
-#: config/attributes.php.dist:466
-#, fuzzy
+#: config/attributes.php.dist:472
 msgid "Common Phone"
-msgstr "“d˜b”ԍ†"
+msgstr "‹¤’Ê‚Ì“d˜b”ԍ†"
 
-#: config/attributes.php.dist:534
-#, fuzzy
+#: config/attributes.php.dist:540
 msgid "Common Post Office Box"
-msgstr "Ž„‘” "
+msgstr "‹¤’Ê‚ÌŽ„‘” "
 
-#: config/attributes.php.dist:552
-#, fuzzy
+#: config/attributes.php.dist:558
 msgid "Common Postal Code"
-msgstr "—X•Ö”ԍ†"
+msgstr "‹¤’Ê‚Ì—X•Ö”ԍ†"
 
-#: config/attributes.php.dist:546
-#, fuzzy
+#: config/attributes.php.dist:552
 msgid "Common State/Province"
-msgstr "B^Œ§"
+msgstr "‹¤’ʂ̏B‚Ü‚½‚ÍŒ§"
 
-#: config/attributes.php.dist:528
-#, fuzzy
+#: config/attributes.php.dist:534
 msgid "Common Street"
-msgstr "”Ô’n"
+msgstr "‹¤’ʂ̏ZŠ”Ô’n"
 
-#: config/attributes.php.dist:491
-#, fuzzy
+#: config/attributes.php.dist:497
 msgid "Common Video Call"
-msgstr "ƒrƒfƒI’ʘb"
+msgstr "‹¤’ʂ̃rƒfƒI’ʘb"
 
-#: config/sources.php.dist:256 config/sources.php.dist:948
+#: config/sources.php.dist:256 config/sources.php.dist:952
 msgid "Communications"
 msgstr "’ʐM"
 
@@ -350,11 +341,12 @@ msgstr "
 msgid "Company Address"
 msgstr "‹Î–±æZŠ"
 
-#: scripts/import_squirrelmail_abook.php:112 lib/api.php:546 lib/api.php:600
-#: lib/api.php:653 lib/api.php:701 lib/api.php:756 lib/api.php:815
-#: lib/api.php:866 lib/api.php:1004 lib/api.php:1066 lib/api.php:1137
-#: lib/api.php:1204 lib/api.php:1324 lib/api.php:1563 lib/api.php:1640
-#: lib/api.php:1791
+#: scripts/import_squirrelmail_sql_abook.php:125
+#: scripts/import_squirrelmail_file_abook.php:114 lib/api.php:546
+#: lib/api.php:600 lib/api.php:653 lib/api.php:701 lib/api.php:756
+#: lib/api.php:815 lib/api.php:866 lib/api.php:1004 lib/api.php:1066
+#: lib/api.php:1137 lib/api.php:1204 lib/api.php:1324 lib/api.php:1563
+#: lib/api.php:1640 lib/api.php:1791
 #, php-format
 msgid "Connection failed: %s"
 msgstr "Ú‘±‚ÉŽ¸”s‚µ‚Ü‚µ‚½: %s"
@@ -367,7 +359,7 @@ msgstr "
 msgid "Contact Search"
 msgstr "˜A—æ‚ÌŒŸõ"
 
-#: config/sources.php.dist:866
+#: config/sources.php.dist:868
 msgid "Contacts"
 msgstr "˜A—æ"
 
@@ -428,7 +420,7 @@ msgstr "
 msgid "Delete failed: (%s) %s"
 msgstr "íœ‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½: (%s) %s"
 
-#: lib/Driver.php:2108 lib/Driver/null.php:62
+#: lib/Driver.php:2123 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr "˜A—æ‚̍폜‚Í‚Å‚«‚Ü‚¹‚ñB"
 
@@ -457,7 +449,7 @@ msgstr "
 msgid "Display Options"
 msgstr "•\Ž¦ƒIƒvƒVƒ‡ƒ“"
 
-#: lib/Object.php:354
+#: lib/Object.php:357
 msgid "Download"
 msgstr "ƒ_ƒEƒ“ƒ[ƒh"
 
@@ -612,7 +604,7 @@ msgstr "
 msgid "From"
 msgstr "From"
 
-#: config/attributes.php.dist:430
+#: config/attributes.php.dist:436
 msgid "Gender"
 msgstr "«•Ê"
 
@@ -628,10 +620,9 @@ msgstr "
 msgid "Home Address"
 msgstr "Ž©‘î‚̏ZŠ"
 
-#: config/attributes.php.dist:592
-#, fuzzy
+#: config/attributes.php.dist:598
 msgid "Home Address Extended"
-msgstr "Ž©‘î‚̏ZŠ"
+msgstr "Ž©‘î‚̏ZŠi‘±‚«j"
 
 #: config/attributes.php.dist:153
 msgid "Home City"
@@ -641,23 +632,23 @@ msgstr "
 msgid "Home Country"
 msgstr "Ž©‘î‚̍‘"
 
-#: config/attributes.php.dist:460
+#: config/attributes.php.dist:466
 msgid "Home Email"
 msgstr "Ž©‘[ƒ‹ƒAƒhƒŒƒX"
 
-#: config/attributes.php.dist:476
+#: config/attributes.php.dist:482
 msgid "Home Fax"
 msgstr "Ž©‘î‚Ì FAX"
 
-#: config/attributes.php.dist:598
+#: config/attributes.php.dist:604
 msgid "Home Latitude"
 msgstr "Ž©‘î‚̈ܓx"
 
-#: config/attributes.php.dist:603
+#: config/attributes.php.dist:609
 msgid "Home Longitude"
 msgstr "Ž©‘î‚ÌŒo“x"
 
-#: config/attributes.php.dist:486
+#: config/attributes.php.dist:492
 msgid "Home Mobile Phone"
 msgstr "Ž©‘î‚ÌŒg‘Ñ“d˜b"
 
@@ -681,11 +672,11 @@ msgstr "
 msgid "Home Street Address"
 msgstr "Ž©‘î‚̔Ԓn"
 
-#: config/attributes.php.dist:501
+#: config/attributes.php.dist:507
 msgid "Home Video Call"
 msgstr "Ž©‘î‚̃rƒfƒI’ʘb"
 
-#: config/attributes.php.dist:586
+#: config/attributes.php.dist:592
 msgid "Home Website URL"
 msgstr "Ž©‘î‚Ì Web URL"
 
@@ -702,11 +693,11 @@ msgstr "
 msgid "Import/Export Address Books"
 msgstr "ƒAƒhƒŒƒX’ ‚̃Cƒ“ƒ|[ƒg^ƒGƒNƒXƒ|[ƒg"
 
-#: config/attributes.php.dist:406
+#: config/attributes.php.dist:412
 msgid "Initials"
 msgstr "ƒCƒjƒVƒƒƒ‹"
 
-#: config/attributes.php.dist:412
+#: config/attributes.php.dist:418
 msgid "Instant Messenger"
 msgstr "ƒCƒ“ƒXƒ^ƒ“ƒgEƒƒbƒZƒ“ƒWƒƒ["
 
@@ -714,9 +705,10 @@ msgstr "
 msgid "Invalid ID"
 msgstr "–³Œø‚È ID ‚Å‚·"
 
-#: scripts/import_squirrelmail_abook.php:105 lib/api.php:368 lib/api.php:696
-#: lib/api.php:751 lib/api.php:810 lib/api.php:859 lib/api.php:995
-#: lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
+#: scripts/import_squirrelmail_sql_abook.php:118
+#: scripts/import_squirrelmail_file_abook.php:107 lib/api.php:368
+#: lib/api.php:696 lib/api.php:751 lib/api.php:810 lib/api.php:859
+#: lib/api.php:995 lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
 #, php-format
 msgid "Invalid address book: %s"
 msgstr "–³Œø‚ȃAƒhƒŒƒX’ ‚Å‚·F%s"
@@ -745,11 +737,20 @@ msgstr "
 msgid "Job Title"
 msgstr "Œ¨‘"
 
-#: lib/Driver/kolab.php:1129 lib/Driver/kolab.php:1195
+#: lib/Driver/kolab.php:1119
+#, php-format
+msgid "Key for saving must be \\'uid\\' not %s!"
+msgstr "•Û‘¶‚̃LƒC‚Í \\'uid\\' ‚Å‚ ‚Á‚āA%s ‚Å‚È‚¢‚±‚ƁI"
+
+#: lib/Driver/kolab.php:1203
 #, php-format
 msgid "Key for saving must be a UID not %s!"
 msgstr "•Û‘¶‚̃LƒC‚Í UID ‚Å‚ ‚Á‚āA%s ‚Å‚È‚¢‚±‚ƁI"
 
+#: config/attributes.php.dist:406
+msgid "Kolab Home Server"
+msgstr "Kolab ƒz[ƒ€ƒT[ƒo"
+
 #: lib/Driver/ldap.php:64
 msgid ""
 "LDAP support is required but the LDAP module is not available or not loaded."
@@ -760,7 +761,7 @@ msgstr ""
 msgid "LDIF Address Book"
 msgstr "LDIFƒAƒhƒŒƒX’ "
 
-#: config/attributes.php.dist:436
+#: config/attributes.php.dist:442
 msgid "Language"
 msgstr "Œ¾Œê"
 
@@ -772,7 +773,7 @@ msgstr "
 msgid "Last Name"
 msgstr "©(Last Name)"
 
-#: config/attributes.php.dist:442
+#: config/attributes.php.dist:448
 msgid "Latitude"
 msgstr "ˆÜ“x"
 
@@ -780,7 +781,7 @@ msgstr "
 msgid "List"
 msgstr "ƒŠƒXƒg"
 
-#: config/sources.php.dist:251 config/sources.php.dist:944
+#: config/sources.php.dist:251 config/sources.php.dist:948
 msgid "Location"
 msgstr "êŠ"
 
@@ -792,7 +793,7 @@ msgstr "
 msgid "Logo MIME Type"
 msgstr "ƒƒS‚ÌMIMEƒ^ƒCƒv"
 
-#: config/attributes.php.dist:447
+#: config/attributes.php.dist:453
 msgid "Longitude"
 msgstr "Œo“x"
 
@@ -804,7 +805,7 @@ msgstr "
 msgid "Manage Address Books"
 msgstr "ƒAƒhƒŒƒX’ ‚ÌŠÇ—"
 
-#: config/attributes.php.dist:418
+#: config/attributes.php.dist:424
 msgid "Manager"
 msgstr "ŠÇ—ŽÒ"
 
@@ -977,7 +978,7 @@ msgstr "1
 msgid "Object not found"
 msgstr "ƒIƒuƒWƒFƒNƒg‚ªŒ©•t‚©‚è‚Ü‚¹‚ñ"
 
-#: lib/Driver/kolab.php:1199
+#: lib/Driver/kolab.php:1207
 #, php-format
 msgid "Object with UID %s does not exist!"
 msgstr "UID %s ‚̃IƒuƒWƒFƒNƒg‚Í‘¶Ý‚µ‚Ü‚¹‚ñI"
@@ -1003,11 +1004,11 @@ msgstr ""
 msgid "Only one vcard supported."
 msgstr "‚P‚Â‚Ì vcard ‚¾‚¯‚ðƒTƒ|[ƒg‚µ‚Ü‚·B"
 
-#: config/sources.php.dist:258 config/sources.php.dist:950
+#: config/sources.php.dist:258 config/sources.php.dist:954
 msgid "Organization"
 msgstr "‘gD"
 
-#: config/sources.php.dist:259 config/sources.php.dist:952
+#: config/sources.php.dist:259 config/sources.php.dist:956
 msgid "Other"
 msgstr "‚»‚Ì‘¼"
 
@@ -1015,7 +1016,7 @@ msgstr "
 msgid "PGP Public Key"
 msgstr "PGP ŒöŠJŒ®"
 
-#: config/attributes.php.dist:517
+#: config/attributes.php.dist:523
 msgid "PTT"
 msgstr "PTT"
 
@@ -1027,12 +1028,12 @@ msgstr "
 msgid "Permanently delete this contact?"
 msgstr "‚±‚̘A—æ‚ð–{“–‚ɍ폜‚µ‚Ü‚·‚©H"
 
-#: deletefile.php:36 lib/Driver.php:791 lib/api.php:870 lib/api.php:1795
+#: deletefile.php:36 lib/Driver.php:805 lib/api.php:870 lib/api.php:1795
 #: lib/Driver/sql.php:515
 msgid "Permission denied"
 msgstr "ƒAƒNƒZƒX‚ª‹‘”Û‚³‚ê‚Ü‚µ‚½"
 
-#: config/sources.php.dist:248 config/sources.php.dist:940
+#: config/sources.php.dist:248 config/sources.php.dist:944
 msgid "Personal"
 msgstr "ŒÂl"
 
@@ -1067,7 +1068,7 @@ msgstr "
 msgid "Read failed: (%s) %s"
 msgstr "“Ǎž‚ÝŽ¸”s: (%s) %s"
 
-#: lib/Driver.php:2092 lib/Driver/null.php:52
+#: lib/Driver.php:2107 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr "˜A—æ‚̓ǂݏo‚µ‚Í‚Å‚«‚Ü‚¹‚ñB"
 
@@ -1088,7 +1089,7 @@ msgstr "
 msgid "Remove from this list"
 msgstr "ƒŠƒXƒg‚©‚çŠO‚·"
 
-#: lib/Driver.php:2130
+#: lib/Driver.php:2145
 msgid ""
 "Removing user data is not supported in the current address book storage "
 "driver."
@@ -1104,7 +1105,7 @@ msgstr ""
 "ƒCƒ“ƒ|[ƒg‚ÅŠù‘¶‚̃AƒhƒŒƒX’ ‚ð’u‚«Š·‚¦‚Ü‚·‚©H <strong>ŒxF‚»‚¤‚·‚é‚ÆŒ»Ý‚Ì"
 "ƒAƒhƒŒƒX’ ‚Ì“à—e‚Í‘S‚ÄŽ¸‚í‚ê‚Ü‚·B</strong>"
 
-#: lib/Driver.php:685
+#: lib/Driver.php:699
 msgid "Requested object not found."
 msgstr "—v‹‚³‚ꂽƒIƒuƒWƒFƒNƒg‚ÍŒ©•t‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½B"
 
@@ -1116,7 +1117,7 @@ msgstr "
 msgid "S/MIME Public Certificate"
 msgstr "S/MIME ŒöŠJØ–¾‘"
 
-#: config/attributes.php.dist:511
+#: config/attributes.php.dist:517
 msgid "SIP"
 msgstr "SIP"
 
@@ -1133,7 +1134,7 @@ msgstr "
 msgid "Save search as a virtual address book?"
 msgstr "ŒŸõŒ‹‰Ê‚ð‰¼‘zƒAƒhƒŒƒX’ ‚É•Û‘¶‚µ‚Ü‚·‚©H"
 
-#: lib/Driver.php:2118 lib/Driver/null.php:67
+#: lib/Driver.php:2133 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr "˜A—æ‚Ì•Û‘¶‚Í‚Å‚«‚Ü‚¹‚ñB"
 
@@ -1156,7 +1157,7 @@ msgstr "
 msgid "Search for: "
 msgstr "ŒŸõF"
 
-#: lib/Driver.php:2077 lib/Driver/null.php:47
+#: lib/Driver.php:2092 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr "ŒŸõ‚ÍŽg—p‚Å‚«‚Ü‚¹‚ñB"
 
@@ -1318,7 +1319,7 @@ msgstr "
 msgid "The VFS backend needs to be configured to enable attachment uploads."
 msgstr "VFS ƒoƒbƒNƒGƒ“ƒh‚Í“Y•t‚̃Aƒbƒvƒ[ƒh‚ª‹–‰Â‚³‚ê‚Ä‚¢‚邱‚Æ‚ª•K—v‚Å‚·B"
 
-#: lib/Driver.php:2048
+#: lib/Driver.php:2063
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr "ƒAƒhƒŒƒX’  \"%s\" ‚Í‘¶Ý‚µ‚Ü‚¹‚ñB"
@@ -1395,7 +1396,7 @@ msgstr[0] "
 msgid "There was a problem creating the virtual address book: %s"
 msgstr "‰¼‘zƒAƒhƒŒƒX’ ‚̍쐬’†‚É–â‘肪‹N‚«‚Ü‚µ‚½: %s"
 
-#: lib/Forms/AddContact.php:95
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
@@ -1482,7 +1483,7 @@ msgstr "
 msgid "Unable to find contact owner."
 msgstr "˜A—æ‚̏Š—LŽÒ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñB"
 
-#: lib/Driver.php:1968 lib/Turba.php:659
+#: lib/Driver.php:1983 lib/Turba.php:662
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr "%s ‚Ì’è‹`‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñB"
@@ -1518,7 +1519,7 @@ msgstr "
 msgid "View to display by default:"
 msgstr "ƒfƒtƒHƒ‹ƒg‚Ì•\Ž¦‰æ–Ê:"
 
-#: config/attributes.php.dist:506
+#: config/attributes.php.dist:512
 msgid "VoIP"
 msgstr "VoIP"
 
@@ -1530,7 +1531,7 @@ msgstr "Web 
 msgid "Work Address"
 msgstr "‹Î–±æ‚̏ZŠ"
 
-#: config/attributes.php.dist:570
+#: config/attributes.php.dist:576
 msgid "Work Address Extended"
 msgstr "‹Î–±æ‚̏ZŠ"
 
@@ -1542,23 +1543,23 @@ msgstr "
 msgid "Work Country"
 msgstr "‹Î–±æ‚̍‘"
 
-#: config/attributes.php.dist:454
+#: config/attributes.php.dist:460
 msgid "Work Email"
 msgstr "‹Î–±æƒ[ƒ‹ƒAƒhƒŒƒX"
 
-#: config/attributes.php.dist:471
+#: config/attributes.php.dist:477
 msgid "Work Fax"
 msgstr "‹Î–±æ‚Ì FAX"
 
-#: config/attributes.php.dist:576
+#: config/attributes.php.dist:582
 msgid "Work Latitude"
 msgstr "‹Î–±æ‚̈ܓx"
 
-#: config/attributes.php.dist:581
+#: config/attributes.php.dist:587
 msgid "Work Longitude"
 msgstr "‹Î–±æ‚ÌŒo“x"
 
-#: config/attributes.php.dist:481
+#: config/attributes.php.dist:487
 msgid "Work Mobile Phone"
 msgstr "‹Î–±æ‚ÌŒg‘Ñ“d˜b"
 
@@ -1582,11 +1583,11 @@ msgstr "
 msgid "Work Street Address"
 msgstr "‹Î–±æ‚̔Ԓn"
 
-#: config/attributes.php.dist:496
+#: config/attributes.php.dist:502
 msgid "Work Video Call"
 msgstr "‹Î–±æ‚̃rƒfƒI’ʘb"
 
-#: config/attributes.php.dist:564
+#: config/attributes.php.dist:570
 msgid "Work Website URL"
 msgstr "‹Î–±æ‚Ì Web URL"
 
@@ -1691,7 +1692,7 @@ msgstr "
 msgid "[no value]"
 msgstr "[’l‚È‚µ]"
 
-#: lib/Turba.php:601
+#: lib/Turba.php:604
 msgid "_Browse"
 msgstr "_B‰{——"
 
@@ -1707,7 +1708,7 @@ msgstr "_D
 msgid "_Edit"
 msgstr "_E•ÒW"
 
-#: lib/Turba.php:610
+#: lib/Turba.php:613
 msgid "_Import/Export"
 msgstr "_IƒCƒ“/ƒAƒEƒg"
 
@@ -1715,15 +1716,15 @@ msgstr "_I
 msgid "_Lists"
 msgstr "_LƒŠƒXƒg"
 
-#: lib/Turba.php:598
+#: lib/Turba.php:601
 msgid "_My Address Books"
 msgstr "_MŽ„‚̃AƒhƒŒƒX’ "
 
-#: lib/Turba.php:604
+#: lib/Turba.php:607
 msgid "_New Contact"
 msgstr "_NV‹K˜A—æ"
 
-#: lib/Turba.php:615
+#: lib/Turba.php:618
 msgid "_Print"
 msgstr "_Pˆóü"
 
@@ -1731,7 +1732,7 @@ msgstr "_P
 msgid "_Remove from this list"
 msgstr "_RƒŠƒXƒg‚©‚çíœ"
 
-#: lib/Turba.php:606
+#: lib/Turba.php:609
 msgid "_Search"
 msgstr "_SŒŸõ"
 
@@ -1746,11 +1747,11 @@ msgstr "
 #: lib/Views/Contact.php:76 lib/Views/Contact.php:87
 #, php-format
 msgid "by %s"
-msgstr ""
+msgstr "%s ì"
 
 #: lib/Views/Contact.php:78 lib/Views/Contact.php:89
 msgid "by me"
-msgstr ""
+msgstr "Ž©ì"
 
 #: vcard.php:45
 msgid "contact"
@@ -1776,16 +1777,16 @@ msgstr "contacts.vcf"
 msgid "descending"
 msgstr "~‡"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "female"
 msgstr "—«"
 
 #: lib/Block/tree_menu.php:38
 #, php-format
 msgid "in %s"
-msgstr ""
+msgstr "in %s"
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "male"
 msgstr "’j«"
 
diff --git a/po/ko_KR.po b/po/ko_KR.po
index efd2533..3919441 100644
--- a/po/ko_KR.po
+++ b/po/ko_KR.po
@@ -1,6 +1,6 @@
 # Korean translations for horde package
 # horde ÆÐÅ°Áö¿¡ ´ëÇÑ Çѱ¹¾î ¹ø¿ª¹®.
-# Copyright (C) 2005 Horde Project
+# Copyright 2005-2009 The Horde Project
 # This file is distributed under the same license as the horde package.
 #
 msgid ""
diff --git a/po/lt_LT.po b/po/lt_LT.po
index c09feef..e9bf63a 100644
--- a/po/lt_LT.po
+++ b/po/lt_LT.po
@@ -1,5 +1,5 @@
 # Lithuanian translations for Turba package.
-# Copyright (C) 2007 Horde Project
+# Copyright 2007-2009 The Horde Project
 # This file is distributed under the same license as the Turba package.
 # Vilius Sumskas <vilius at lnk.lt>, 2003, 2004, 2007.
 # 
diff --git a/po/mk_MK.po b/po/mk_MK.po
index 934035d..be47fa7 100644
--- a/po/mk_MK.po
+++ b/po/mk_MK.po
@@ -1,6 +1,6 @@
 # translation of mk_MK.po to Macedonian
 # This file is distributed under the same license as the Turba package.
-# Copyright (C) 2003 Eureka Informatika
+# Copyright 2003 Eureka Informatika
 # Stojan Pesov <ssp at eureka.com.mk>, 2003
 #
 msgid ""
diff --git a/po/nb_NO.po b/po/nb_NO.po
index 851b97c..adb9cea 100644
--- a/po/nb_NO.po
+++ b/po/nb_NO.po
@@ -1,5 +1,5 @@
 # Norwegian Turba Translation.
-# Copyright (C) 2001-2002 Horde Project.
+# Copyright 2001-2009 The Horde Project.
 # Oystein Steimler <oystein at rexta.net>, 2001.
 # Torstein S. Hansen <huleboer at techbee.no>, 2002.
 # Andreas Gunleikskaas <andreas at gunleikskaas.no>, 2003.
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 6238c56..fd9f581 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -1,5 +1,5 @@
 # Turba Dutch translation.
-# Copyright (C) 2001 Jan Kuipers.
+# Copyright 2001 Jan Kuipers.
 # Jan Kuipers <jrkuipers at lauwerscollege.nl>, 2001-2008.
 # Updated Han Spruyt 2005.
 #
diff --git a/po/nn_NO.po b/po/nn_NO.po
index fb6a4cc..00f98a7 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -1,5 +1,5 @@
 # Turba Norwegian Nynorsk translation
-# Copyright (C) 2002 Per-Stian Vatne
+# Copyright 2002 Per-Stian Vatne
 # This file is distributed under the same license as the Turba package.
 # Per-Stian Vatne <psv at orsta.org>, 2002.
 #
diff --git a/po/pl_PL.po b/po/pl_PL.po
index b9355fa..01b64e0 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -1,6 +1,6 @@
 # Polish translations for Turba package
 # Polskie tlumaczenia dla pakietu Turba.
-# Copyright (C) 2007 Horde Project
+# Copyright 2007-2009 The Horde Project
 # This file is distributed under the same license as the Horde package.
 # Automatically generated, 2007.
 # Mariusz Zynel <mariusz at math.uwb.edu.pl>, 2001.
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 9271c25..ea16ff3 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -1,6 +1,6 @@
 # translation of pt_BR.po to Português brasileiro
 # This file is distributed under the same license as the Turba package.
-# Copyright (C) YEAR Horde Project.
+# Copyright YEAR Horde Project.
 #
 # Fabio Gomes <flgoms at uol.com.br>, 2005.
 # Luis Felipe Marzagao <duli at fedoraproject.org>, 2008.
diff --git a/po/ro_RO.po b/po/ro_RO.po
index 06e0bd9..8d62b29 100644
--- a/po/ro_RO.po
+++ b/po/ro_RO.po
@@ -1,5 +1,5 @@
 # TURBA Romanian Translation.
-# Copyright (C) 2003 Horde Project
+# Copyright 2003-2009 The Horde Project
 # Eugen Hoanca <eugenh at urban-grafx.ro>, 2003.
 # Marius Dragulescu <mariusd at urban-grafx.ro>, 2003.
 #
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 2858c01..f357a42 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -1,5 +1,5 @@
 # Russian Turba Translation
-# Copyright (C)
+# Copyright
 # Ignat Ikryanov <iignat at newmail.ru>, 2001
 # Anton Nekhoroshih <anton at valuehost.ru>, 2001
 # Fedor A. Fetisov <faf at ssc.ru>, 2002
diff --git a/po/sk_SK.po b/po/sk_SK.po
index e8ce1d0..ed46971 100644
--- a/po/sk_SK.po
+++ b/po/sk_SK.po
@@ -1,5 +1,5 @@
 # Turba Slovak translation.
-# Copyright (C) 2002 Leo Mrafko. <leo at oel.sk> (original translator)
+# Copyright 2002 Leo Mrafko. <leo at oel.sk> (original translator)
 # (C) 2002, 2003 Ivan Noris <vix at vazka.sk>
 # Martin Matu¹ka <martin at matuska.org>, 2008.
 #
diff --git a/po/sl_SI.po b/po/sl_SI.po
index 50e6284..42df9ef 100644
--- a/po/sl_SI.po
+++ b/po/sl_SI.po
@@ -1,7 +1,7 @@
 # translation of sl_SI.po to Slovene
 # Slovenian translations for Turba packaga
 # Slovenski prevod Turba paketa
-# Copyright (C) 2006 Horde Project
+# Copyright 2006-2009 The Horde Project
 # This file is distributed under the same license as the horde package.
 #
 # Automatically generated, 2006.
diff --git a/po/sv_SE.po b/po/sv_SE.po
index 03c12ef..0778957 100644
--- a/po/sv_SE.po
+++ b/po/sv_SE.po
@@ -1,5 +1,5 @@
 # Turba Swedish translation
-# Copyright (C) 2002-2005 Andreas Dahlén.
+# Copyright 2002-2005 Andreas Dahlén.
 # Andreas Dahlén <andreas at dahlen.ws>, 2005.
 #
 msgid ""
diff --git a/po/tr_TR.po b/po/tr_TR.po
index f4e2fef..7c90029 100644
--- a/po/tr_TR.po
+++ b/po/tr_TR.po
@@ -1,6 +1,6 @@
 # Turkish translations for Turba package
 # Adres Defteri paketi için Türkçe çeviriler.
-# Copyright (C) 2008 Horde Project
+# Copyright 2008-2009 The Horde Project
 # This file is distributed under the same license as the Turba package.
 # horde-tr at metu.edu.tr, 2005-2008.
 #
diff --git a/po/turba.pot b/po/turba.pot
index d54ba73..5ac979d 100644
--- a/po/turba.pot
+++ b/po/turba.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2008-09-25 12:32+0200\n"
+"POT-Creation-Date: 2009-09-12 10:09+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -58,12 +58,12 @@ msgstr ""
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr ""
 
-#: lib/Driver.php:619
+#: lib/Driver.php:632
 #, php-format
 msgid "%d. %s of %s"
 msgstr ""
 
-#: lib/Forms/AddContact.php:88
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr ""
@@ -78,7 +78,7 @@ msgstr ""
 msgid "%s to %s of %s"
 msgstr ""
 
-#: lib/Turba.php:541
+#: lib/Turba.php:542
 #, php-format
 msgid "%s's Address Book"
 msgstr ""
@@ -112,11 +112,11 @@ msgstr ""
 msgid "Add to"
 msgstr ""
 
-#: lib/Driver.php:2113 lib/Driver/null.php:57
+#: lib/Driver.php:2135 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr ""
 
-#: templates/addressbook_list.php:16
+#: templates/addressbook_list.php:16 templates/browse/search.inc:125
 msgid "Address Book"
 msgstr ""
 
@@ -153,7 +153,7 @@ msgstr ""
 msgid "All"
 msgstr ""
 
-#: lib/api.php:941
+#: lib/api.php:983
 msgid "Already Exists"
 msgstr ""
 
@@ -174,7 +174,7 @@ msgstr ""
 msgid "Are you sure that you want to delete the selected contacts?"
 msgstr ""
 
-#: config/attributes.php.dist:424
+#: config/attributes.php.dist:430
 msgid "Assistant"
 msgstr ""
 
@@ -182,7 +182,7 @@ msgstr ""
 msgid "Basic Search"
 msgstr ""
 
-#: lib/Driver/ldap.php:92 lib/Driver/ldap.php:95
+#: lib/Driver/ldap.php:97 lib/Driver/ldap.php:100
 #, php-format
 msgid "Bind failed: (%s) %s"
 msgstr ""
@@ -292,43 +292,43 @@ msgstr ""
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr ""
 
-#: config/attributes.php.dist:522
+#: config/attributes.php.dist:528
 msgid "Common Address Extended"
 msgstr ""
 
-#: config/attributes.php.dist:540
+#: config/attributes.php.dist:546
 msgid "Common City"
 msgstr ""
 
-#: config/attributes.php.dist:558
+#: config/attributes.php.dist:564
 msgid "Common Country"
 msgstr ""
 
-#: config/attributes.php.dist:466
+#: config/attributes.php.dist:472
 msgid "Common Phone"
 msgstr ""
 
-#: config/attributes.php.dist:534
+#: config/attributes.php.dist:540
 msgid "Common Post Office Box"
 msgstr ""
 
-#: config/attributes.php.dist:552
+#: config/attributes.php.dist:558
 msgid "Common Postal Code"
 msgstr ""
 
-#: config/attributes.php.dist:546
+#: config/attributes.php.dist:552
 msgid "Common State/Province"
 msgstr ""
 
-#: config/attributes.php.dist:528
+#: config/attributes.php.dist:534
 msgid "Common Street"
 msgstr ""
 
-#: config/attributes.php.dist:491
+#: config/attributes.php.dist:497
 msgid "Common Video Call"
 msgstr ""
 
-#: config/sources.php.dist:256 config/sources.php.dist:948
+#: config/sources.php.dist:286 config/sources.php.dist:1013
 msgid "Communications"
 msgstr ""
 
@@ -340,11 +340,12 @@ msgstr ""
 msgid "Company Address"
 msgstr ""
 
-#: scripts/import_squirrelmail_abook.php:112 lib/api.php:546 lib/api.php:600
-#: lib/api.php:653 lib/api.php:701 lib/api.php:756 lib/api.php:815
-#: lib/api.php:866 lib/api.php:1004 lib/api.php:1066 lib/api.php:1137
-#: lib/api.php:1204 lib/api.php:1324 lib/api.php:1563 lib/api.php:1640
-#: lib/api.php:1791
+#: scripts/import_squirrelmail_sql_abook.php:125
+#: scripts/import_squirrelmail_file_abook.php:114 lib/api.php:587
+#: lib/api.php:641 lib/api.php:694 lib/api.php:742 lib/api.php:797
+#: lib/api.php:857 lib/api.php:908 lib/api.php:1046 lib/api.php:1108
+#: lib/api.php:1179 lib/api.php:1246 lib/api.php:1366 lib/api.php:1610
+#: lib/api.php:1696 lib/api.php:1848
 #, php-format
 msgid "Connection failed: %s"
 msgstr ""
@@ -357,7 +358,7 @@ msgstr ""
 msgid "Contact Search"
 msgstr ""
 
-#: config/sources.php.dist:866
+#: config/sources.php.dist:929
 msgid "Contacts"
 msgstr ""
 
@@ -409,16 +410,16 @@ msgstr ""
 msgid "Delete %s"
 msgstr ""
 
-#: lib/api.php:644
+#: lib/api.php:685
 msgid "Delete denied."
 msgstr ""
 
-#: lib/Driver/ldap.php:321
+#: lib/Driver/ldap.php:326
 #, php-format
 msgid "Delete failed: (%s) %s"
 msgstr ""
 
-#: lib/Driver.php:2121 lib/Driver/null.php:62
+#: lib/Driver.php:2143 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr ""
 
@@ -434,10 +435,6 @@ msgstr ""
 msgid "Description"
 msgstr ""
 
-#: templates/browse/search.inc:125
-msgid "Directory"
-msgstr ""
-
 #: config/prefs.php.dist:24
 msgid "Display"
 msgstr ""
@@ -447,7 +444,7 @@ msgstr ""
 msgid "Display Options"
 msgstr ""
 
-#: lib/Object.php:354
+#: lib/Object.php:360
 msgid "Download"
 msgstr ""
 
@@ -511,7 +508,7 @@ msgstr ""
 msgid "Error removing %d of %d requested contact(s) from list."
 msgstr ""
 
-#: lib/api.php:707
+#: lib/api.php:748
 #, php-format
 msgid "Error searching the address book: %s"
 msgstr ""
@@ -551,7 +548,7 @@ msgstr ""
 msgid "Failed to browse the directory"
 msgstr ""
 
-#: lib/Driver/ldap.php:354
+#: lib/Driver/ldap.php:359
 #, php-format
 msgid "Failed to change name: (%s) %s; Old DN = %s, New DN = %s, Root = %s"
 msgstr ""
@@ -570,7 +567,7 @@ msgstr ""
 msgid "Failed to search the directory: %s"
 msgstr ""
 
-#: config/sources.php.dist:565
+#: config/sources.php.dist:626
 msgid "Favourite Recipients"
 msgstr ""
 
@@ -602,11 +599,11 @@ msgstr ""
 msgid "From"
 msgstr ""
 
-#: config/attributes.php.dist:430
+#: config/attributes.php.dist:436
 msgid "Gender"
 msgstr ""
 
-#: config/sources.php.dist:791
+#: config/sources.php.dist:852
 msgid "Global Address Book"
 msgstr ""
 
@@ -618,7 +615,7 @@ msgstr ""
 msgid "Home Address"
 msgstr ""
 
-#: config/attributes.php.dist:592
+#: config/attributes.php.dist:598
 msgid "Home Address Extended"
 msgstr ""
 
@@ -630,23 +627,23 @@ msgstr ""
 msgid "Home Country"
 msgstr ""
 
-#: config/attributes.php.dist:460
+#: config/attributes.php.dist:466
 msgid "Home Email"
 msgstr ""
 
-#: config/attributes.php.dist:476
+#: config/attributes.php.dist:482
 msgid "Home Fax"
 msgstr ""
 
-#: config/attributes.php.dist:598
+#: config/attributes.php.dist:604
 msgid "Home Latitude"
 msgstr ""
 
-#: config/attributes.php.dist:603
+#: config/attributes.php.dist:609
 msgid "Home Longitude"
 msgstr ""
 
-#: config/attributes.php.dist:486
+#: config/attributes.php.dist:492
 msgid "Home Mobile Phone"
 msgstr ""
 
@@ -670,15 +667,15 @@ msgstr ""
 msgid "Home Street Address"
 msgstr ""
 
-#: config/attributes.php.dist:501
+#: config/attributes.php.dist:507
 msgid "Home Video Call"
 msgstr ""
 
-#: config/attributes.php.dist:586
+#: config/attributes.php.dist:592
 msgid "Home Website URL"
 msgstr ""
 
-#: config/sources.php.dist:682
+#: config/sources.php.dist:743
 msgid "IMSP"
 msgstr ""
 
@@ -691,42 +688,43 @@ msgstr ""
 msgid "Import/Export Address Books"
 msgstr ""
 
-#: config/attributes.php.dist:406
+#: config/attributes.php.dist:412
 msgid "Initials"
 msgstr ""
 
-#: config/attributes.php.dist:412
+#: config/attributes.php.dist:418
 msgid "Instant Messenger"
 msgstr ""
 
-#: lib/api.php:999 lib/api.php:1132
+#: lib/api.php:1041 lib/api.php:1174
 msgid "Invalid ID"
 msgstr ""
 
-#: scripts/import_squirrelmail_abook.php:105 lib/api.php:368 lib/api.php:696
-#: lib/api.php:751 lib/api.php:810 lib/api.php:859 lib/api.php:995
-#: lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
+#: scripts/import_squirrelmail_sql_abook.php:118
+#: scripts/import_squirrelmail_file_abook.php:107 lib/api.php:373
+#: lib/api.php:737 lib/api.php:792 lib/api.php:852 lib/api.php:901
+#: lib/api.php:1037 lib/api.php:1170 lib/api.php:1236 lib/api.php:1831
 #, php-format
 msgid "Invalid address book: %s"
 msgstr ""
 
-#: lib/api.php:1198
+#: lib/api.php:1240
 msgid "Invalid contact unique ID"
 msgstr ""
 
-#: lib/api.php:1778 lib/api.php:1864 lib/api.php:1925
+#: lib/api.php:1835 lib/api.php:1921 lib/api.php:1982
 msgid "Invalid email"
 msgstr ""
 
-#: lib/api.php:1786
+#: lib/api.php:1843
 msgid "Invalid entry"
 msgstr ""
 
-#: lib/Driver/ldap.php:317
+#: lib/Driver/ldap.php:322
 msgid "Invalid key specified."
 msgstr ""
 
-#: lib/api.php:1782
+#: lib/api.php:1839
 msgid "Invalid name"
 msgstr ""
 
@@ -734,9 +732,8 @@ msgstr ""
 msgid "Job Title"
 msgstr ""
 
-#: lib/Driver/kolab.php:1129 lib/Driver/kolab.php:1195
-#, php-format
-msgid "Key for saving must be a UID not %s!"
+#: config/attributes.php.dist:406
+msgid "Kolab Home Server"
 msgstr ""
 
 #: lib/Driver/ldap.php:64
@@ -748,7 +745,7 @@ msgstr ""
 msgid "LDIF Address Book"
 msgstr ""
 
-#: config/attributes.php.dist:436
+#: config/attributes.php.dist:442
 msgid "Language"
 msgstr ""
 
@@ -760,7 +757,7 @@ msgstr ""
 msgid "Last Name"
 msgstr ""
 
-#: config/attributes.php.dist:442
+#: config/attributes.php.dist:448
 msgid "Latitude"
 msgstr ""
 
@@ -768,7 +765,7 @@ msgstr ""
 msgid "List"
 msgstr ""
 
-#: config/sources.php.dist:251 config/sources.php.dist:944
+#: config/sources.php.dist:281 config/sources.php.dist:1009
 msgid "Location"
 msgstr ""
 
@@ -780,11 +777,11 @@ msgstr ""
 msgid "Logo MIME Type"
 msgstr ""
 
-#: config/attributes.php.dist:447
+#: config/attributes.php.dist:453
 msgid "Longitude"
 msgstr ""
 
-#: lib/api.php:616
+#: lib/api.php:657
 msgid "Malformed request."
 msgstr ""
 
@@ -792,7 +789,7 @@ msgstr ""
 msgid "Manage Address Books"
 msgstr ""
 
-#: config/attributes.php.dist:418
+#: config/attributes.php.dist:424
 msgid "Manager"
 msgstr ""
 
@@ -804,7 +801,7 @@ msgstr ""
 msgid "Matching"
 msgstr ""
 
-#: lib/api.php:329
+#: lib/api.php:334
 msgid "Maximum Number of Contacts"
 msgstr ""
 
@@ -820,7 +817,7 @@ msgstr ""
 msgid "Middle Names"
 msgstr ""
 
-#: lib/Driver/ldap.php:347
+#: lib/Driver/ldap.php:352
 msgid "Missing DN in LDAP source configuration."
 msgstr ""
 
@@ -828,7 +825,7 @@ msgstr ""
 msgid "Mobile Phone"
 msgstr ""
 
-#: lib/Driver/ldap.php:376 lib/Driver/ldap.php:392
+#: lib/Driver/ldap.php:381 lib/Driver/ldap.php:397
 #, php-format
 msgid "Modify failed: (%s) %s"
 msgstr ""
@@ -837,7 +834,7 @@ msgstr ""
 msgid "More Options..."
 msgstr ""
 
-#: lib/api.php:1902
+#: lib/api.php:1959
 msgid "More than 1 entry found"
 msgstr ""
 
@@ -857,13 +854,13 @@ msgstr ""
 msgid "Mulberry Address Book"
 msgstr ""
 
-#: lib/api.php:1810
+#: lib/api.php:1867
 #, php-format
 msgid ""
 "Multiple persons with address [%s], but none with name [%s] already exist"
 msgstr ""
 
-#: config/sources.php.dist:167
+#: config/sources.php.dist:197
 msgid "My Address Book"
 msgstr ""
 
@@ -901,7 +898,7 @@ msgstr ""
 msgid "Nickname"
 msgstr ""
 
-#: lib/api.php:1905 lib/api.php:1965
+#: lib/api.php:1962 lib/api.php:2022
 #, php-format
 msgid "No %s entry found for %s"
 msgstr ""
@@ -915,8 +912,8 @@ msgstr ""
 msgid "No Address Books are currently available. Searching is disabled."
 msgstr ""
 
-#: lib/api.php:690 lib/api.php:745 lib/api.php:805 lib/api.php:990
-#: lib/api.php:1123 lib/api.php:1189
+#: lib/api.php:731 lib/api.php:786 lib/api.php:846 lib/api.php:1032
+#: lib/api.php:1165 lib/api.php:1231
 msgid "No address book specified"
 msgstr ""
 
@@ -936,7 +933,7 @@ msgstr ""
 msgid "No source for favourite recipients exists."
 msgstr ""
 
-#: lib/api.php:893 lib/api.php:1235
+#: lib/api.php:935 lib/api.php:1277
 msgid "No vCard data was found."
 msgstr ""
 
@@ -961,11 +958,11 @@ msgstr ""
 msgid "Number of items per page"
 msgstr ""
 
-#: lib/api.php:1041 lib/api.php:1260
+#: lib/api.php:1083 lib/api.php:1302
 msgid "Object not found"
 msgstr ""
 
-#: lib/Driver/kolab.php:1199
+#: lib/Driver/kolab.php:1207
 #, php-format
 msgid "Object with UID %s does not exist!"
 msgstr ""
@@ -985,15 +982,15 @@ msgid ""
 "to \"None\"."
 msgstr ""
 
-#: lib/api.php:1243
+#: lib/api.php:1285
 msgid "Only one vcard supported."
 msgstr ""
 
-#: config/sources.php.dist:258 config/sources.php.dist:950
+#: config/sources.php.dist:288 config/sources.php.dist:1015
 msgid "Organization"
 msgstr ""
 
-#: config/sources.php.dist:259 config/sources.php.dist:952
+#: config/sources.php.dist:289 config/sources.php.dist:1017
 msgid "Other"
 msgstr ""
 
@@ -1001,7 +998,7 @@ msgstr ""
 msgid "PGP Public Key"
 msgstr ""
 
-#: config/attributes.php.dist:517
+#: config/attributes.php.dist:523
 msgid "PTT"
 msgstr ""
 
@@ -1013,12 +1010,12 @@ msgstr ""
 msgid "Permanently delete this contact?"
 msgstr ""
 
-#: deletefile.php:36 lib/Driver.php:804 lib/api.php:870 lib/api.php:1795
-#: lib/Driver/sql.php:515
+#: deletefile.php:36 lib/Driver.php:817 lib/api.php:912 lib/api.php:1852
+#: lib/Driver/sql.php:521
 msgid "Permission denied"
 msgstr ""
 
-#: config/sources.php.dist:248 config/sources.php.dist:940
+#: config/sources.php.dist:278 config/sources.php.dist:1005
 msgid "Personal"
 msgstr ""
 
@@ -1043,17 +1040,17 @@ msgstr ""
 msgid "Previous"
 msgstr ""
 
-#: lib/Driver/ldap.php:197
+#: lib/Driver/ldap.php:202
 #, php-format
 msgid "Query failed: (%s) %s"
 msgstr ""
 
-#: lib/Driver/ldap.php:242 lib/Driver/ldap.php:250 lib/Driver/ldap.php:486
+#: lib/Driver/ldap.php:247 lib/Driver/ldap.php:255 lib/Driver/ldap.php:491
 #, php-format
 msgid "Read failed: (%s) %s"
 msgstr ""
 
-#: lib/Driver.php:2105 lib/Driver/null.php:52
+#: lib/Driver.php:2127 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr ""
 
@@ -1072,7 +1069,7 @@ msgstr ""
 msgid "Remove from this list"
 msgstr ""
 
-#: lib/Driver.php:2143
+#: lib/Driver.php:2165
 msgid ""
 "Removing user data is not supported in the current address book storage "
 "driver."
@@ -1084,7 +1081,7 @@ msgid ""
 "deletes all entries in your current address book.</strong>"
 msgstr ""
 
-#: lib/Driver.php:698
+#: lib/Driver.php:711
 msgid "Requested object not found."
 msgstr ""
 
@@ -1096,11 +1093,11 @@ msgstr ""
 msgid "S/MIME Public Certificate"
 msgstr ""
 
-#: config/attributes.php.dist:511
+#: config/attributes.php.dist:517
 msgid "SIP"
 msgstr ""
 
-#: lib/Driver/ldap.php:84
+#: lib/Driver/ldap.php:89
 #, php-format
 msgid "STARTTLS failed: (%s) %s"
 msgstr ""
@@ -1113,7 +1110,7 @@ msgstr ""
 msgid "Save search as a virtual address book?"
 msgstr ""
 
-#: lib/Driver.php:2131 lib/Driver/null.php:67
+#: lib/Driver.php:2153 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr ""
 
@@ -1123,11 +1120,11 @@ msgstr ""
 msgid "Search"
 msgstr ""
 
-#: lib/api.php:1568
+#: lib/api.php:1615
 msgid "Search failed"
 msgstr ""
 
-#: lib/api.php:1800 lib/api.php:1806 lib/api.php:1815 lib/api.php:1828
+#: lib/api.php:1857 lib/api.php:1863 lib/api.php:1872 lib/api.php:1885
 #, php-format
 msgid "Search failed: %s"
 msgstr ""
@@ -1136,7 +1133,7 @@ msgstr ""
 msgid "Search for: "
 msgstr ""
 
-#: lib/Driver.php:2090 lib/Driver/null.php:47
+#: lib/Driver.php:2112 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr ""
 
@@ -1235,7 +1232,7 @@ msgstr ""
 msgid "Source:"
 msgstr ""
 
-#: lib/api.php:322
+#: lib/api.php:327
 msgid "Sources"
 msgstr ""
 
@@ -1298,7 +1295,7 @@ msgstr ""
 msgid "The VFS backend needs to be configured to enable attachment uploads."
 msgstr ""
 
-#: lib/Driver.php:2061
+#: lib/Driver.php:2083
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr ""
@@ -1313,7 +1310,7 @@ msgstr ""
 msgid "The address book could not be purged: %s"
 msgstr ""
 
-#: lib/api.php:1061
+#: lib/api.php:1103
 msgid "The address book with your own contact doesn't exist anymore."
 msgstr ""
 
@@ -1373,7 +1370,7 @@ msgstr[1] ""
 msgid "There was a problem creating the virtual address book: %s"
 msgstr ""
 
-#: lib/Forms/AddContact.php:95
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
@@ -1402,11 +1399,11 @@ msgstr ""
 msgid "There was an error importing the data: %s"
 msgstr ""
 
-#: lib/api.php:889 lib/api.php:1230
+#: lib/api.php:931 lib/api.php:1272
 msgid "There was an error importing the iCalendar data."
 msgstr ""
 
-#: lib/api.php:258
+#: lib/api.php:263
 #, php-format
 msgid "There was an error removing an address book for %s"
 msgstr ""
@@ -1438,7 +1435,7 @@ msgstr ""
 msgid "This file format is not supported."
 msgstr ""
 
-#: lib/api.php:1819 lib/api.php:1832
+#: lib/api.php:1876 lib/api.php:1889
 #, php-format
 msgid "This person already has a %s entry in the address book"
 msgstr ""
@@ -1456,7 +1453,7 @@ msgstr ""
 msgid "Unable to find contact owner."
 msgstr ""
 
-#: lib/Driver.php:1981 lib/Turba.php:659
+#: lib/Driver.php:2003 lib/Turba.php:663
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr ""
@@ -1474,7 +1471,7 @@ msgstr ""
 msgid "Unfiled"
 msgstr ""
 
-#: lib/api.php:927 lib/api.php:1038 lib/api.php:1248
+#: lib/api.php:969 lib/api.php:1080 lib/api.php:1290
 #, php-format
 msgid "Unsupported Content-Type: %s"
 msgstr ""
@@ -1492,7 +1489,7 @@ msgstr ""
 msgid "View to display by default:"
 msgstr ""
 
-#: config/attributes.php.dist:506
+#: config/attributes.php.dist:512
 msgid "VoIP"
 msgstr ""
 
@@ -1504,7 +1501,7 @@ msgstr ""
 msgid "Work Address"
 msgstr ""
 
-#: config/attributes.php.dist:570
+#: config/attributes.php.dist:576
 msgid "Work Address Extended"
 msgstr ""
 
@@ -1516,23 +1513,23 @@ msgstr ""
 msgid "Work Country"
 msgstr ""
 
-#: config/attributes.php.dist:454
+#: config/attributes.php.dist:460
 msgid "Work Email"
 msgstr ""
 
-#: config/attributes.php.dist:471
+#: config/attributes.php.dist:477
 msgid "Work Fax"
 msgstr ""
 
-#: config/attributes.php.dist:576
+#: config/attributes.php.dist:582
 msgid "Work Latitude"
 msgstr ""
 
-#: config/attributes.php.dist:581
+#: config/attributes.php.dist:587
 msgid "Work Longitude"
 msgstr ""
 
-#: config/attributes.php.dist:481
+#: config/attributes.php.dist:487
 msgid "Work Mobile Phone"
 msgstr ""
 
@@ -1556,11 +1553,11 @@ msgstr ""
 msgid "Work Street Address"
 msgstr ""
 
-#: config/attributes.php.dist:496
+#: config/attributes.php.dist:502
 msgid "Work Video Call"
 msgstr ""
 
-#: config/attributes.php.dist:564
+#: config/attributes.php.dist:570
 msgid "Work Website URL"
 msgstr ""
 
@@ -1577,7 +1574,7 @@ msgstr ""
 msgid "You are not allowed to delete this addressbook."
 msgstr ""
 
-#: lib/api.php:204
+#: lib/api.php:209
 msgid "You are not allowed to remove user data."
 msgstr ""
 
@@ -1593,7 +1590,7 @@ msgstr ""
 msgid "You cannot delete contacts from a virtual address book"
 msgstr ""
 
-#: lib/api.php:1056
+#: lib/api.php:1098
 msgid "You didn't mark a contact as your own yet."
 msgstr ""
 
@@ -1610,13 +1607,13 @@ msgstr ""
 msgid "You do not have permissions to delete this address book."
 msgstr ""
 
-#: lib/api.php:1070
+#: lib/api.php:1112
 msgid ""
 "You don't have sufficient permissions to read the address book that contains "
 "your own contact."
 msgstr ""
 
-#: lib/Driver/ldap.php:741
+#: lib/Driver/ldap.php:749
 msgid ""
 "You must have the Net_LDAP PEAR library installed to use the schema check "
 "function."
@@ -1652,7 +1649,7 @@ msgstr ""
 msgid "Your own contact"
 msgstr ""
 
-#: lib/api.php:1075
+#: lib/api.php:1117
 msgid "Your own contact cannot be found in the address book."
 msgstr ""
 
@@ -1660,7 +1657,7 @@ msgstr ""
 msgid "[no value]"
 msgstr ""
 
-#: lib/Turba.php:601
+#: lib/Turba.php:605
 msgid "_Browse"
 msgstr ""
 
@@ -1676,7 +1673,7 @@ msgstr ""
 msgid "_Edit"
 msgstr ""
 
-#: lib/Turba.php:610
+#: lib/Turba.php:614
 msgid "_Import/Export"
 msgstr ""
 
@@ -1684,15 +1681,15 @@ msgstr ""
 msgid "_Lists"
 msgstr ""
 
-#: lib/Turba.php:598
+#: lib/Turba.php:602
 msgid "_My Address Books"
 msgstr ""
 
-#: lib/Turba.php:604
+#: lib/Turba.php:608
 msgid "_New Contact"
 msgstr ""
 
-#: lib/Turba.php:615
+#: lib/Turba.php:619
 msgid "_Print"
 msgstr ""
 
@@ -1700,7 +1697,7 @@ msgstr ""
 msgid "_Remove from this list"
 msgstr ""
 
-#: lib/Turba.php:606
+#: lib/Turba.php:610
 msgid "_Search"
 msgstr ""
 
@@ -1745,7 +1742,7 @@ msgstr ""
 msgid "descending"
 msgstr ""
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "female"
 msgstr ""
 
@@ -1754,7 +1751,7 @@ msgstr ""
 msgid "in %s"
 msgstr ""
 
-#: config/attributes.php.dist:433
+#: config/attributes.php.dist:439
 msgid "male"
 msgstr ""
 
diff --git a/po/uk_UA.po b/po/uk_UA.po
index 8c20fbb..bf53927 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -1,5 +1,5 @@
 # Turba Ukrainian win-1251 translation.
-# Copyright (C)
+# Copyright
 # Andriy Kopystyansky <anri at polynet.lviv.ua>, 2008
 #
 msgid ""
diff --git a/po/zh_CN.po b/po/zh_CN.po
index ebba7ec..9ca65a2 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -1,5 +1,5 @@
 # Turba Simplified Chinese Translation
-# Copyright (C) 2001 WangHengWen.
+# Copyright 2001 WangHengWen.
 # WangHengWen <whw at my169.com>, 2001.
 #
 msgid ""
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 9426321..2312fdc 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -1,12 +1,12 @@
 # Turba Traditional Chinese Translation.
-# Copyright (C) 2001 David Chang,TAIWAN. ±i¨}¤å,¥xÆW
+# Copyright 2001 David Chang,TAIWAN. ±i¨}¤å,¥xÆW
 # David Chang <david at tmv.gov.tw>, 2001.12
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Turba 2.2\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2008-05-11 18:39+0800\n"
+"POT-Creation-Date: 2008-12-15 13:56+0800\n"
 "PO-Revision-Date: 2008-03-28 12:00+0800\n"
 "Last-Translator: David Cahng <david at tmv.gov.tw>\n"
 "Language-Team: Traditional Chinese <i18n at lists.horde.org>\n"
@@ -23,17 +23,17 @@ msgstr "
 msgid " Delete IMSP Address Book"
 msgstr "§R°£ IMSP ³q°T¿ý:"
 
-#: data.php:350
+#: data.php:455
 #, php-format
 msgid "\"%s\" already exists and was not imported."
 msgstr "\"%s\" ¤w¦s¦b¦Ó¥B¨S¦³¶×¤J¸ê®Æ."
 
-#: lib/Forms/EditContact.php:76
+#: lib/Forms/EditContact.php:83
 #, php-format
 msgid "\"%s\" updated, but saving the uploaded file failed: %s"
 msgstr "\"%s\" ¤w§ó·s,¦ýÀx¦s¤W¶ÇÀɮ׮ɥ¢±Ñ: %s"
 
-#: lib/Forms/EditContact.php:78 lib/Forms/EditContact.php:81
+#: lib/Forms/EditContact.php:85 lib/Forms/EditContact.php:88
 #, php-format
 msgid "\"%s\" updated."
 msgstr "\"%s\" ¤w§ó·s."
@@ -56,34 +56,34 @@ msgstr "\"
 msgid "\"Lastname, Firstname\" (ie. Doe, John)"
 msgstr "\"©m¤ó ¦W¦r\" (¨Ò¦p. ±i ¨}¤å)"
 
-#: lib/Forms/AddContact.php:83
+#: lib/Driver.php:620
+#, php-format
+msgid "%d. %s of %s"
+msgstr "%d. %s ¦@ %s"
+
+#: lib/Forms/AddContact.php:91
 #, php-format
 msgid "%s added."
 msgstr "%s ¤w·s¼W."
 
-#: data.php:369
+#: data.php:483
 #, php-format
 msgid "%s file successfully imported."
 msgstr "ÀÉ®× %s ¤w¶×¤J§¹¦¨."
 
-#: lib/Driver.php:555
-#, php-format
-msgid "%s of %s"
-msgstr "%s ¦@ %s"
-
 #: templates/list/numPager.inc:6
 #, php-format
 msgid "%s to %s of %s"
 msgstr " %s ¨ì %s ¦@ %s"
 
-#: lib/Turba.php:560
+#: lib/Turba.php:541
 #, php-format
 msgid "%s's Address Book"
 msgstr "%s ªº³q°T¿ý"
 
-#: lib/Block/minisearch.php:42
-msgid "A browser that supports iFrames is required"
-msgstr "ÂsÄý¾¹¥²¶·¤ä´© iFrames"
+#: lib/Block/minisearch.php:44
+msgid "A browser that supports iframes is required"
+msgstr "ÂsÄý¾¹¥²¶·¤ä´© iframes"
 
 #: view.php:54
 #, php-format
@@ -110,7 +110,7 @@ msgstr "
 msgid "Add to"
 msgstr "·s¼W¨ì"
 
-#: lib/Driver.php:1876 lib/Driver/null.php:57
+#: lib/Driver.php:2115 lib/Driver/null.php:57
 msgid "Adding contacts is not available."
 msgstr "©Ò·s¼Wªº³sµ¸¤HµL®Ä."
 
@@ -130,7 +130,7 @@ msgstr "
 msgid "Address Books"
 msgstr "³q°T¿ý"
 
-#: data.php:330
+#: data.php:435
 msgid "Address book successfully purged."
 msgstr "³q°T¿ý¤w§¹¦¨²MªÅ."
 
@@ -139,7 +139,7 @@ msgstr "
 msgid "Address books that will not be displayed:"
 msgstr "¤£Åã¥Üªº³q°T¿ý:"
 
-#: search.php:199 templates/browse/search.inc:47
+#: search.php:184 templates/browse/search.inc:47
 msgid "Advanced Search"
 msgstr "¶i¶¥·j´M"
 
@@ -151,7 +151,7 @@ msgstr "
 msgid "All"
 msgstr "©Ò¦³"
 
-#: lib/api.php:810
+#: lib/api.php:941
 msgid "Already Exists"
 msgstr "¤w¦s¦b"
 
@@ -172,11 +172,11 @@ msgstr "
 msgid "Are you sure that you want to delete the selected contacts?"
 msgstr "§A½T©w­n§R°£©Ò¿ï¾Üªº³sµ¸¤H¶Ü?"
 
-#: config/attributes.php.dist:378
+#: config/attributes.php.dist:430
 msgid "Assistant"
 msgstr "§U²z"
 
-#: search.php:196 templates/browse/search.inc:46
+#: search.php:181 templates/browse/search.inc:46
 msgid "Basic Search"
 msgstr "°ò¥»·j´M"
 
@@ -193,7 +193,7 @@ msgstr "
 msgid "Birthdays"
 msgstr "¥Í¤é"
 
-#: contact.php:106 templates/browse/row.inc:6
+#: contact.php:128 templates/browse/row.inc:10
 msgid "Blank name"
 msgstr "ªÅ¥Õ¦WºÙ"
 
@@ -201,16 +201,16 @@ msgstr "
 msgid "Both"
 msgstr "¥þ³¡"
 
-#: addressbooks/index.php:39 templates/menu.inc:8
-#: templates/addressbook_list.php:29
+#: templates/addressbook_list.php:29 templates/menu.inc:8
+#: addressbooks/index.php:39
 msgid "Browse"
 msgstr "ÂsÄý"
 
-#: config/attributes.php.dist:288
+#: config/attributes.php.dist:300
 msgid "Business Category"
 msgstr "°Ó·~¤ÀÃþ"
 
-#: data.php:60
+#: data.php:101
 msgid "CSV"
 msgstr "³rÂI¤À¹j®æ¦¡ .csv"
 
@@ -227,24 +227,24 @@ msgstr "
 msgid "Cannot delete all address book entries for %s"
 msgstr "µLªk§R°£©Ò¦³ %s ªº³q°T¿ý°O¿ý."
 
-#: config/attributes.php.dist:350
+#: config/attributes.php.dist:388
 msgid "Category"
 msgstr "¤ÀÃþ"
 
-#: templates/browse/column_headers.inc:24
+#: templates/browse/column_headers.inc:25
 #, php-format
 msgid "Change %s sort to %s"
 msgstr "§ïÅÜ %s ªº±Æ¦C¤è¦V¬° %s"
 
-#: addressbooks/index.php:41 templates/addressbook_list.php:33
+#: templates/addressbook_list.php:33 addressbooks/index.php:41
 msgid "Change Permissions"
 msgstr "Åܧó¦s¨ú¼Ò¦¡"
 
-#: templates/browse/column_headers.inc:7
+#: templates/browse/column_headers.inc:8
 msgid "Check All/None"
 msgstr "¿ï¨ú ¥þ³¡/µL"
 
-#: templates/browse/column_headers.inc:7
+#: templates/browse/column_headers.inc:8
 msgid "Check _All/None"
 msgstr "¿ï¨ú ¥þ³¡/µL_A"
 
@@ -264,11 +264,13 @@ msgstr "
 msgid "Choose which address books to use."
 msgstr "¿ï¾Ü­n¨Ï¥Îªº³q°T¿ý."
 
-#: templates/prefs/columnselect.inc:43
-msgid "Click an address book to sort its columns:"
-msgstr "¿ï¾Ü­n±Æ¦CÄæ¦ìªº³q°T¿ý:"
+#: templates/prefs/columnselect.inc:41
+msgid ""
+"Click an address book to sort its columns. Drag columns to re-arrange them. "
+"Check a column to enable it."
+msgstr "ÂI¿ï¤@¥»³q°T¿ý¥H±Æ§Ç¨äÄæ¦ì. ©ì¦²­n­«·s±Æ¦CªºÄæ¦ì. ÂI¿ïÄæ¦ì¥H±Ò¥Î."
 
-#: templates/block/minisearch.inc:27
+#: templates/block/minisearch.inc:26
 msgid "Close"
 msgstr "Ãö³¬"
 
@@ -288,58 +290,60 @@ msgstr "
 msgid "Comma separated values (Microsoft Outlook)"
 msgstr "³rÂI¤À¹j­È (Microsoft Outlook *.csv)"
 
-#: config/attributes.php.dist:476
+#: config/attributes.php.dist:528
 msgid "Common Address Extended"
 msgstr "³q±`¦a§}"
 
-#: config/attributes.php.dist:494
+#: config/attributes.php.dist:546
 msgid "Common City"
 msgstr "³q±`©ÒÄÝ«°¥«"
 
-#: config/attributes.php.dist:512
+#: config/attributes.php.dist:564
 msgid "Common Country"
 msgstr "³q±`©ÒÄÝ°ê®a"
 
-#: config/attributes.php.dist:420
+#: config/attributes.php.dist:472
 msgid "Common Phone"
 msgstr "³q±`¹q¸Ü"
 
-#: config/attributes.php.dist:488
+#: config/attributes.php.dist:540
 msgid "Common Post Office Box"
 msgstr "³q±`¶l½c"
 
-#: config/attributes.php.dist:506
+#: config/attributes.php.dist:558
 msgid "Common Postal Code"
 msgstr "³q±`¶l»¼°Ï¸¹"
 
-#: config/attributes.php.dist:500
+#: config/attributes.php.dist:552
 msgid "Common State/Province"
 msgstr "³q±`©ÒÄݬ٥÷"
 
-#: config/attributes.php.dist:482
+#: config/attributes.php.dist:534
 msgid "Common Street"
 msgstr "³q±`¦í§}"
 
-#: config/attributes.php.dist:445
+#: config/attributes.php.dist:497
 msgid "Common Video Call"
 msgstr ""
 
-#: config/sources.php.dist:243 config/sources.php.dist:922
+#: config/sources.php.dist:256 config/sources.php.dist:952
 msgid "Communications"
 msgstr "³q°T"
 
-#: config/attributes.php.dist:294
+#: config/attributes.php.dist:306
 msgid "Company"
 msgstr "¤½¥q"
 
-#: config/attributes.php.dist:223
+#: config/attributes.php.dist:235
 msgid "Company Address"
 msgstr "¤½¥q¦a§}"
 
-#: scripts/import_squirrelmail_abook.php:112 lib/api.php:433 lib/api.php:478
-#: lib/api.php:529 lib/api.php:572 lib/api.php:627 lib/api.php:686
-#: lib/api.php:736 lib/api.php:872 lib/api.php:964 lib/api.php:1030
-#: lib/api.php:1136 lib/api.php:1369 lib/api.php:1446 lib/api.php:1595
+#: scripts/import_squirrelmail_file_abook.php:114
+#: scripts/import_squirrelmail_sql_abook.php:125 lib/api.php:546
+#: lib/api.php:600 lib/api.php:653 lib/api.php:701 lib/api.php:756
+#: lib/api.php:815 lib/api.php:866 lib/api.php:1004 lib/api.php:1066
+#: lib/api.php:1137 lib/api.php:1204 lib/api.php:1324 lib/api.php:1563
+#: lib/api.php:1640 lib/api.php:1791
 #, php-format
 msgid "Connection failed: %s"
 msgstr "³sµ²¥¢±Ñ: %s"
@@ -352,7 +356,7 @@ msgstr "
 msgid "Contact Search"
 msgstr "³sµ¸¤H·j´M"
 
-#: config/sources.php.dist:851
+#: config/sources.php.dist:868
 msgid "Contacts"
 msgstr "³sµ¸¤H"
 
@@ -360,7 +364,7 @@ msgstr "
 msgid "Contacts displayed:"
 msgstr "¤wÅã¥Üªº³sµ¸¤H:"
 
-#: lib/Views/Browse.php:339
+#: lib/Views/Browse.php:346
 #, php-format
 msgid "Contacts in list: %s"
 msgstr "¸s²Õ: %s ¤¤ªº³sµ¸¤H"
@@ -381,7 +385,7 @@ msgstr "
 msgid "Create a new Address Book"
 msgstr "«Ø¥ß³q°T¿ý"
 
-#: lib/ListView.php:447
+#: lib/ListView.php:448
 msgid "Create a new Contact List in:"
 msgstr "¦b¤U¦C³q°T¿ý«Ø¥ß·s¸s²Õ:"
 
@@ -389,13 +393,13 @@ msgstr "
 msgid "Created"
 msgstr "«Ø¥ß"
 
-#: contact.php:89
+#: contact.php:95
 msgid "De_lete"
 msgstr "§R°£_l"
 
-#: addressbooks/index.php:42 templates/addressbook_list.php:35
-#: templates/browse/actions.inc:3 lib/Views/DeleteContact.php:58
-#: lib/Forms/DeleteAddressBook.php:45
+#: templates/addressbook_list.php:35 templates/browse/actions.inc:3
+#: lib/Views/DeleteContact.php:58 lib/Forms/DeleteAddressBook.php:45
+#: addressbooks/index.php:42
 msgid "Delete"
 msgstr "§R°£"
 
@@ -404,12 +408,16 @@ msgstr "
 msgid "Delete %s"
 msgstr "§R°£ %s"
 
+#: lib/api.php:644
+msgid "Delete denied."
+msgstr "§R°£¾D©Ú."
+
 #: lib/Driver/ldap.php:321
 #, php-format
 msgid "Delete failed: (%s) %s"
 msgstr "§R°£¥¢±Ñ: (%s) %s"
 
-#: lib/Driver.php:1884 lib/Driver/null.php:62
+#: lib/Driver.php:2123 lib/Driver/null.php:62
 msgid "Deleting contacts is not available."
 msgstr "©Ò§R°£ªº³sµ¸¤HµL®Ä."
 
@@ -417,7 +425,7 @@ msgstr "
 msgid "Deletion failed"
 msgstr "§R°£¥¢±Ñ"
 
-#: config/attributes.php.dist:300
+#: config/attributes.php.dist:312
 msgid "Department"
 msgstr "³¡ªù"
 
@@ -438,23 +446,19 @@ msgstr "
 msgid "Display Options"
 msgstr "Åã¥Ü¿ï¶µ"
 
-#: lib/Object.php:348
+#: lib/Object.php:357
 msgid "Download"
 msgstr "¤U¸ü"
 
-#: templates/browse/row.inc:15 templates/browse/row.inc:16
-#: templates/browse/contactrow.inc:25
+#: templates/browse/contactrow.inc:25 templates/browse/row.inc:27
+#: templates/browse/row.inc:28
 msgid "Download vCard"
 msgstr "¤U¸ü vCard"
 
-#: templates/prefs/columnselect.inc:52
-msgid "Drag columns to re-arrange them. Check a column to enable it."
-msgstr "ÂI¿ï¨Ã©ì¦²­n­«·s±Æ¦CªºÄæ¦ì."
-
-#: addressbooks/index.php:40 templates/addressbook_list.php:31
-#: templates/browse/actions.inc:6 templates/browse/column_headers.inc:10
-#: templates/browse/row.inc:28 templates/browse/row.inc:29
-#: templates/browse/contactrow.inc:33
+#: templates/addressbook_list.php:31 templates/browse/actions.inc:6
+#: templates/browse/column_headers.inc:11 templates/browse/contactrow.inc:33
+#: templates/browse/row.inc:40 templates/browse/row.inc:41
+#: addressbooks/index.php:40
 msgid "Edit"
 msgstr "½s¿è"
 
@@ -468,20 +472,20 @@ msgstr "
 msgid "Edit %s"
 msgstr "½s¿è %s"
 
-#: config/attributes.php.dist:237
+#: config/attributes.php.dist:249
 msgid "Email"
 msgstr "¹q¤l¶l¥ó"
 
-#: config/attributes.php.dist:243
+#: config/attributes.php.dist:255
 msgid "Emails"
 msgstr "¹q¤l¶l¥ó"
 
-#: lib/Views/Browse.php:263 lib/Views/Browse.php:303
+#: lib/Views/Browse.php:270 lib/Views/Browse.php:310
 #, php-format
 msgid "Error adding %d contact(s) to list."
 msgstr "·s¼W %d ­Ó³sµ¸¤H¨ì¸s²Õ¤¤®Éµo¥Í¿ù»~."
 
-#: lib/Views/Browse.php:265 lib/Views/Browse.php:305
+#: lib/Views/Browse.php:272 lib/Views/Browse.php:312
 #, php-format
 msgid "Error adding %d of %d requested contact(s) to list."
 msgstr "·s¼W²Ä %d ­Ó¦@ %d ­Ó³sµ¸¤H¨ì¸s²Õ¤¤®Éµo¥Í¿ù»~."
@@ -506,7 +510,7 @@ msgstr "
 msgid "Error removing %d of %d requested contact(s) from list."
 msgstr "¦Û¸s²Õ¤¤²¾°£²Ä %d ­Ó¦@ %d ­Ó³sµ¸¤H®Éµo¥Í¿ù»~."
 
-#: lib/api.php:578
+#: lib/api.php:707
 #, php-format
 msgid "Error searching the address book: %s"
 msgstr "·j´M³q°T¿ý: %s ¥¢±Ñ"
@@ -527,7 +531,7 @@ msgstr "
 msgid "Export the following address book completely."
 msgstr "§¹¾ã¶×¥X¤U¦C³q°T¿ý."
 
-#: add.php:42 data.php:142 data.php:241 data.php:319 search.php:121
+#: add.php:42 data.php:247 data.php:346 data.php:424 search.php:106
 #: lib/Views/Browse.php:84 lib/Views/Browse.php:152 lib/Views/Browse.php:180
 #, php-format
 msgid "Failed to access the address book: %s"
@@ -538,11 +542,11 @@ msgstr "
 msgid "Failed to add %s to %s: %s"
 msgstr "·s¼W %s ¨ì %s: %s"
 
-#: lib/Views/Browse.php:345
+#: lib/Views/Browse.php:352
 msgid "Failed to browse list"
 msgstr "ÂsÄý¸s²Õ¥¢±Ñ"
 
-#: lib/Views/Browse.php:376
+#: lib/Views/Browse.php:383
 msgid "Failed to browse the directory"
 msgstr "·j´M¥Ø¿ý¥¢±Ñ"
 
@@ -556,20 +560,20 @@ msgstr "
 msgid "Failed to find object to be added: %s"
 msgstr "§ä´Mª«¥ó¥H·s¼W¨ì:%s¥¢±Ñ"
 
-#: search.php:190
+#: search.php:175
 msgid "Failed to search the address book"
 msgstr "·j´M³q°T¿ý¥¢±Ñ"
 
-#: data.php:157
+#: data.php:262
 #, php-format
 msgid "Failed to search the directory: %s"
 msgstr "·j´M¥Ø¿ý: %s ¥¢±Ñ"
 
-#: config/sources.php.dist:550
+#: config/sources.php.dist:565
 msgid "Favourite Recipients"
 msgstr "¼öªù¤H¿ï"
 
-#: config/attributes.php.dist:264
+#: config/attributes.php.dist:276
 msgid "Fax"
 msgstr "¶Ç¯u"
 
@@ -581,7 +585,7 @@ msgstr "
 msgid "Find"
 msgstr "´M§ä"
 
-#: lib/Forms/EditContact.php:121 lib/Forms/EditContact.php:160
+#: lib/Forms/EditContact.php:128 lib/Forms/EditContact.php:167
 msgid "Finish"
 msgstr "§¹¦¨"
 
@@ -589,7 +593,7 @@ msgstr "
 msgid "First Name"
 msgstr "¦W¦r"
 
-#: config/attributes.php.dist:326
+#: config/attributes.php.dist:350
 msgid "Freebusy URL"
 msgstr "Freebusy ºô§}"
 
@@ -597,83 +601,83 @@ msgstr "Freebusy 
 msgid "From"
 msgstr "±q"
 
-#: config/attributes.php.dist:384
+#: config/attributes.php.dist:436
 msgid "Gender"
 msgstr "©Ê§O"
 
-#: config/sources.php.dist:776
+#: config/sources.php.dist:791
 msgid "Global Address Book"
 msgstr "¥þ°ì³q°T¿ý"
 
-#: templates/browse/row.inc:49 templates/browse/contactrow.inc:44
+#: templates/browse/contactrow.inc:44 templates/browse/row.inc:61
 msgid "Group"
 msgstr "¸s²Õ"
 
-#: config/attributes.php.dist:123
+#: config/attributes.php.dist:135
 msgid "Home Address"
 msgstr "¦í®a¦a§}"
 
-#: config/attributes.php.dist:546
+#: config/attributes.php.dist:598
 msgid "Home Address Extended"
 msgstr "¦í®a¦a§}"
 
-#: config/attributes.php.dist:141
+#: config/attributes.php.dist:153
 msgid "Home City"
 msgstr "¦í®a©ÒÄÝ«°¥«"
 
-#: config/attributes.php.dist:159
+#: config/attributes.php.dist:171
 msgid "Home Country"
 msgstr "¦í®a©ÒÄÝ°ê®a"
 
-#: config/attributes.php.dist:414
+#: config/attributes.php.dist:466
 msgid "Home Email"
 msgstr "¦í®a¹q¤l¶l¥ó"
 
-#: config/attributes.php.dist:430
+#: config/attributes.php.dist:482
 msgid "Home Fax"
 msgstr "¦í®a¶Ç¯u"
 
-#: config/attributes.php.dist:552
+#: config/attributes.php.dist:604
 msgid "Home Latitude"
 msgstr "¦í®a½n«×"
 
-#: config/attributes.php.dist:557
+#: config/attributes.php.dist:609
 msgid "Home Longitude"
 msgstr "¦í®a¸g«×"
 
-#: config/attributes.php.dist:440
+#: config/attributes.php.dist:492
 msgid "Home Mobile Phone"
 msgstr "¦í®a¦æ°Ê¹q¸Ü"
 
-#: config/attributes.php.dist:249
+#: config/attributes.php.dist:261
 msgid "Home Phone"
 msgstr "¦í®a¹q¸Ü"
 
-#: config/attributes.php.dist:135
+#: config/attributes.php.dist:147
 msgid "Home Post Office Box"
 msgstr "¦í®a¶l½c"
 
-#: config/attributes.php.dist:153
+#: config/attributes.php.dist:165
 msgid "Home Postal Code"
 msgstr "¦í®a¶l»¼°Ï¸¹"
 
-#: config/attributes.php.dist:147
+#: config/attributes.php.dist:159
 msgid "Home State/Province"
 msgstr "¦í®a©ÒÄݬ٥÷"
 
-#: config/attributes.php.dist:129
+#: config/attributes.php.dist:141
 msgid "Home Street Address"
 msgstr "¦í®a¦í§}"
 
-#: config/attributes.php.dist:455
+#: config/attributes.php.dist:507
 msgid "Home Video Call"
 msgstr ""
 
-#: config/attributes.php.dist:540
+#: config/attributes.php.dist:592
 msgid "Home Website URL"
 msgstr "¦í®aºô§}"
 
-#: config/sources.php.dist:667
+#: config/sources.php.dist:682
 msgid "IMSP"
 msgstr "IMSP"
 
@@ -682,38 +686,39 @@ msgstr "IMSP"
 msgid "Import Address Book, Step %d"
 msgstr "¶×¤J³q°T¿ý, ¨BÆJ %d"
 
-#: data.php:387
+#: data.php:501
 msgid "Import/Export Address Books"
 msgstr "¶×¤J/¶×¥X ³q°T¿ý"
 
-#: config/attributes.php.dist:360
+#: config/attributes.php.dist:412
 msgid "Initials"
 msgstr "¦WºÙªº°_­º¦r¥À"
 
-#: config/attributes.php.dist:366
+#: config/attributes.php.dist:418
 msgid "Instant Messenger"
 msgstr "§Y®É³q°T"
 
-#: lib/api.php:867 lib/api.php:959
+#: lib/api.php:999 lib/api.php:1132
 msgid "Invalid ID"
 msgstr "µL®Äªº½s¸¹"
 
-#: scripts/import_squirrelmail_abook.php:105 lib/api.php:345 lib/api.php:567
-#: lib/api.php:622 lib/api.php:681 lib/api.php:729 lib/api.php:863
-#: lib/api.php:955 lib/api.php:1020 lib/api.php:1578
+#: scripts/import_squirrelmail_file_abook.php:107
+#: scripts/import_squirrelmail_sql_abook.php:118 lib/api.php:368
+#: lib/api.php:696 lib/api.php:751 lib/api.php:810 lib/api.php:859
+#: lib/api.php:995 lib/api.php:1128 lib/api.php:1194 lib/api.php:1774
 #, php-format
 msgid "Invalid address book: %s"
 msgstr "µL®Äªº³q°T¿ý: %s"
 
-#: lib/api.php:1024
+#: lib/api.php:1198
 msgid "Invalid contact unique ID"
 msgstr "µL®ÄªºÁpµ¸¤H°ß¤@ÃѧO½X"
 
-#: lib/api.php:1582 lib/api.php:1668 lib/api.php:1729
+#: lib/api.php:1778 lib/api.php:1864 lib/api.php:1925
 msgid "Invalid email"
 msgstr "µL®Äªº¹q¤l¦í§}"
 
-#: lib/api.php:1590
+#: lib/api.php:1786
 msgid "Invalid entry"
 msgstr "µL®Äªº°O¿ý"
 
@@ -721,29 +726,38 @@ msgstr "
 msgid "Invalid key specified."
 msgstr "«ü©wªºª÷Æ_µL®Ä"
 
-#: lib/api.php:1586
+#: lib/api.php:1782
 msgid "Invalid name"
 msgstr "µL®Äªº¦WºÙ"
 
-#: config/attributes.php.dist:276
+#: config/attributes.php.dist:288
 msgid "Job Title"
 msgstr "¾ºÙ"
 
-#: lib/Driver/kolab.php:1114 lib/Driver/kolab.php:1180
+#: lib/Driver/kolab.php:1119
+#, php-format
+msgid "Key for saving must be \\'uid\\' not %s!"
+msgstr "Àx¦sªºª÷Æ_¥²¶·¬O \\'uid\\' ¦Ó«D %s!"
+
+#: lib/Driver/kolab.php:1203
 #, php-format
 msgid "Key for saving must be a UID not %s!"
 msgstr "Àx¦sªºª÷Æ_¥²¶·¬O UID ¦Ó«D %s!"
 
+#: config/attributes.php.dist:406
+msgid "Kolab Home Server"
+msgstr "Kolab Home ¦øªA¾¹"
+
 #: lib/Driver/ldap.php:64
 msgid ""
 "LDAP support is required but the LDAP module is not available or not loaded."
 msgstr "¥²¶·­n¦³ LDAP ªº¤ä´©,¦ý¬O LDAP ¼Ò²Õ¤£¬O¥¼¦w¸Ë´N¬O¨S¦³¸ü¤J."
 
-#: data.php:65 templates/data/export.inc:16 templates/data/import.inc:18
+#: data.php:106 templates/data/export.inc:16 templates/data/import.inc:18
 msgid "LDIF Address Book"
 msgstr "LDIF ³q°T¿ý"
 
-#: config/attributes.php.dist:390
+#: config/attributes.php.dist:442
 msgid "Language"
 msgstr "»y¨¥"
 
@@ -755,35 +769,52 @@ msgstr "
 msgid "Last Name"
 msgstr "©m"
 
-#: config/attributes.php.dist:396
+#: config/attributes.php.dist:448
 msgid "Latitude"
 msgstr "½n«×"
 
-#: templates/browse/column_headers.inc:16
+#: templates/browse/column_headers.inc:17
 msgid "List"
 msgstr "²M³æ"
 
-#: config/sources.php.dist:238 config/sources.php.dist:918
+#: config/sources.php.dist:251 config/sources.php.dist:948
 msgid "Location"
 msgstr "¦ì¸m"
 
-#: config/attributes.php.dist:401
+#: config/attributes.php.dist:324
+msgid "Logo"
+msgstr "¼Ð»x"
+
+#: config/attributes.php.dist:330
+msgid "Logo MIME Type"
+msgstr "¼Ð»xªº MIME «¬ºA"
+
+#: config/attributes.php.dist:453
 msgid "Longitude"
 msgstr "¸g«×"
 
-#: addressbooks/index.php:46 templates/addressbook_list.php:2
+#: lib/api.php:616
+#, fuzzy
+msgid "Malformed request."
+msgstr "µL®ÄªºÀɮ׽ШD."
+
+#: templates/addressbook_list.php:2 addressbooks/index.php:46
 msgid "Manage Address Books"
 msgstr "³q°T¿ýºÞ²z"
 
-#: config/attributes.php.dist:372
+#: config/attributes.php.dist:424
 msgid "Manager"
 msgstr "¸g²z"
 
+#: contact.php:109
+msgid "Mark this as your own contact"
+msgstr "¼Ð¥Ü¦¨§A¦Û¤vªº³sµ¸¤H"
+
 #: templates/browse/search.inc:109
 msgid "Matching"
 msgstr "¤Ç°t"
 
-#: lib/api.php:306
+#: lib/api.php:329
 msgid "Maximum Number of Contacts"
 msgstr "³sµ¸¤H¤W­­¼Æ¥Ø"
 
@@ -799,17 +830,36 @@ msgstr "
 #, fuzzy
 msgid "Middle Names"
 msgstr ""
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
+"ÀɮצWºÙ\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2-ALPHA)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
 "#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
 "#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
 "ÀɮצWºÙ\n"
 "#-#-#-#-#  zh_TW.po (Turba 2.2-ALPHA)  #-#-#-#-#\n"
 "#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
 
 #: lib/Driver/ldap.php:347
 msgid "Missing DN in LDAP source configuration."
 msgstr "§ä¤£¨ì LDAP ³]©w©Ò»Ý­nªº DN ­È."
 
-#: config/attributes.php.dist:259
+#: config/attributes.php.dist:271
 msgid "Mobile Phone"
 msgstr "¦æ°Ê¹q¸Ü"
 
@@ -822,7 +872,7 @@ msgstr "
 msgid "More Options..."
 msgstr "§ó¦h¿ï¶µ..."
 
-#: lib/api.php:1706
+#: lib/api.php:1902
 msgid "More than 1 entry found"
 msgstr "¶W¹L 1 µ§°O¿ý³Q¶Ç¦^"
 
@@ -838,11 +888,11 @@ msgstr "
 msgid "Move right"
 msgstr "½Õ­°"
 
-#: data.php:63 templates/data/import.inc:16
+#: data.php:104 templates/data/import.inc:16
 msgid "Mulberry Address Book"
 msgstr "Mulberry ³q°T¿ý"
 
-#: lib/api.php:1614
+#: lib/api.php:1810
 #, php-format
 msgid ""
 "Multiple persons with address [%s], but none with name [%s] already exist"
@@ -850,7 +900,7 @@ msgstr ""
 "¦b³q°T¿ý¤¤¦³¦n´X¦ì³sµ¸¤Hªº¶l¥ó¦í§}³£¬O [%s],¦ý³o¨Ç³sµ¸¤H¨S¦³¤@­Ó¬O¥s°µ [%s] "
 "ªº."
 
-#: config/sources.php.dist:162
+#: config/sources.php.dist:167
 msgid "My Address Book"
 msgstr "§Úªº³q°T¿ý"
 
@@ -867,32 +917,70 @@ msgstr "
 #, fuzzy
 msgid "Name Prefixes"
 msgstr ""
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
+"¶l¥ó¹wÄý\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2-ALPHA)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
 "#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
 "#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
 "¶l¥ó¹wÄý\n"
 "#-#-#-#-#  zh_TW.po (Turba 2.2-ALPHA)  #-#-#-#-#\n"
 "#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
 
 #: config/attributes.php.dist:77
 #, fuzzy
 msgid "Name Suffixes"
 msgstr ""
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (ansel 1.0-cvs)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
+"#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
+"¶l¥ó¹wÄý\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2-ALPHA)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
 "#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
 "#-#-#-#-#  compendium.po (Dimp 1.0-ALPHA)  #-#-#-#-#\n"
 "¶l¥ó¹wÄý\n"
 "#-#-#-#-#  zh_TW.po (Turba 2.2-ALPHA)  #-#-#-#-#\n"
 "#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
+"#-#-#-#-#  zh_TW.po (Turba 2.2)  #-#-#-#-#\n"
 
 #: templates/browse/search_vbook.inc:6
 msgid "Name:"
 msgstr "ÀɦW:"
 
-#: add.php:70 lib/Block/tree_menu.php:27
+#: add.php:70 lib/Block/tree_menu.php:28
 msgid "New Contact"
 msgstr "·s¼W³sµ¸¤H"
 
-#: templates/data/import.inc:46 lib/Forms/EditContact.php:112
-#: lib/Forms/EditContact.php:119 lib/Forms/EditContact.php:174
+#: templates/data/import.inc:46 lib/Forms/EditContact.php:119
+#: lib/Forms/EditContact.php:126 lib/Forms/EditContact.php:181
 msgid "Next"
 msgstr "¤U¤@¨B"
 
@@ -900,30 +988,30 @@ msgstr "
 msgid "Nickname"
 msgstr "¼ÊºÙ"
 
-#: lib/api.php:1709 lib/api.php:1769
+#: lib/api.php:1905 lib/api.php:1965
 #, php-format
 msgid "No %s entry found for %s"
 msgstr "§ä¤£¨ì %2$s ªº %1$s °O¿ý"
 
-#: data.php:52
+#: data.php:93
 msgid ""
 "No Address Books are currently available. Import and Export is disabled."
 msgstr "¥Ø«eµL¥ô¦ó³q°T¿ý¥i¨Ï¥Î. ¶×¤J»P¶×¥X¦]¦Ó°±¥Î."
 
-#: search.php:107
+#: search.php:92
 msgid "No Address Books are currently available. Searching is disabled."
 msgstr "¥Ø«eµL¥ô¦ó³q°T¿ý¥i¨Ï¥Î. ·j´M¥\¯à¦]¦Ó°±¥Î."
 
-#: lib/api.php:561 lib/api.php:616 lib/api.php:676 lib/api.php:858
-#: lib/api.php:950 lib/api.php:1015
+#: lib/api.php:690 lib/api.php:745 lib/api.php:805 lib/api.php:990
+#: lib/api.php:1123 lib/api.php:1189
 msgid "No address book specified"
 msgstr "¥¼«ü©w³q°T¿ý"
 
-#: minisearch.php:77
+#: minisearch.php:80
 msgid "No contacts found"
 msgstr "§ä¤£¨ì³sµ¸¤H"
 
-#: templates/browse/column_headers.inc:43
+#: templates/browse/column_headers.inc:44
 msgid "No contacts match the current filter."
 msgstr "µL¥ô¦ó³sµ¸¤H²Å¦X²{¦æ±ø¥ó."
 
@@ -935,7 +1023,7 @@ msgstr "
 msgid "No source for favourite recipients exists."
 msgstr "¼öªù¤H¿ïªº¨Ó·½¤£¦s¦b."
 
-#: lib/api.php:762 lib/api.php:1060
+#: lib/api.php:893 lib/api.php:1235
 msgid "No vCard data was found."
 msgstr "§ä¤£¨ì vCard ¸ê®Æ."
 
@@ -952,7 +1040,7 @@ msgstr "
 msgid "Not found"
 msgstr "§ä¤£¨ì"
 
-#: config/attributes.php.dist:314
+#: config/attributes.php.dist:338
 msgid "Notes"
 msgstr "³Æµù"
 
@@ -960,20 +1048,20 @@ msgstr "
 msgid "Number of items per page"
 msgstr "¨C­¶¼Æ¥Ø"
 
-#: lib/api.php:909 lib/api.php:1085
+#: lib/api.php:1041 lib/api.php:1260
 msgid "Object not found"
 msgstr "§ä¤£¨ìª«¥ó"
 
-#: lib/Driver/kolab.php:1184
+#: lib/Driver/kolab.php:1207
 #, php-format
 msgid "Object with UID %s does not exist!"
 msgstr "UID  %s ªºª«¥ó¨Ã¤£¦s¦b!"
 
-#: config/attributes.php.dist:282
+#: config/attributes.php.dist:294
 msgid "Occupation"
 msgstr "¦æ·~"
 
-#: config/attributes.php.dist:306
+#: config/attributes.php.dist:318
 msgid "Office"
 msgstr "¿ì¤½«Ç"
 
@@ -986,27 +1074,27 @@ msgstr ""
 "¤@¥¹§AÀx¦s¦¹¿ï¶µ­¶­±, ³q°T¿ý±N¥Ã»·§R°£. ¦pªG³o¤£¬O§A©Ò§Æ±æªº, §AÀ³¸Ó¿ï¾Ü\"µL"
 "\"."
 
-#: lib/api.php:1068
+#: lib/api.php:1243
 msgid "Only one vcard supported."
 msgstr "¶È¤ä´©³æ¤@VCARD."
 
-#: config/sources.php.dist:245 config/sources.php.dist:924
+#: config/sources.php.dist:258 config/sources.php.dist:954
 msgid "Organization"
 msgstr "²Õ´"
 
-#: config/sources.php.dist:246 config/sources.php.dist:926
+#: config/sources.php.dist:259 config/sources.php.dist:956
 msgid "Other"
 msgstr "¨ä¥L"
 
-#: config/attributes.php.dist:332
+#: config/attributes.php.dist:356
 msgid "PGP Public Key"
 msgstr "PGP ¤½¶}ª÷Æ_"
 
-#: config/attributes.php.dist:471
+#: config/attributes.php.dist:523
 msgid "PTT"
 msgstr ""
 
-#: config/attributes.php.dist:269
+#: config/attributes.php.dist:281
 msgid "Pager"
 msgstr "©I¥s¾¹"
 
@@ -1014,16 +1102,24 @@ msgstr "
 msgid "Permanently delete this contact?"
 msgstr "¥Ã¤[§R°£¦¹³sµ¸¤H?"
 
-#: deletefile.php:36 lib/Driver.php:721 lib/api.php:740 lib/api.php:1599
-#: lib/Driver/sql.php:486
+#: deletefile.php:36 lib/Driver.php:805 lib/api.php:870 lib/api.php:1795
+#: lib/Driver/sql.php:515
 msgid "Permission denied"
 msgstr "¦s¨ú¾D©Ú"
 
-#: config/sources.php.dist:235 config/sources.php.dist:914
+#: config/sources.php.dist:248 config/sources.php.dist:944
 msgid "Personal"
 msgstr "­Ó¤H"
 
-#: data.php:64 templates/data/import.inc:17
+#: config/attributes.php.dist:121
+msgid "Photo"
+msgstr "·Ó¤ù"
+
+#: config/attributes.php.dist:127
+msgid "Photo MIME Type"
+msgstr "·Ó¤ùªº MIME «¬ºA"
+
+#: data.php:105 templates/data/import.inc:17
 msgid "Pine Address Book"
 msgstr "Pine ³q°T¿ý"
 
@@ -1031,8 +1127,8 @@ msgstr "Pine 
 msgid "Please name the new contact list:"
 msgstr "½Ð¿é¤J·s¸s²Õªº¦WºÙ:"
 
-#: lib/Forms/EditContact.php:115 lib/Forms/EditContact.php:118
-#: lib/Forms/EditContact.php:167
+#: lib/Forms/EditContact.php:122 lib/Forms/EditContact.php:125
+#: lib/Forms/EditContact.php:174
 msgid "Previous"
 msgstr "¤W¤@±i"
 
@@ -1046,7 +1142,7 @@ msgstr "
 msgid "Read failed: (%s) %s"
 msgstr "Ū¨ú¥¢±Ñ: (%s) %s"
 
-#: lib/Driver.php:1868 lib/Driver/null.php:52
+#: lib/Driver.php:2107 lib/Driver/null.php:52
 msgid "Reading contacts is not available."
 msgstr "©ÒŪ¨úªº³sµ¸¤HµL®Ä."
 
@@ -1067,7 +1163,7 @@ msgstr "
 msgid "Remove from this list"
 msgstr "±q³o­Ó¸s²Õ¤¤²¾°£"
 
-#: lib/Driver.php:1906
+#: lib/Driver.php:2145
 msgid ""
 "Removing user data is not supported in the current address book storage "
 "driver."
@@ -1081,7 +1177,7 @@ msgstr ""
 "¥H¶×¤Jªº³q°T¿ý¸m´«²{¦sªº³q°T¿ý ? <strong>ĵ§i: ³o±N·|§R°£¥Ø«e³q°T¿ý¤¤ªº©Ò¦³¬ö"
 "¿ý.</strong>"
 
-#: lib/Driver.php:615
+#: lib/Driver.php:699
 msgid "Requested object not found."
 msgstr "§ä¤£¨ì©Ò»Ýªºª«¥ó."
 
@@ -1089,11 +1185,11 @@ msgstr "
 msgid "Reset to Defaults"
 msgstr "­«³]¦^¤º©w­È"
 
-#: config/attributes.php.dist:338
+#: config/attributes.php.dist:362
 msgid "S/MIME Public Certificate"
 msgstr "S/MIME ¤½¶}¾ÌÃÒ"
 
-#: config/attributes.php.dist:465
+#: config/attributes.php.dist:517
 msgid "SIP"
 msgstr ""
 
@@ -1102,7 +1198,7 @@ msgstr ""
 msgid "STARTTLS failed: (%s) %s"
 msgstr "STARTTLS ¥¢±Ñ: (%s) %s"
 
-#: lib/Forms/EditContact.php:26 lib/Forms/EditAddressBook.php:46
+#: lib/Forms/EditAddressBook.php:46 lib/Forms/EditContact.php:26
 msgid "Save"
 msgstr "Àx¦s"
 
@@ -1110,34 +1206,34 @@ msgstr "
 msgid "Save search as a virtual address book?"
 msgstr "Àx¦s·j´Mµ²ªG¦¨¤@­ÓµêÀÀ³q°T¿ý?"
 
-#: lib/Driver.php:1894 lib/Driver/null.php:67
+#: lib/Driver.php:2133 lib/Driver/null.php:67
 msgid "Saving contacts is not available."
 msgstr "©ÒÀx¦sªº³sµ¸¤HµL®Ä."
 
 #: templates/browse/header.inc:3 templates/browse/search.inc:111
-#: templates/browse/search.inc:119 templates/block/minisearch.inc:26
-#: lib/Block/tree_menu.php:58 config/prefs.php.dist:116
+#: templates/browse/search.inc:119 templates/block/minisearch.inc:25
+#: lib/Block/tree_menu.php:62 config/prefs.php.dist:116
 msgid "Search"
 msgstr "·j´M"
 
-#: lib/api.php:1374
+#: lib/api.php:1568
 msgid "Search failed"
 msgstr "·j´M¥¢±Ñ"
 
-#: lib/api.php:1604 lib/api.php:1610 lib/api.php:1619 lib/api.php:1632
+#: lib/api.php:1800 lib/api.php:1806 lib/api.php:1815 lib/api.php:1828
 #, php-format
 msgid "Search failed: %s"
 msgstr "·j´M¥¢±Ñ: %s"
 
-#: templates/block/minisearch.inc:24
+#: templates/block/minisearch.inc:23
 msgid "Search for: "
 msgstr "·j´M: "
 
-#: lib/Driver.php:1853 lib/Driver/null.php:47
+#: lib/Driver.php:2092 lib/Driver/null.php:47
 msgid "Searching is not available."
 msgstr "·j´M¥\¯àµL®Ä."
 
-#: templates/browse/row.inc:40
+#: templates/browse/row.inc:52
 msgid "Select contact"
 msgstr "¿ï¾Ü³sµ¸¤H"
 
@@ -1213,17 +1309,17 @@ msgstr "
 msgid "Sort Direction"
 msgstr "±Æ§Ç¤è¦V"
 
-#: templates/browse/column_headers.inc:31
+#: templates/browse/column_headers.inc:32
 #, php-format
 msgid "Sort by %s"
 msgstr "¤w %s ±Æ¦C"
 
-#: templates/browse/column_headers.inc:26
+#: templates/browse/column_headers.inc:27
 #, php-format
 msgid "Sort by %s only"
 msgstr "¶È¨Ì %s ±Æ¦C"
 
-#: templates/browse/column_headers.inc:29
+#: templates/browse/column_headers.inc:30
 #, php-format
 msgid "Sort by %s, then by %s"
 msgstr "¥ý¨Ì %s ±Æ¦C,µM«á %s"
@@ -1232,7 +1328,7 @@ msgstr "
 msgid "Source:"
 msgstr "¨Ó·½:"
 
-#: lib/api.php:299
+#: lib/api.php:322
 msgid "Sources"
 msgstr "¨Ó·½"
 
@@ -1240,7 +1336,7 @@ msgstr "
 msgid "Spouse"
 msgstr "°t°¸"
 
-#: lib/Views/Browse.php:261 lib/Views/Browse.php:301
+#: lib/Views/Browse.php:268 lib/Views/Browse.php:308
 #, php-format
 msgid "Successfully added %d contact(s) to list."
 msgstr "¤w¦¨¥\¦a¥[¤J %d ­Ó³sµ¸¤H¨ì¸s²Õ¤¤."
@@ -1250,12 +1346,12 @@ msgstr "
 msgid "Successfully added %s to %s"
 msgstr "%s ¤w¦¨¥\¦a¥[¤J¨ì %s ¨t²Î¤¤."
 
-#: lib/Views/Browse.php:291
+#: lib/Views/Browse.php:298
 #, php-format
 msgid "Successfully created the contact list \"%s\"."
 msgstr "¤w¦¨¥\ªº«Ø¥ß¸s²Õ \"%s\"."
 
-#: search.php:165
+#: search.php:150
 #, php-format
 msgid "Successfully created virtual address book \"%s\""
 msgstr "¤w¦¨¥\¦a«Ø¥ßµêÀÀ³q°T¿ý \"%s\""
@@ -1270,7 +1366,7 @@ msgstr "%d 
 msgid "Successfully removed %d contact(s) from list."
 msgstr "¤w¦¨¥\¦a±q¸s²Õ²¾°£ %d ­Ó³sµ¸¤H."
 
-#: data.php:61
+#: data.php:102
 msgid "TSV"
 msgstr "Tab ¤À¹j®æ¦¡"
 
@@ -1286,7 +1382,7 @@ msgstr "
 msgid "Target Contact List"
 msgstr "¥Ø¼Ð¸s²Õ"
 
-#: data.php:321
+#: data.php:426
 #, php-format
 msgid "The %s file didn't contain any contacts."
 msgstr "ÀÉ®× %s ¤¤¨S¦³¥ô¦ó³sµ¸¤H¸ê®Æ."
@@ -1295,7 +1391,7 @@ msgstr "
 msgid "The VFS backend needs to be configured to enable attachment uploads."
 msgstr "­n±Ò¥Îªþ¥ó¤W¶Ç¥\¯à«e,µêÀÀÀɮרt²Î(VFS)¦øªAºÝ¥²¶·³]©w§¹¦¨."
 
-#: lib/Driver.php:1824
+#: lib/Driver.php:2063
 #, php-format
 msgid "The address book \"%s\" does not exist."
 msgstr "³q°T¿ý \"%s\" ¤£¦s¦b."
@@ -1305,11 +1401,15 @@ msgstr "
 msgid "The address book \"%s\" has been created."
 msgstr "³q°T¿ý \"%s\" ¤w«Ø¥ß."
 
-#: data.php:328
+#: data.php:433
 #, php-format
 msgid "The address book could not be purged: %s"
 msgstr "¦¹³q°T¿ýµLªk³Q²MªÅ: %s"
 
+#: lib/api.php:1061
+msgid "The address book with your own contact doesn't exist anymore."
+msgstr "­ìÄÝ©ó§Aªº³q°T¿ý²{¤w¤£¦s¦b."
+
 #: addressbooks/delete.php:50
 #, php-format
 msgid "The addressbook \"%s\" has been deleted."
@@ -1334,7 +1434,7 @@ msgstr "
 msgid "The file \"%s\" has been deleted."
 msgstr "ÀÉ®× \"%s\" ¤w³Q§R°£."
 
-#: data.php:301
+#: data.php:406
 msgid "The import can be finished despite the warnings."
 msgstr "¾¨ºÞ¦³Äµ§i°T®§¦ý¤´µM¥i¥H§¹¦¨¸ê®Æªº¶×¤J."
 
@@ -1355,24 +1455,24 @@ msgid ""
 msgstr ""
 "µL¥i¥Î¨Ó·s¼W°O¿ýªº³q°T¿ý¥i¥Î.¦pªG§A»{¬°³o©Î³\¬O­Ó¿ù»~,½ÐÁpµ¸§Aªº¨t²ÎºÞ²z­û."
 
-#: lib/Views/Browse.php:349
+#: lib/Views/Browse.php:356
 #, php-format
 msgid "There is %d contact in this list that is not viewable to you"
 msgid_plural "There are %d contacts in this list that are not viewable to you"
 msgstr[0] "¦@ %d ­Ó³sµ¸¤H¦b¦¹¸s²Õ¤¤,¦Ó¥BµLªk³Q§AÀ˵ø"
 
-#: search.php:161
+#: search.php:146
 #, php-format
 msgid "There was a problem creating the virtual address book: %s"
 msgstr "«Ø¥ßµêÀÀ³q°T¿ý: %s ®Éµo¥Í¤@­Ó¿ù»~."
 
-#: lib/Forms/AddContact.php:90
+#: lib/Forms/AddContact.php:100
 msgid ""
 "There was an error adding the new contact. Contact your system administrator "
 "for further help."
 msgstr "·s¼W³sµ¸¤H®Éµo¥Í¤@­Ó¿ù»~.½ÐÁpµ¸§Aªº¨t²ÎºÞ²z­û¥H¨ó§U³B²z."
 
-#: lib/Views/Browse.php:311
+#: lib/Views/Browse.php:318
 msgid "There was an error creating a new list."
 msgstr "«Ø¥ß·s¸s²Õ®Éµo¥Í¿ù»~."
 
@@ -1386,31 +1486,31 @@ msgstr "
 msgid "There was an error deleting this contact: %s"
 msgstr "§R°£³sµ¸¤H: %s ®Éµo¥Í¤@­Ó¿ù»~."
 
-#: lib/Views/Browse.php:355
+#: lib/Views/Browse.php:362
 msgid "There was an error displaying the list"
 msgstr "Åã¥Ü¸s²Õ®Éµo¥Í¤@­Ó¿ù»~"
 
-#: data.php:355
+#: data.php:469
 #, php-format
 msgid "There was an error importing the data: %s"
 msgstr "¶×¤J¸ê®Æ:%s ®Éµo¥Í¤@­Ó¿ù»~"
 
-#: lib/api.php:758 lib/api.php:1055
+#: lib/api.php:889 lib/api.php:1230
 msgid "There was an error importing the iCalendar data."
 msgstr "¶×¤J iCalendar ¸ê®Æ®Éµo¥Í¤@­Ó¿ù»~."
 
-#: lib/api.php:235
+#: lib/api.php:258
 #, php-format
 msgid "There was an error removing an address book for %s"
 msgstr "²¾°£ %s ªº³q°T¿ý®Éµo¥Í¤@­Ó¿ù»~"
 
-#: lib/Forms/EditContact.php:86
+#: lib/Forms/EditContact.php:93
 msgid ""
 "There was an error saving the contact. Contact your system administrator for "
 "further help."
 msgstr "Àx¦s³sµ¸¤H®Éµo¥Í¤@­Ó¿ù»~.½ÐÁpµ¸§Aªº¨t²ÎºÞ²z­û¥H¨ó§U³B²z."
 
-#: data.php:187
+#: data.php:292
 msgid "There were no addresses to export."
 msgstr "µL³q°T¿ý¸ê®Æ¥i¨Ñ¶×¥X³q°T¿ý."
 
@@ -1423,11 +1523,15 @@ msgstr "
 msgid "This addressbook cannot be deleted"
 msgstr "¦¹³q°T¿ýµLªk³Q§R°£"
 
-#: data.php:286
+#: contact.php:57
+msgid "This contact has been marked as your own."
+msgstr "¦¹³q°T¿ý¤w¼Ð¥Ü¦¨§Aªº."
+
+#: data.php:391
 msgid "This file format is not supported."
 msgstr "¦¹ºØÀɮ׮榡¨Ã¥¼³Q¤ä´©."
 
-#: lib/api.php:1623 lib/api.php:1636
+#: lib/api.php:1819 lib/api.php:1832
 #, php-format
 msgid "This person already has a %s entry in the address book"
 msgstr "³o­Ó¤Hªº %s °O¿ý¤w¦s¦b©ó³q°T¿ý¤¤."
@@ -1437,7 +1541,7 @@ msgid ""
 "This will be the default address book when adding or importing contacts."
 msgstr "·s¼W©Î¶×¤J³sµ¸¤Hªº¹w³]³q°T¿ý."
 
-#: config/attributes.php.dist:229
+#: config/attributes.php.dist:241
 msgid "Time Zone"
 msgstr "®É°Ï"
 
@@ -1445,7 +1549,7 @@ msgstr "
 msgid "Unable to find contact owner."
 msgstr "§ä¤£¨ì³sµ¸¤Hªº¾Ö¦³ªÌ."
 
-#: lib/Driver.php:1746 lib/Turba.php:672
+#: lib/Driver.php:1983 lib/Turba.php:662
 #, php-format
 msgid "Unable to load the definition of %s."
 msgstr "µLªk¸ü¤J %s ªº©w¸q¸ê®Æ."
@@ -1459,11 +1563,11 @@ msgstr "
 msgid "Unable to search."
 msgstr "µLªk·j´M."
 
-#: config/attributes.php.dist:353
+#: config/attributes.php.dist:391
 msgid "Unfiled"
 msgstr "¥¼¤ÀÃþ"
 
-#: lib/api.php:796 lib/api.php:906 lib/api.php:1073
+#: lib/api.php:927 lib/api.php:1038 lib/api.php:1248
 #, php-format
 msgid "Unsupported Content-Type: %s"
 msgstr "¥¼¤ä´©ªº¤º®e«¬ºA: %s"
@@ -1473,7 +1577,7 @@ msgstr "
 msgid "View \"%s\""
 msgstr "À˵ø \"%s\""
 
-#: minisearch.php:72
+#: minisearch.php:72 minisearch.php:73
 msgid "View Contact"
 msgstr "À˵ø³sµ¸¤H"
 
@@ -1481,75 +1585,75 @@ msgstr "
 msgid "View to display by default:"
 msgstr "¹w³]À˵ø:"
 
-#: config/attributes.php.dist:460
+#: config/attributes.php.dist:512
 msgid "VoIP"
-msgstr ""
+msgstr "VoIP"
 
-#: config/attributes.php.dist:320
+#: config/attributes.php.dist:344
 msgid "Website URL"
 msgstr "ºô§}"
 
-#: config/attributes.php.dist:173
+#: config/attributes.php.dist:185
 msgid "Work Address"
 msgstr "¿ì¤½«Ç¦a§}"
 
-#: config/attributes.php.dist:524
+#: config/attributes.php.dist:576
 msgid "Work Address Extended"
 msgstr "¿ì¤½«Ç¦a§}"
 
-#: config/attributes.php.dist:191
+#: config/attributes.php.dist:203
 msgid "Work City"
 msgstr "¿ì¤½«Ç©ÒÄÝ«°¥«"
 
-#: config/attributes.php.dist:209
+#: config/attributes.php.dist:221
 msgid "Work Country"
 msgstr "¿ì¤½«Ç©ÒÄÝ°ê®a"
 
-#: config/attributes.php.dist:408
+#: config/attributes.php.dist:460
 msgid "Work Email"
 msgstr "¿ì¤½«Ç¹q¤l¶l¥ó"
 
-#: config/attributes.php.dist:425
+#: config/attributes.php.dist:477
 msgid "Work Fax"
 msgstr "¿ì¤½«Ç¶Ç¯u"
 
-#: config/attributes.php.dist:530
+#: config/attributes.php.dist:582
 msgid "Work Latitude"
 msgstr "¿ì¤½«Ç½n«×"
 
-#: config/attributes.php.dist:535
+#: config/attributes.php.dist:587
 msgid "Work Longitude"
 msgstr "¿ì¤½«Ç¸g«×"
 
-#: config/attributes.php.dist:435
+#: config/attributes.php.dist:487
 msgid "Work Mobile Phone"
 msgstr "¿ì¤½«Ç¦æ°Ê¹q¸Ü"
 
-#: config/attributes.php.dist:254
+#: config/attributes.php.dist:266
 msgid "Work Phone"
 msgstr "¿ì¤½«Ç¹q¸Ü"
 
-#: config/attributes.php.dist:185
+#: config/attributes.php.dist:197
 msgid "Work Post Office Box"
 msgstr "¿ì¤½«Ç¶l½c"
 
-#: config/attributes.php.dist:203
+#: config/attributes.php.dist:215
 msgid "Work Postal Code"
 msgstr "¿ì¤½«Ç¶l»¼°Ï¸¹"
 
-#: config/attributes.php.dist:197
+#: config/attributes.php.dist:209
 msgid "Work State/Province"
 msgstr "¿ì¤½«Ç©ÒÄݬ٥÷"
 
-#: config/attributes.php.dist:179
+#: config/attributes.php.dist:191
 msgid "Work Street Address"
 msgstr "¿ì¤½«Ç¦í§}"
 
-#: config/attributes.php.dist:450
+#: config/attributes.php.dist:502
 msgid "Work Video Call"
 msgstr ""
 
-#: config/attributes.php.dist:518
+#: config/attributes.php.dist:570
 msgid "Work Website URL"
 msgstr "¿ì¤½«Çºô§}"
 
@@ -1557,7 +1661,7 @@ msgstr "
 msgid "You are not allowed to change this addressbook."
 msgstr "§A¨S¦³Åܧ󦹳q°T¿ýªºÅv­­."
 
-#: add.php:48 data.php:250 lib/Views/Browse.php:159 lib/Views/Browse.php:274
+#: add.php:48 data.php:355 lib/Views/Browse.php:159 lib/Views/Browse.php:281
 #, php-format
 msgid "You are not allowed to create more than %d contacts in \"%s\"."
 msgstr "¤£¤¹³\§A¦b \"%2$s\" ¤¤«Ø¥ß %1$d ­Ó¥H¤Wªº³sµ¸¤H."
@@ -1566,7 +1670,7 @@ msgstr "
 msgid "You are not allowed to delete this addressbook."
 msgstr "§A¨S¦³§R°£¦¹³q°T¿ýªºÅv­­."
 
-#: lib/api.php:198
+#: lib/api.php:204
 msgid "You are not allowed to remove user data."
 msgstr "§A¨S¦³²¾°£¥Î¤á¸ê®ÆªºÅv­­."
 
@@ -1582,6 +1686,10 @@ msgstr "
 msgid "You cannot delete contacts from a virtual address book"
 msgstr "§AµLªk¦ÛµêÀÀ³q°T¿ý¤¤§R°£³sµ¸¤H."
 
+#: lib/api.php:1056
+msgid "You didn't mark a contact as your own yet."
+msgstr "§A©|¥¼¼Ð¥Ü¥ô¤@­Ó³sµ¸¤H¬°§A¦Û¤vªº."
+
 #: edit.php:66 view.php:38 lib/Views/DeleteContact.php:42
 #: lib/Views/EditContact.php:49
 msgid "You do not have permission to view this contact."
@@ -1595,6 +1703,12 @@ msgstr "
 msgid "You do not have permissions to delete this address book."
 msgstr "§A¨S¦³§R°£¦¹³q°T¿ýªºÅv­­."
 
+#: lib/api.php:1070
+msgid ""
+"You don't have sufficient permissions to read the address book that contains "
+"your own contact."
+msgstr "¦¹³q°T¿ý¥]§t§A¦Û¤vªºÁpµ¸¤H,¦ý¬O§A¨Ã¨S¦³¨¬°÷ªºÅª¨úÅv­­."
+
 #: lib/Driver/ldap.php:741
 msgid ""
 "You must have the Net_LDAP PEAR library installed to use the schema check "
@@ -1603,7 +1717,7 @@ msgstr ""
 "­n¨Ï¥Î¾÷½XÀˬd¥\¯à(schema check function)«e,§A¥²¶·¥ý¦w¸Ë¦n Net_LDAP PEAR ¨ç¦¡"
 "®w."
 
-#: search.php:148
+#: search.php:133
 msgid "You must provide a name for virtual address books."
 msgstr "§A¥²¶·À°µêÀÀ³q°T¿ý¨ú­Ó¦WºÙ."
 
@@ -1624,15 +1738,24 @@ msgstr "
 msgid "You only have permission to view this contact."
 msgstr "§A¥u¦³À˵ø³o­Ó³sµ¸¤HªºÅv­­."
 
-#: lib/Views/Browse.php:362
+#: lib/Views/Browse.php:369
 msgid "Your default address book is not browseable."
 msgstr "§Aªº¹w³]³q°T¿ý¤£¥iÂsÄý."
 
+#: contact.php:101 contact.php:102 templates/browse/row.inc:14
+#: templates/browse/row.inc:15
+msgid "Your own contact"
+msgstr "§A¦Û¤vªº³sµ¸¤H"
+
+#: lib/api.php:1075
+msgid "Your own contact cannot be found in the address book."
+msgstr "¦b¦¹³q°T¿ý¤¤§ä¤£¨ì§A¦Û¤vªº³sµ¸¤H."
+
 #: templates/browse/contactrow.inc:12
 msgid "[no value]"
 msgstr "[µL³]©w­È]"
 
-#: lib/Turba.php:614
+#: lib/Turba.php:604
 msgid "_Browse"
 msgstr "ÂsÄý_B"
 
@@ -1644,11 +1767,11 @@ msgstr "
 msgid "_Delete"
 msgstr "§R°£_D"
 
-#: contact.php:85
+#: contact.php:91
 msgid "_Edit"
 msgstr "½s¿è_E"
 
-#: lib/Turba.php:623
+#: lib/Turba.php:613
 msgid "_Import/Export"
 msgstr "¶×¤J/¶×¥X_I"
 
@@ -1656,15 +1779,15 @@ msgstr "
 msgid "_Lists"
 msgstr "¸s²Õ_L"
 
-#: lib/Turba.php:611
+#: lib/Turba.php:601
 msgid "_My Address Books"
 msgstr "³q°T¿ýºÞ²z"
 
-#: lib/Turba.php:617
+#: lib/Turba.php:607
 msgid "_New Contact"
 msgstr "·s¼W³sµ¸¤H_N"
 
-#: lib/Turba.php:628
+#: lib/Turba.php:618
 msgid "_Print"
 msgstr "¦C¦L_P"
 
@@ -1672,15 +1795,15 @@ msgstr "
 msgid "_Remove from this list"
 msgstr "±q³o­Ó¸s²Õ¤¤²¾°£_R"
 
-#: lib/Turba.php:619
+#: lib/Turba.php:609
 msgid "_Search"
 msgstr "·j´M_S"
 
-#: contact.php:82
+#: contact.php:88
 msgid "_View"
 msgstr "À˵ø_V"
 
-#: templates/browse/column_headers.inc:24
+#: templates/browse/column_headers.inc:25
 msgid "ascending"
 msgstr "¤W¤É"
 
@@ -1697,36 +1820,36 @@ msgstr "
 msgid "contact"
 msgstr "contact"
 
-#: data.php:207 data.php:212 templates/data/export.inc:1
+#: data.php:312 data.php:317 templates/data/export.inc:1
 msgid "contacts.csv"
 msgstr "contacts.csv"
 
-#: data.php:232
+#: data.php:337
 msgid "contacts.ldif"
 msgstr "contacts.ldif"
 
-#: data.php:217
+#: data.php:322
 msgid "contacts.tsv"
 msgstr "contacts.tsv"
 
-#: data.php:227
+#: data.php:332
 msgid "contacts.vcf"
 msgstr "contacts.vcf"
 
-#: templates/browse/column_headers.inc:24
+#: templates/browse/column_headers.inc:25
 msgid "descending"
 msgstr "¤U­°"
 
-#: config/attributes.php.dist:387
+#: config/attributes.php.dist:439
 msgid "female"
 msgstr "¤k©Ê"
 
-#: lib/Block/tree_menu.php:37
+#: lib/Block/tree_menu.php:38
 #, php-format
 msgid "in %s"
 msgstr "©ó %s"
 
-#: config/attributes.php.dist:387
+#: config/attributes.php.dist:439
 msgid "male"
 msgstr "¨k©Ê"
 
@@ -1746,7 +1869,7 @@ msgstr "
 msgid "to a different Address Book"
 msgstr "¨ì¨ä¥Lªº³q°T¿ý"
 
-#: data.php:62 templates/browse/column_headers.inc:13
+#: data.php:103 templates/browse/column_headers.inc:14
 #: templates/data/export.inc:15 templates/data/import.inc:15
 msgid "vCard"
 msgstr "vCard"
diff --git a/scripts/import_squirrelmail_file_abook.php b/scripts/import_squirrelmail_file_abook.php
index e6814bb..fdb9647 100755
--- a/scripts/import_squirrelmail_file_abook.php
+++ b/scripts/import_squirrelmail_file_abook.php
@@ -8,9 +8,9 @@
  * Input can be either a single squirrelmail .abook file, or a directory
  * containing multiple .abook files.
  *
- * $Horde: turba/scripts/import_squirrelmail_file_abook.php,v 1.2.2.1 2008/12/04 14:44:04 jan Exp $
+ * $Horde: turba/scripts/import_squirrelmail_file_abook.php,v 1.2.2.2 2009/01/06 15:28:01 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/scripts/import_squirrelmail_sql_abook.php b/scripts/import_squirrelmail_sql_abook.php
index 7695fa0..b6d236b 100755
--- a/scripts/import_squirrelmail_sql_abook.php
+++ b/scripts/import_squirrelmail_sql_abook.php
@@ -6,9 +6,9 @@
  * The first argument must be a DSN to the database containing the "address"
  * table, e.g.: "mysql://root:password@localhost/squirrelmail".
  *
- * $Horde: turba/scripts/import_squirrelmail_sql_abook.php,v 1.4.2.2 2008/12/04 17:58:32 jan Exp $
+ * $Horde: turba/scripts/import_squirrelmail_sql_abook.php,v 1.4.2.3 2009/01/06 15:28:01 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/scripts/import_vcards.php b/scripts/import_vcards.php
index 240bd65..bcc0cdd 100755
--- a/scripts/import_vcards.php
+++ b/scripts/import_vcards.php
@@ -5,9 +5,9 @@
  * The VCARD data is read from standard input, the address book and user name
  * passed as parameters.
  *
- * $Horde: turba/scripts/import_vcards.php,v 1.4.2.5 2008/01/02 11:32:40 jan Exp $
+ * $Horde: turba/scripts/import_vcards.php,v 1.4.2.6 2009/01/06 15:28:01 jan Exp $
  *
- * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2005-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/scripts/upgrades/2.1_to_2.2_sql_schema.php b/scripts/upgrades/2.1_to_2.2_sql_schema.php
index d82539c..c1e6c89 100755
--- a/scripts/upgrades/2.1_to_2.2_sql_schema.php
+++ b/scripts/upgrades/2.1_to_2.2_sql_schema.php
@@ -9,9 +9,9 @@
  * It is HIGHLY RECOMMENDED to back up your current Turba tables BEFORE
  * attempting this upgrade!
  *
- * $Horde: turba/scripts/upgrades/2.1_to_2.2_sql_schema.php,v 1.18.2.7 2008/06/03 16:42:39 mrubinsk Exp $
+ * $Horde: turba/scripts/upgrades/2.1_to_2.2_sql_schema.php,v 1.18.2.8 2009/01/06 15:28:03 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/scripts/upgrades/convert_datatree_shares_to_sql.php b/scripts/upgrades/convert_datatree_shares_to_sql.php
index 23abda9..e148774 100755
--- a/scripts/upgrades/convert_datatree_shares_to_sql.php
+++ b/scripts/upgrades/convert_datatree_shares_to_sql.php
@@ -6,7 +6,7 @@
  * 2.1_to_2.2_add_sql_share_tables SQL creation script for your RDBMS before
  * executing this script.
  *
- * $Horde: turba/scripts/upgrades/convert_datatree_shares_to_sql.php,v 1.1.2.6 2008/10/23 15:50:35 jan Exp $
+ * $Horde: turba/scripts/upgrades/convert_datatree_shares_to_sql.php,v 1.1.2.7 2009/07/20 11:16:56 jan Exp $
  */
 
 @define('AUTH_HANDLER', true);
@@ -28,6 +28,7 @@ require_once 'MDB2.php';
 $config = $GLOBALS['conf']['sql'];
 unset($config['charset']);
 $db = MDB2::factory($config);
+$db->setOption('seqcol_name', 'id');
 
 $error_cnt = 0;
 $delete_dt_data = false;
@@ -41,23 +42,26 @@ if ($answer != 'y') {
 }
 
 /* Get the share entries */
-$sql = 'SELECT datatree_id, datatree_name FROM horde_datatree WHERE '
-    . 'group_uid = \'horde.shares.turba\'';
-$shares_result = $db->query($sql);
+$shares_result = $db->query('SELECT datatree_id, datatree_name FROM horde_datatree WHERE group_uid = \'horde.shares.turba\'');
 if (is_a($shares_result, 'PEAR_Error')) {
     die($shares_result->toString());
 }
 
+$query = $db->prepare('SELECT attribute_name, attribute_key, attribute_value FROM horde_datatree_attributes WHERE datatree_id = ?');
 while ($row = $shares_result->fetchRow(MDB2_FETCHMODE_ASSOC)) {
     $share_id = $row['datatree_id'];
     $share_name = $row['datatree_name'];
 
     /* Build an array to hold the new row data */
-    $data = array('share_id' => $db->nextId('turba_shares'),
+    $nextId = $db->nextId('turba_shares');
+    if (is_a($nextId, 'PEAR_Error')) {
+        $cli->message($nextId->toString(), 'cli.error');
+        $error_cnt++;
+        continue;
+    }
+    $data = array('share_id' => $nextId,
                   'share_name' => $share_name);
 
-    $sql = 'SELECT attribute_name, attribute_key, attribute_value FROM horde_datatree_attributes WHERE datatree_id = ?';
-    $query = $db->prepare($sql);
     $query_result = $query->execute($share_id);
     $rows = $query_result->fetchAll(MDB2_FETCHMODE_ASSOC);
     $users = array();
diff --git a/scripts/upgrades/public_to_horde_share.php b/scripts/upgrades/public_to_horde_share.php
index 849fe99..0d816e9 100755
--- a/scripts/upgrades/public_to_horde_share.php
+++ b/scripts/upgrades/public_to_horde_share.php
@@ -9,9 +9,9 @@
  * a SQL source (such as 'localsql') - otherwise, you will turn every user's
  * private address book into a public source!
  *
- * $Horde: turba/scripts/upgrades/public_to_horde_share.php,v 1.3.2.8 2008/01/02 11:32:40 jan Exp $
+ * $Horde: turba/scripts/upgrades/public_to_horde_share.php,v 1.3.2.9 2009/01/06 15:28:03 jan Exp $
  *
- * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2005-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/search.php b/search.php
index 80de805..56ad745 100644
--- a/search.php
+++ b/search.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/search.php,v 1.94.4.21 2008/08/25 17:10:04 jan Exp $
+ * $Horde: turba/search.php,v 1.94.4.22 2009/01/06 15:27:39 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/templates/browse/search.inc b/templates/browse/search.inc
index 15a48b8..bdd97e7 100644
--- a/templates/browse/search.inc
+++ b/templates/browse/search.inc
@@ -122,7 +122,7 @@ Event.observe(window, 'load', updateCriteria);
  </tr>
  <?php if ($source_count > 1): ?>
  <tr>
-  <td class="rightAlign"><strong><?php echo Horde::label('source', _("Directory")) ?></strong></td>
+  <td class="rightAlign"><strong><?php echo Horde::label('source', _("Address Book")) ?></strong></td>
   <td class="leftAlign">
    <select id="source" name="source" onchange="directory_search.submit()">
     <?php echo $source_options ?>
diff --git a/templates/common-header.inc b/templates/common-header.inc
index 01b804f..52b4207 100644
--- a/templates/common-header.inc
+++ b/templates/common-header.inc
@@ -6,7 +6,7 @@ if (isset($language)) {
 }
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
-<!-- Turba: Copyright 2000-2008 The Horde Project.  Turba is under an ASL license. -->
+<!-- Turba: Copyright 2000-2009 The Horde Project.  Turba is under an ASL license. -->
 <!--   Horde Project: http://www.horde.org/ | Turba: http://www.horde.org/turba/   -->
 <!--          Horde ASL License: http://www.horde.org/licenses/asl.php             -->
 <?php echo !empty($language) ? '<html lang="' . strtr($language, '_', '-') . '">' : '<html>' ?>
diff --git a/test.php b/test.php
index bfe7c04..d419095 100644
--- a/test.php
+++ b/test.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/test.php,v 1.9.10.9 2008/09/26 14:25:21 jan Exp $
+ * $Horde: turba/test.php,v 1.9.10.11 2009/03/25 23:06:04 jan Exp $
  *
- * Copyright 1999-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
@@ -84,6 +84,7 @@ $basedn = isset($_POST['basedn']) ? $_POST['basedn'] : ''; // 'dc=example,dc=com
 $user = isset($_POST['user']) ? $_POST['user'] : '';     // 'user';
 $passwd = isset($_POST['passwd']) ? $_POST['passwd'] : ''; // 'password';
 $filter = isset($_POST['filter']) ? $_POST['filter'] : ''; // 'cn=Babs Jensen';
+$proto = isset($_POST['version']) ? $_POST['version'] : ''; // 'LDAPv3';
 
 if (!empty($server) && !empty($basedn) && !empty($filter)) {
     if (empty($port)) {
@@ -97,6 +98,9 @@ if (!empty($server) && !empty($basedn) && !empty($filter)) {
     }
     $ldap = ldap_connect($server, $port);
     if ($ldap) {
+        if (!empty($proto) && ($proto == '3')) {
+            ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
+        }
         if (!empty($user) && !ldap_bind($ldap, $user, $passwd)) {
             echo '<p>unable to bind as ' . htmlspecialchars($user) . ' to LDAP server</p>';
             ldap_close($ldap);
@@ -137,6 +141,7 @@ if (!empty($server) && !empty($basedn) && !empty($filter)) {
 <tr><td align="right"><label for="user">User</label></td><td><input type="text" id="user" name="user" /></td><td>(leave blank for anonymous)</td></tr>
 <tr><td align="right"><label for="passwd">Password</label></td><td><input type="password" id="passwd" name="passwd" /></td></tr>
 <tr><td align="right"><label for="filter">Filter</label></td><td><input type="text" id="filter" name="filter" /></td><td>(e.g. "cn=Babs Jensen")</td></tr>
+<tr><td align="right"><label for="proto">Protocol</label></td><td><select id="version" name="version"><option value="2">LDAPv2 (Deprecated)</option><option value="3" selected="selected">LDAPv3</option></td><td>(LDAP protocol version)</select></td></tr>
 <tr><td></td><td><input type="submit" name="f_submit" value="Submit" /><input type="reset" name="f_reset" value="Reset" /></td></tr>
 </table>
 </form>
diff --git a/vcard.php b/vcard.php
index a271e5b..945e1ad 100644
--- a/vcard.php
+++ b/vcard.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/vcard.php,v 1.12.10.7 2008/01/02 11:32:38 jan Exp $
+ * $Horde: turba/vcard.php,v 1.12.10.8 2009/01/06 15:27:39 jan Exp $
  *
- * Copyright 2000-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.
diff --git a/view.php b/view.php
index 878d18e..a4181ae 100644
--- a/view.php
+++ b/view.php
@@ -1,8 +1,8 @@
 <?php
 /**
- * $Horde: turba/view.php,v 1.6.2.5 2008/01/02 11:32:38 jan Exp $
+ * $Horde: turba/view.php,v 1.6.2.6 2009/01/06 15:27:39 jan Exp $
  *
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (ASL).  If you
  * did not receive this file, see http://www.horde.org/licenses/asl.php.

-- 
Debian Horde Packages repository: turba2 package



More information about the pkg-horde-hackers mailing list